diff --git a/CHANGES.md b/CHANGES.md index bc4f5241..982e677f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -23,6 +23,68 @@ OpenSSL 3.0 ### Changes between 1.1.1 and 3.0 [xx XXX xxxx] + * Handshake now fails if Extended Master Secret extension is dropped + on renegotiation. + + *Tomas Mraz* + + * Dropped interactive mode from the 'openssl' program. From now on, + the `openssl` command without arguments is equivalent to `openssl + help`. + + *Richard Levitte* + + * Renamed EVP_PKEY_cmp() to EVP_PKEY_eq() and + EVP_PKEY_cmp_parameters() to EVP_PKEY_parameters_eq(). + While the old function names have been retained for backward compatibility + they should not be used in new developments + because their return values are confusing: Unlike other `_cmp()` functions + they do not return 0 in case their arguments are equal. + + *David von Oheimb* + + * Deprecated EC_METHOD_get_field_type(). Applications should switch to + EC_GROUP_get_field_type(). + + *Billy Bob Brumley* + + * Deprecated EC_GFp_simple_method(), EC_GFp_mont_method(), + EC_GF2m_simple_method(), EC_GFp_nist_method(), EC_GFp_nistp224_method() + EC_GFp_nistp256_method(), and EC_GFp_nistp521_method(). + Applications should rely on the library automatically assigning a suitable + EC_METHOD internally upon EC_GROUP construction. + + *Billy Bob Brumley* + + * Deprecated EC_GROUP_new(), EC_GROUP_method_of(), and EC_POINT_method_of(). + EC_METHOD is now an internal-only concept and a suitable EC_METHOD is + assigned internally without application intervention. + Users of EC_GROUP_new() should switch to a different suitable constructor. + + *Billy Bob Brumley* + + * Add CAdES-BES signature verification support, mostly derived + from ESSCertIDv2 TS (RFC 5816) contribution by Marek Klein. + + *Filipe Raimundo da Silva* + + * Add CAdES-BES signature scheme and attributes support (RFC 5126) to CMS API. + + *Antonio Iacono* + + * Deprecated EC_POINT_make_affine() and EC_POINTs_make_affine(). These + functions are not widely used and now OpenSSL automatically perform this + conversion when needed. + + *Billy Bob Brumley* + + * Deprecated EC_GROUP_precompute_mult(), EC_GROUP_have_precompute_mult(), and + EC_KEY_precompute_mult(). These functions are not widely used and + applications should instead switch to named curves which OpenSSL has + hardcoded lookup tables for. + + *Billy Bob Brumley* + * Deprecated EC_POINTs_mul(). This function is not widely used and applications should instead use the L function. @@ -35,6 +97,12 @@ OpenSSL 3.0 *Shane Lontis* + * The SSL option SSL_OP_IGNORE_UNEXPECTED_EOF is introduced. If that option + is set, an unexpected EOF is ignored, it pretends a close notify was received + instead and so the returned error becomes SSL_ERROR_ZERO_RETURN. + + *Dmitry Belyavskiy* + * Deprecated EC_POINT_set_Jprojective_coordinates_GFp() and EC_POINT_get_Jprojective_coordinates_GFp(). These functions are not widely used and applications should instead use the @@ -109,6 +177,12 @@ OpenSSL 3.0 *David von Oheimb* + * BIO_do_connect and BIO_do_handshake have been extended: + If domain name resolution yields multiple IP addresses all of them are tried + after connect() failures. + + *David von Oheimb* + * All of the low level RSA functions have been deprecated including: RSA_new_method, RSA_size, RSA_security_bits, RSA_get0_pss_params, @@ -287,8 +361,8 @@ OpenSSL 3.0 and HMAC_CTX_get_md. Use of these low level functions has been informally discouraged for a long - time. Instead applications should use L, - L, L, L + time. Instead applications should use L, + L, L, L and L. *Paul Dale* @@ -311,8 +385,8 @@ OpenSSL 3.0 CMAC_CTX_copy, CMAC_Init, CMAC_Update, CMAC_Final and CMAC_resume. Use of these low level functions has been informally discouraged for a long - time. Instead applications should use L, - L, L, L + time. Instead applications should use L, + L, L, L and L. *Paul Dale* @@ -514,13 +588,6 @@ OpenSSL 3.0 - SSL_CTX_load_verify_dir() - SSL_CTX_load_verify_store() - Also, the following functions are now deprecated: - - - X509_STORE_load_locations() (use X509_STORE_load_file(), - X509_STORE_load_path() or X509_STORE_load_store() instead) - - SSL_CTX_load_verify_locations() (use SSL_CTX_load_verify_file(), - SSL_CTX_load_verify_dir() or SSL_CTX_load_verify_store() instead) - *Richard Levitte* * Added a new method to gather entropy on VMS, based on SYS$GET_ENTROPY. diff --git a/Configurations/10-main.conf b/Configurations/10-main.conf index 7b5da5c4..a44a74cb 100644 --- a/Configurations/10-main.conf +++ b/Configurations/10-main.conf @@ -1004,7 +1004,6 @@ my %targets = ( CFLAGS => add(picker(release => "-fomit-frame-pointer")), lib_cppflags => add("-DL_ENDIAN"), bn_ops => "BN_LLONG", - shared_target => "bsd-shared", asm_arch => 'x86', perlasm_scheme => "a.out", }, diff --git a/Configurations/shared-info.pl b/Configurations/shared-info.pl index 42435914..82e828dc 100644 --- a/Configurations/shared-info.pl +++ b/Configurations/shared-info.pl @@ -40,12 +40,6 @@ my %shared_info; }; }, 'bsd-gcc-shared' => sub { return $shared_info{'linux-shared'}; }, - 'bsd-shared' => sub { - return $shared_info{'gnu-shared'} if detect_gnu_ld(); - return { - shared_ldflag => '-shared -nostdlib', - }; - }, 'darwin-shared' => { module_ldflags => '-bundle', shared_ldflag => '-dynamiclib -current_version $(SHLIB_VERSION_NUMBER) -compatibility_version $(SHLIB_VERSION_NUMBER)', diff --git a/Configure b/Configure index 77380734..5c38a2fb 100755 --- a/Configure +++ b/Configure @@ -423,6 +423,7 @@ my @disablables = ( "poly1305", "posix-io", "psk", + "quic", "rc2", "rc4", "rc5", @@ -579,6 +580,7 @@ my @disable_cascades = ( "legacy" => [ "md2" ], "cmp" => [ "crmf" ], + "tls1_3" => [ "quic" ], # Padlock engine uses low-level AES APIs which are deprecated sub { $disabled{"deprecated-3.0"} } @@ -1124,6 +1126,9 @@ if (scalar(@seed_sources) == 0) { print "Using os-specific seed configuration\n"; push @seed_sources, 'os'; } +if (scalar(grep { $_ eq 'egd' } @seed_sources) > 0) { + delete $disabled{'egd'}; +} if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) { die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1; warn <<_____ if scalar(@seed_sources) == 1; diff --git a/NEWS.md b/NEWS.md index c09e9599..29fb641d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -20,6 +20,7 @@ OpenSSL 3.0 ### Major changes between OpenSSL 1.1.1 and OpenSSL 3.0 [under development] + * Interactive mode is removed from the 'openssl' program. * The X25519, X448, Ed25519, Ed448 and SHAKE256 algorithms are included in the FIPS provider. None have the "fips=yes" property set and, as such, will not be accidentially used. diff --git a/NOTES.PERL b/NOTES.PERL index 42c61277..6c1d7c8c 100644 --- a/NOTES.PERL +++ b/NOTES.PERL @@ -35,9 +35,11 @@ MinGW and Cygwin. The key recommendation is to use "matching" Perl, one that matches build environment. For example, if you will build on Cygwin be sure to use the Cygwin package manager to install Perl. - For MSYS builds use the MSYS provided Perl. For VC-* builds we - recommend ActiveState Perl, available from - http://www.activestate.com/ActivePerl. + For MSYS builds use the MSYS provided Perl. + For VC-* builds we recommend Strawberry Perl, from http://strawberryperl.com. + An alternative is ActiveState Perl, from http://www.activestate.com/ActivePerl + for which you may need to explicitly select the Perl module Win32/Console.pm + available via https://platform.activestate.com/ActiveState. Notes on Perl on VMS -------------------- diff --git a/NOTES.WIN b/NOTES.WIN index ca033602..bc6e3d2c 100644 --- a/NOTES.WIN +++ b/NOTES.WIN @@ -1,58 +1,74 @@ - NOTES FOR THE WINDOWS PLATFORMS - =============================== + NOTES FOR WINDOWS PLATFORMS + =========================== - Windows targets can be classified as "native", ones that use Windows API - directly, and "hosted" which rely on POSIX-compatible layer. "Native" - targets are VC-* (where "VC" stems from abbreviating Microsoft Visual C - compiler) and mingw[64]. "Hosted" platforms are Cygwin and MSYS[2]. Even - though the latter is not directly supported by OpenSSL Team, it's #1 - popular choice for building MinGW targets. In the nutshell MinGW builds - are always cross-compiled. On Linux and Cygwin they look exactly as such - and require --cross-compile-prefix option. While on MSYS[2] it's solved - rather by placing gcc that produces "MinGW binary" code 1st on $PATH. - This is customarily source of confusion. "Hosted" applications "live" in - emulated file system name space with POSIX-y root, mount points, /dev - and even /proc. Confusion is intensified by the fact that MSYS2 shell - (or rather emulated execve(2) call) examines the binary it's about to - start, and if it's found *not* to be linked with MSYS2 POSIX-y thing, - command line arguments that look like file names get translated from - emulated name space to "native". For example '/c/some/where' becomes - 'c:\some\where', '/dev/null' - 'nul'. This creates an illusion that - there is no difference between MSYS2 shell and "MinGW binary", but - there is. Just keep in mind that "MinGW binary" "experiences" Windows - system in exactly same way as one produced by VC, and in its essence - is indistinguishable from the latter. (Which by the way is why - it's referred to in quotes here, as "MinGW binary", it's just as - "native" as it can get.) + There are various options to build and run OpenSSL on the Windows platforms. - Visual C++ builds, a.k.a. VC-* - ============================== + "Native" OpenSSL uses the Windows APIs directly at run time. + To build a native OpenSSL you can either use: + + Microsoft Visual C++ (MSVC) C compiler on the command line + or + MinGW cross compiler + run on the GNU-like development environment MSYS2 + or run on Linux or Cygwin + + "Hosted" OpenSSL relies on an external POSIX compatibility layer + for building (using GNU/Unix shell, compiler, and tools) and at run time. + For this option you can use Cygwin. + + + Visual C++ native builds, a.k.a. VC-* + ===================================== Requirement details ------------------- - In addition to the requirements and instructions listed in INSTALL, + In addition to the requirements and instructions listed in INSTALL.md, these are required as well: - - Perl. We recommend ActiveState Perl, available from - https://www.activestate.com/ActivePerl. Another viable alternative - appears to be Strawberry Perl, http://strawberryperl.com. - You also need the perl module Text::Template, available on CPAN. - Please read NOTES.PERL for more information. + - Perl. + We recommend Strawberry Perl, available from http://strawberryperl.com/ + Please read NOTES.PERL for more information, including the use of CPAN. + An alternative is ActiveState Perl, https://www.activestate.com/ActivePerl + for which you may need to explicitly build the Perl module Win32/Console.pm + via https://platform.activestate.com/ActiveState and then download it. - - Microsoft Visual C compiler. Since we can't test them all, there is - unavoidable uncertainty about which versions are supported. Latest - version along with couple of previous are certainly supported. On - the other hand oldest one is known not to work. Everything between - falls into best-effort category. + - Microsoft Visual C compiler. + Since these are proprietary and ever-changing we cannot test them all. + Older versions may not work. Use a recent version wherever possible. - - Netwide Assembler, a.k.a. NASM, available from https://www.nasm.us, - is required. Note that NASM is the only supported assembler. Even - though Microsoft provided assembler is NOT supported, contemporary - 64-bit version is exercised through continuous integration of - VC-WIN64A-masm target. + - Netwide Assembler (NASM), available from https://www.nasm.us + Note that NASM is the only supported assembler. + Quick start + ----------- + + 1. Install Perl + + 2. Install NASM + + 3. Make sure both Perl and NASM are on your %PATH% + + 4. Use Visual Studio Developer Command Prompt with administrative privileges, + choosing one of its variants depending on the intended architecture. + Or run "cmd" and execute "vcvarsall.bat" with one of the options x86, + x86_amd64, x86_arm, x86_arm64, amd64, amd64_x86, amd64_arm, or amd64_arm64. + This sets up the environment variables needed for nmake.exe, cl.exe, etc. + See also https://docs.microsoft.com/cpp/build/building-on-the-command-line + + 5. From the root of the OpenSSL source directory enter + perl Configure VC-WIN32 if you want 32-bit OpenSSL or + perl Configure VC-WIN64A if you want 64-bit OpenSSL + + 6. nmake + + 7. nmake test + + 8. nmake install + + For the full installation instructions, or if anything goes wrong at any stage, + check the INSTALL.md file. Installation directories ------------------------ @@ -83,7 +99,6 @@ is, of course, to choose a different set of directories by using --prefix and --openssldir when configuring. - Special notes for Universal Windows Platform builds, a.k.a. VC-*-UWP -------------------------------------------------------------------- @@ -91,33 +106,56 @@ - You should define the platform type to "uwp" and the target arch via "vcvarsall.bat" before you compile. For example, if you want to build - "arm64" builds, you should type "vcvarsall.bat x86_arm64 uwp". + "arm64" builds, you should run "vcvarsall.bat x86_arm64 uwp". - mingw and mingw64 - ================= - * MSYS2 shell and development environment installation: + Native OpenSSL built using MinGW + ================================ - Download MSYS2 from https://msys2.github.io/ and follow installation - instructions. Once up and running install even make, perl, (git if - needed,) mingw-w64-i686-gcc and/or mingw-w64-x86_64-gcc. You should - have corresponding MinGW items on your start menu, use *them*, not - generic MSYS2. As implied in opening note, difference between them - is which compiler is found 1st on $PATH. At this point ./config - should recognize correct target, roll as if it was Unix... + MinGW offers an alternative way to build native OpenSSL, by cross compilation. - * It is also possible to build mingw[64] on Linux or Cygwin by - configuring with corresponding --cross-compile-prefix= option. For - example + * Usually the build is done on Windows in a GNU-like environment called MSYS2. + + MSYS2 provides GNU tools, a Unix-like command prompt, + and a UNIX compatibility layer for applications. + However in this context it is only used for building OpenSSL. + The resulting OpenSSL does not rely on MSYS2 to run and is fully native. + + Requirement details + + - MSYS2 shell, from https://www.msys2.org/ + + - Perl, at least version 5.10.0, which usually comes pre-installed with MSYS2 + + - make, installed using "pacman -S make" into the MSYS2 environment + + - MinGW[64] compiler: mingw-w64-i686-gcc and/or mingw-w64-x86_64-gcc. + These compilers must be on your MSYS2 $PATH. + A common error is to not have these on your $PATH. + The MSYS2 version of gcc will not work correctly here. + + In the MSYS2 shell do the configuration depending on the target architecture: + + ./Configure mingw ... + or + ./Configure mingw64 ... + or + ./config ... + for the default architecture. + + Apart from that, follow the Unix / Linux instructions in INSTALL.md. + + * It is also possible to build mingw[64] on Linux or Cygwin. + + In this case configure with the corresponding --cross-compile-prefix= option. + For example ./Configure mingw --cross-compile-prefix=i686-w64-mingw32- ... - or - ./Configure mingw64 --cross-compile-prefix=x86_64-w64-mingw32- ... - This naturally implies that you've installed corresponding add-on - packages. + This requires that you've installed the necessary add-on packages for + mingw[64] cross compilation. Linking your application ======================== @@ -146,28 +184,29 @@ } If you link with OpenSSL .DLLs, then you're expected to include into - your application code small "shim" snippet, which provides glue between - OpenSSL BIO layer and your compiler run-time. See the OPENSSL_Applink - manual page for further details. + your application code a small "shim" snippet, which provides + the glue between the OpenSSL BIO layer and your compiler run-time. + See also the OPENSSL_Applink manual page. - Cygwin, "hosted" environment - ============================ - Cygwin implements a Posix/Unix runtime system (cygwin1.dll) on top of the - Windows subsystem and provides a bash shell and GNU tools environment. - Consequently, a make of OpenSSL with Cygwin is virtually identical to the + Hosted OpenSSL built using Cygwin + ================================= + + Cygwin implements a POSIX/Unix runtime system (cygwin1.dll) on top of the + Windows subsystem and provides a Bash shell and GNU tools environment. + Consequently, a build of OpenSSL with Cygwin is virtually identical to the Unix procedure. To build OpenSSL using Cygwin, you need to: - * Install Cygwin (see https://cygwin.com/) + * Install Cygwin, see https://cygwin.com/ - * Install Cygwin Perl and ensure it is in the path. Recall that - as least 5.10.0 is required. + * Install Cygwin Perl, at least version 5.10.0 + and ensure it is in the $PATH - * Run the Cygwin bash shell + * Run the Cygwin Bash shell - Apart from that, follow the Unix instructions in INSTALL. + Apart from that, follow the Unix / Linux instructions in INSTALL.md. NOTE: "make test" and normal file operations may fail in directories mounted as text (i.e. mount -t c:\somewhere /home) due to Cygwin diff --git a/VERSION b/VERSION index a342bef4..48c68bdd 100644 --- a/VERSION +++ b/VERSION @@ -1,7 +1,7 @@ MAJOR=3 MINOR=0 PATCH=0 -PRE_RELEASE_TAG=alpha3-dev +PRE_RELEASE_TAG=alpha4-dev BUILD_METADATA= RELEASE_DATE="" SHLIB_VERSION=3 diff --git a/apps/build.info b/apps/build.info index 1bbedc1b..e6683b23 100644 --- a/apps/build.info +++ b/apps/build.info @@ -14,8 +14,8 @@ $OPENSSLSRC=\ openssl.c progs.c \ asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c dgst.c \ enc.c errstr.c \ - genpkey.c genrsa.c kdf.c mac.c nseq.c ocsp.c passwd.c pkcs12.c pkcs7.c \ - pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c rsa.c \ + genpkey.c kdf.c mac.c nseq.c passwd.c pkcs7.c \ + pkcs8.c pkey.c pkeyparam.c pkeyutl.c prime.c rand.c req.c \ rsautl.c s_client.c s_server.c s_time.c sess_id.c smime.c speed.c \ spkac.c verify.c version.c x509.c rehash.c storeutl.c \ list.c info.c provider.c fipsinstall.c @@ -43,6 +43,9 @@ ENDIF IF[{- !$disabled{'engine'} -}] $OPENSSLSRC=$OPENSSLSRC engine.c ENDIF +IF[{- !$disabled{'rsa'} -}] +$OPENSSLSRC=$OPENSSLSRC rsa.c genrsa.c +ENDIF IF[{- !$disabled{'cmp'} -}] $OPENSSLSRC=$OPENSSLSRC cmp.c cmp_mock_srv.c ENDIF diff --git a/apps/cmp.c b/apps/cmp.c index 72ebe34d..f80410fe 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -347,16 +347,16 @@ const OPTIONS cmp_options[] = { OPT_SECTION("Server authentication"), {"trusted", OPT_TRUSTED, 's', - "Trusted certs used for CMP server authentication when verifying responses"}, + "Certificates to trust as chain roots when verifying signed CMP responses"}, {OPT_MORE_STR, 0, 0, "unless -srvcert is given"}, {"untrusted", OPT_UNTRUSTED, 's', - "Intermediate certs for chain construction verifying CMP/TLS/enrolled certs"}, + "Intermediate CA certs for chain construction for CMP/TLS/enrolled certs"}, {"srvcert", OPT_SRVCERT, 's', - "Specific CMP server cert to use and trust directly when verifying responses"}, + "Server cert to pin and trust directly when verifying signed CMP responses"}, {"recipient", OPT_RECIPIENT, 's', - "Distinguished Name (DN) of the recipient to use unless -srvcert is given"}, + "Distinguished Name (DN) to use as msg recipient; see man page for defaults"}, {"expect_sender", OPT_EXPECT_SENDER, 's', - "DN of expected response sender. Defaults to DN of -srvcert, if provided"}, + "DN of expected sender of responses. Defaults to subject of -srvcert, if any"}, {"ignore_keyusage", OPT_IGNORE_KEYUSAGE, '-', "Ignore CMP signer cert key usage, else 'digitalSignature' must be allowed"}, {"unprotected_errors", OPT_UNPROTECTED_ERRORS, '-', @@ -1637,8 +1637,7 @@ static SSL_CTX *setup_ssl_ctx(OSSL_CMP_CTX *ctx, ENGINE *e) /* * Any further certs and any untrusted certs are used for constructing - * the client cert chain to be provided along with the TLS client cert - * to the TLS server. + * the chain to be provided with the TLS client cert to the TLS server. */ if (!SSL_CTX_set0_chain(ssl_ctx, certs)) { CMP_err("could not set TLS client cert chain"); @@ -2097,9 +2096,12 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *e) goto oom; if (opt_proxy != NULL && !OSSL_CMP_CTX_set1_proxy(ctx, opt_proxy)) goto oom; + if (opt_no_proxy != NULL && !OSSL_CMP_CTX_set1_no_proxy(ctx, opt_no_proxy)) + goto oom; (void)BIO_snprintf(server_buf, sizeof(server_buf), "http%s://%s%s%s/%s", opt_tls_used ? "s" : "", opt_server, server_port == 0 ? "" : ":", server_port_s, + opt_path == NULL ? "" : opt_path[0] == '/' ? opt_path + 1 : opt_path); if (opt_proxy != NULL) @@ -2221,7 +2223,7 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx, ENGINE *e) if (!set_name(opt_recipient, OSSL_CMP_CTX_set1_recipient, ctx, "recipient") || !set_name(opt_expect_sender, OSSL_CMP_CTX_set1_expected_sender, ctx, "expected sender")) - goto oom; + goto err; if (opt_geninfo != NULL && !handle_opt_geninfo(ctx)) goto err; @@ -2977,12 +2979,13 @@ int cmp_main(int argc, char **argv) if ((acbio = http_server_init_bio(prog, opt_port)) == NULL) goto err; while (opt_max_msgs <= 0 || msgs < opt_max_msgs) { + char *path = NULL; OSSL_CMP_MSG *req = NULL; OSSL_CMP_MSG *resp = NULL; ret = http_server_get_asn1_req(ASN1_ITEM_rptr(OSSL_CMP_MSG), - (ASN1_VALUE **)&req, &cbio, acbio, - prog, 0, 0); + (ASN1_VALUE **)&req, &path, + &cbio, acbio, prog, 0, 0); if (ret == 0) continue; if (ret++ == -1) @@ -2991,17 +2994,32 @@ int cmp_main(int argc, char **argv) ret = 0; msgs++; if (req != NULL) { + if (strcmp(path, "") != 0 && strcmp(path, "pkix/") != 0) { + (void)http_server_send_status(cbio, 404, "Not Found"); + CMP_err1("Expecting empty path or 'pkix/' but got '%s'", + path); + OPENSSL_free(path); + OSSL_CMP_MSG_free(req); + goto cont; + } + OPENSSL_free(path); resp = OSSL_CMP_CTX_server_perform(cmp_ctx, req); OSSL_CMP_MSG_free(req); - if (resp == NULL) + if (resp == NULL) { + (void)http_server_send_status(cbio, + 500, "Internal Server Error"); break; /* treated as fatal error */ + } ret = http_server_send_asn1_resp(cbio, "application/pkixcmp", ASN1_ITEM_rptr(OSSL_CMP_MSG), (const ASN1_VALUE *)resp); OSSL_CMP_MSG_free(resp); if (!ret) break; /* treated as fatal error */ + } else { + (void)http_server_send_status(cbio, 400, "Bad Request"); } + cont: BIO_free_all(cbio); cbio = NULL; } diff --git a/apps/cmp_mock_srv.c b/apps/cmp_mock_srv.c index b45f9855..c63e5f99 100644 --- a/apps/cmp_mock_srv.c +++ b/apps/cmp_mock_srv.c @@ -208,6 +208,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, } if (ctx->certOut != NULL && (*certOut = X509_dup(ctx->certOut)) == NULL) + /* TODO better return a cert produced from data in request template */ goto err; if (ctx->chainOut != NULL && (*chainOut = X509_chain_up_ref(ctx->chainOut)) == NULL) diff --git a/apps/cms.c b/apps/cms.c index 6b5577ec..445fec53 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -670,12 +670,18 @@ int cms_main(int argc, char **argv) goto opthelp; } - if (flags & CMS_CADES) { - if (flags & CMS_NOATTR) { + if ((flags & CMS_CADES) != 0) { + if ((flags & CMS_NOATTR) != 0) { BIO_puts(bio_err, "Incompatible options: " "CAdES required signed attributes\n"); goto opthelp; } + if (operation == SMIME_VERIFY + && (flags & (CMS_NO_SIGNER_CERT_VERIFY | CMS_NO_ATTR_VERIFY)) != 0) { + BIO_puts(bio_err, "Incompatible options: CAdES validation require" + " certs and signed attributes validations\n"); + goto opthelp; + } } if (operation & SMIME_SIGNERS) { @@ -1115,7 +1121,8 @@ int cms_main(int argc, char **argv) goto end; } else if (operation == SMIME_VERIFY) { if (CMS_verify(cms, other, store, indata, out, flags) > 0) { - BIO_printf(bio_err, "Verification successful\n"); + BIO_printf(bio_err, "%s Verification successful\n", + (flags & CMS_CADES) ? "CAdES" : "CMS"); } else { BIO_printf(bio_err, "Verification failure\n"); if (verify_retcode) diff --git a/apps/dhparam.c b/apps/dhparam.c index 3e5f4095..84f5f3ed 100644 --- a/apps/dhparam.c +++ b/apps/dhparam.c @@ -84,7 +84,7 @@ const OPTIONS dhparam_options[] = { int dhparam_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; - DH *dh = NULL; + DH *dh = NULL, *alloc_dh = NULL; EVP_PKEY *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; char *infile = NULL, *outfile = NULL, *prog; @@ -177,7 +177,7 @@ int dhparam_main(int argc, char **argv) #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (dsaparam && g) { BIO_printf(bio_err, - "generator may not be chosen for DSA parameters\n"); + "Error, generator may not be chosen for DSA parameters\n"); goto end; } #endif @@ -198,10 +198,8 @@ int dhparam_main(int argc, char **argv) DSA *dsa = DSA_new(); BN_GENCB *cb = BN_GENCB_new(); - if (cb == NULL) { - ERR_print_errors(bio_err); + if (cb == NULL) goto end; - } BN_GENCB_set(cb, dh_cb, bio_err); @@ -212,23 +210,20 @@ int dhparam_main(int argc, char **argv) cb)) { DSA_free(dsa); BN_GENCB_free(cb); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Error, unable to generate DSA parameters\n"); goto end; } - dh = DSA_dup_DH(dsa); + dh = alloc_dh = DSA_dup_DH(dsa); DSA_free(dsa); BN_GENCB_free(cb); - if (dh == NULL) { - ERR_print_errors(bio_err); + if (dh == NULL) goto end; - } } else #endif { ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL); if (ctx == NULL) { - ERR_print_errors(bio_err); BIO_printf(bio_err, "Error, DH key generation context allocation failed\n"); goto end; @@ -242,20 +237,18 @@ int dhparam_main(int argc, char **argv) if (!EVP_PKEY_paramgen_init(ctx)) { BIO_printf(bio_err, "Error, unable to initialise DH param generation\n"); - ERR_print_errors(bio_err); goto end; } if (!EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, num)) { BIO_printf(bio_err, "Error, unable to set DH prime length\n"); - ERR_print_errors(bio_err); goto end; } if (!EVP_PKEY_paramgen(ctx, &pkey)) { BIO_printf(bio_err, "Error, DH generation failed\n"); - ERR_print_errors(bio_err); goto end; } + dh = EVP_PKEY_get0_DH(pkey); } } else { in = bio_open_default(infile, 'r', informat); @@ -272,17 +265,14 @@ int dhparam_main(int argc, char **argv) dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); if (dsa == NULL) { - BIO_printf(bio_err, "unable to load DSA parameters\n"); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Error, unable to load DSA parameters\n"); goto end; } - dh = DSA_dup_DH(dsa); + dh = alloc_dh = DSA_dup_DH(dsa); DSA_free(dsa); - if (dh == NULL) { - ERR_print_errors(bio_err); + if (dh == NULL) goto end; - } } else #endif { @@ -291,18 +281,17 @@ int dhparam_main(int argc, char **argv) * We have no PEM header to determine what type of DH params it * is. We'll just try both. */ - dh = ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, in, NULL); + dh = alloc_dh = ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, in, NULL); /* BIO_reset() returns 0 for success for file BIOs only!!! */ if (dh == NULL && BIO_reset(in) == 0) - dh = ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, in, NULL); + dh = alloc_dh = ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, in, NULL); } else { /* informat == FORMAT_PEM */ - dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); + dh = alloc_dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); } if (dh == NULL) { - BIO_printf(bio_err, "unable to load DH parameters\n"); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Error, unable to load DH parameters\n"); goto end; } } @@ -314,8 +303,7 @@ int dhparam_main(int argc, char **argv) if (check) { if (!EVP_PKEY_param_check(ctx) /* DH_check(dh, &i) */) { - ERR_print_errors(bio_err); - BIO_printf(bio_err, "ERROR: Invalid parameters generated\n"); + BIO_printf(bio_err, "Error, invalid parameters generated\n"); goto end; } BIO_printf(bio_err, "DH parameters appear to be ok.\n"); @@ -324,7 +312,7 @@ int dhparam_main(int argc, char **argv) * We have generated parameters but DH_check() indicates they are * invalid! This should never happen! */ - BIO_printf(bio_err, "ERROR: Invalid parameters generated\n"); + BIO_printf(bio_err, "Error, invalid parameters generated\n"); goto end; } } @@ -382,13 +370,15 @@ int dhparam_main(int argc, char **argv) i = PEM_write_bio_DHparams(out, dh); } if (!i) { - BIO_printf(bio_err, "unable to write DH parameters\n"); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Error, unable to write DH parameters\n"); goto end; } } ret = 0; end: + if (ret != 0) + ERR_print_errors(bio_err); + DH_free(alloc_dh); BIO_free(in); BIO_free_all(out); EVP_PKEY_free(pkey); diff --git a/apps/dsaparam.c b/apps/dsaparam.c index 9b73a31c..dfcaf38c 100644 --- a/apps/dsaparam.c +++ b/apps/dsaparam.c @@ -66,9 +66,8 @@ const OPTIONS dsaparam_options[] = { int dsaparam_main(int argc, char **argv) { ENGINE *e = NULL; - DSA *dsa = NULL; BIO *in = NULL, *out = NULL; - EVP_PKEY *pkey = NULL; + EVP_PKEY *params = NULL, *pkey = NULL; EVP_PKEY_CTX *ctx = NULL; int numbits = -1, num = 0, genkey = 0; int informat = FORMAT_PEM, outformat = FORMAT_PEM, noout = 0, C = 0; @@ -150,7 +149,6 @@ int dsaparam_main(int argc, char **argv) ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL); if (ctx == NULL) { - ERR_print_errors(bio_err); BIO_printf(bio_err, "Error, DSA parameter generation context allocation failed\n"); goto end; @@ -170,62 +168,41 @@ int dsaparam_main(int argc, char **argv) BIO_printf(bio_err, "This could take some time\n"); } if (EVP_PKEY_paramgen_init(ctx) <= 0) { - ERR_print_errors(bio_err); BIO_printf(bio_err, "Error, DSA key generation paramgen init failed\n"); goto end; } if (!EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, num)) { - ERR_print_errors(bio_err); BIO_printf(bio_err, "Error, DSA key generation setting bit length failed\n"); goto end; } - if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) { - ERR_print_errors(bio_err); + if (EVP_PKEY_paramgen(ctx, ¶ms) <= 0) { BIO_printf(bio_err, "Error, DSA key generation failed\n"); goto end; } - dsa = EVP_PKEY_get1_DSA(pkey); - if (dsa == NULL) { - ERR_print_errors(bio_err); - BIO_printf(bio_err, "Error, DSA key extraction failed\n"); - goto end; - } } else if (informat == FORMAT_ASN1) { - dsa = d2i_DSAparams_bio(in, NULL); + params = d2i_KeyParams_bio(EVP_PKEY_DSA, NULL, in); } else { - dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL); + params = PEM_read_bio_Parameters(in, NULL); } - if (dsa == NULL) { - BIO_printf(bio_err, "unable to load DSA parameters\n"); - ERR_print_errors(bio_err); + if (params == NULL) { + BIO_printf(bio_err, "Error, unable to load DSA parameters\n"); goto end; } - if (pkey == NULL) { - pkey = EVP_PKEY_new(); - if (pkey == NULL) { - BIO_printf(bio_err, "Error, unable to allocate PKEY object\n"); - ERR_print_errors(bio_err); - goto end; - } - if (!EVP_PKEY_set1_DSA(pkey, dsa)) { - BIO_printf(bio_err, "Error, unable to set DSA parameters\n"); - ERR_print_errors(bio_err); - goto end; - } - } if (text) { - EVP_PKEY_print_params(out, pkey, 0, NULL); + EVP_PKEY_print_params(out, params, 0, NULL); } if (C) { - const BIGNUM *p = NULL, *q = NULL, *g = NULL; + BIGNUM *p = NULL, *q = NULL, *g = NULL; unsigned char *data; int len, bits_p; - DSA_get0_pqg(dsa, &p, &q, &g); + EVP_PKEY_get_bn_param(params, "p", &p); + EVP_PKEY_get_bn_param(params, "q", &q); + EVP_PKEY_get_bn_param(params, "g", &g); len = BN_num_bytes(p); bits_p = BN_num_bits(p); @@ -261,56 +238,46 @@ int dsaparam_main(int argc, char **argv) if (!noout) { if (outformat == FORMAT_ASN1) - i = i2d_DSAparams_bio(out, dsa); + i = i2d_KeyParams_bio(out, params); else - i = PEM_write_bio_DSAparams(out, dsa); + i = PEM_write_bio_Parameters(out, params); if (!i) { - BIO_printf(bio_err, "unable to write DSA parameters\n"); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Error, unable to write DSA parameters\n"); goto end; } } if (genkey) { - DSA *dsakey; - EVP_PKEY_CTX_free(ctx); - ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL); + ctx = EVP_PKEY_CTX_new(params, NULL); if (ctx == NULL) { - ERR_print_errors(bio_err); BIO_printf(bio_err, "Error, DSA key generation context allocation failed\n"); goto end; } if (!EVP_PKEY_keygen_init(ctx)) { - BIO_printf(bio_err, "unable to initialise for key generation\n"); - ERR_print_errors(bio_err); + BIO_printf(bio_err, + "Error, unable to initialise for key generation\n"); goto end; } if (!EVP_PKEY_keygen(ctx, &pkey)) { - BIO_printf(bio_err, "unable to generate key\n"); - ERR_print_errors(bio_err); - goto end; - } - dsakey = EVP_PKEY_get0_DSA(pkey); - if (dsakey == NULL) { - BIO_printf(bio_err, "unable to extract generated key\n"); - ERR_print_errors(bio_err); + BIO_printf(bio_err, "Error, unable to generate key\n"); goto end; } assert(private); if (outformat == FORMAT_ASN1) - i = i2d_DSAPrivateKey_bio(out, dsakey); + i = i2d_PrivateKey_bio(out, pkey); else - i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL, - NULL); + i = PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, NULL); } ret = 0; end: + if (ret != 0) + ERR_print_errors(bio_err); BIO_free(in); BIO_free_all(out); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(pkey); - DSA_free(dsa); + EVP_PKEY_free(params); release_engine(e); return ret; } diff --git a/apps/ecparam.c b/apps/ecparam.c index 635bde2d..4abb0517 100644 --- a/apps/ecparam.c +++ b/apps/ecparam.c @@ -305,7 +305,6 @@ int ecparam_main(int argc, char **argv) size_t buf_len = 0, tmp_len = 0; const EC_POINT *point; int is_prime, len = 0; - const EC_METHOD *meth = EC_GROUP_method_of(group); if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL @@ -317,7 +316,7 @@ int ecparam_main(int argc, char **argv) goto end; } - is_prime = (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field); + is_prime = (EC_GROUP_get_field_type(group) == NID_X9_62_prime_field); if (!is_prime) { BIO_printf(bio_err, "Can only handle X9.62 prime fields\n"); goto end; diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c index 1eb183f3..e0fe43e8 100644 --- a/apps/fipsinstall.c +++ b/apps/fipsinstall.c @@ -366,7 +366,7 @@ opthelp: goto end; } - ctx = EVP_MAC_CTX_new(mac); + ctx = EVP_MAC_new_ctx(mac); if (ctx == NULL) { BIO_printf(bio_err, "Unable to create MAC CTX for module check\n"); goto end; @@ -380,7 +380,7 @@ opthelp: if (params == NULL) goto end; - if (!EVP_MAC_CTX_set_params(ctx, params)) { + if (!EVP_MAC_set_ctx_params(ctx, params)) { BIO_printf(bio_err, "MAC parameter error\n"); ERR_print_errors(bio_err); ok = 0; @@ -390,7 +390,7 @@ opthelp: goto end; } - ctx2 = EVP_MAC_CTX_dup(ctx); + ctx2 = EVP_MAC_dup_ctx(ctx); if (ctx2 == NULL) { BIO_printf(bio_err, "Unable to create MAC CTX for install indicator\n"); goto end; @@ -450,8 +450,8 @@ cleanup: BIO_free(module_bio); sk_OPENSSL_STRING_free(opts); EVP_MAC_free(mac); - EVP_MAC_CTX_free(ctx2); - EVP_MAC_CTX_free(ctx); + EVP_MAC_free_ctx(ctx2); + EVP_MAC_free_ctx(ctx); OPENSSL_free(read_buffer); free_config_and_unload(conf); return ret; diff --git a/apps/genrsa.c b/apps/genrsa.c index 44ce4288..57c710f9 100644 --- a/apps/genrsa.c +++ b/apps/genrsa.c @@ -29,11 +29,14 @@ static int verbose = 0; -static int genrsa_cb(EVP_PKEY_CTX *ctx); +static int genrsa_cb(int p, int n, BN_GENCB *cb); typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_3, OPT_F4, OPT_ENGINE, +#ifndef OPENSSL_NO_DEPRECATED_3_0 + OPT_3, +#endif + OPT_F4, OPT_ENGINE, OPT_OUT, OPT_PASSOUT, OPT_CIPHER, OPT_PRIMES, OPT_VERBOSE, OPT_R_ENUM, OPT_PROV_ENUM } OPTION_CHOICE; @@ -48,9 +51,11 @@ const OPTIONS genrsa_options[] = { #endif OPT_SECTION("Input"), - {"3", OPT_3, '-', "Use 3 for the E value"}, - {"F4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, - {"f4", OPT_F4, '-', "Use F4 (0x10001) for the E value"}, +#ifndef OPENSSL_NO_DEPRECATED_3_0 + {"3", OPT_3, '-', "(deprecated) Use 3 for the E value"}, +#endif + {"F4", OPT_F4, '-', "Use the Fermat number F4 (0x10001) for the E value"}, + {"f4", OPT_F4, '-', "Use the Fermat number F4 (0x10001) for the E value"}, OPT_SECTION("Output"), {"out", OPT_OUT, '>', "Output the key to specified file"}, @@ -70,24 +75,24 @@ const OPTIONS genrsa_options[] = { int genrsa_main(int argc, char **argv) { BN_GENCB *cb = BN_GENCB_new(); + PW_CB_DATA cb_data; ENGINE *eng = NULL; BIGNUM *bn = BN_new(); - RSA *rsa; BIO *out = NULL; const BIGNUM *e; - EVP_PKEY *pkey = NULL; - EVP_PKEY_CTX *ctx = NULL; + RSA *rsa = NULL; const EVP_CIPHER *enc = NULL; int ret = 1, num = DEFBITS, private = 0, primes = DEFPRIMES; unsigned long f4 = RSA_F4; char *outfile = NULL, *passoutarg = NULL, *passout = NULL; char *prog, *hexe, *dece; OPTION_CHOICE o; - unsigned char *ebuf = NULL; if (bn == NULL || cb == NULL) goto end; + BN_GENCB_set(cb, genrsa_cb, bio_err); + prog = opt_init(argc, argv, genrsa_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -100,9 +105,11 @@ opthelp: ret = 0; opt_help(genrsa_options); goto end; +#ifndef OPENSSL_NO_DEPRECATED_3_0 case OPT_3: - f4 = RSA_3; + f4 = 3; break; +#endif case OPT_F4: f4 = RSA_F4; break; @@ -162,74 +169,49 @@ opthelp: if (out == NULL) goto end; - if (!init_gen_str(&ctx, "RSA", eng, 0)) - goto end; - - EVP_PKEY_CTX_set_cb(ctx, genrsa_cb); - EVP_PKEY_CTX_set_app_data(ctx, bio_err); - - if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, num) <= 0) { - BIO_printf(bio_err, "Error setting RSA length\n"); - goto end; - } - if (!BN_set_word(bn, f4)) { - BIO_printf(bio_err, "Error allocating RSA public exponent\n"); - goto end; - } - if (EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, bn) <= 0) { - BIO_printf(bio_err, "Error setting RSA public exponent\n"); - goto end; - } - if (EVP_PKEY_CTX_set_rsa_keygen_primes(ctx, primes) <= 0) { - BIO_printf(bio_err, "Error setting number of primes\n"); - goto end; - } if (verbose) BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus (%d primes)\n", num, primes); - if (!EVP_PKEY_keygen(ctx, &pkey)) { - BIO_printf(bio_err, "Error generating RSA key\n"); + rsa = eng ? RSA_new_method(eng) : RSA_new(); + if (rsa == NULL) goto end; - } - if (verbose) { - if ((rsa = EVP_PKEY_get0_RSA(pkey)) != NULL) { - RSA_get0_key(rsa, NULL, &e, NULL); - } else { - BIO_printf(bio_err, "Error cannot access RSA e\n"); - goto end; - } - hexe = BN_bn2hex(e); - dece = BN_bn2dec(e); - if (hexe && dece) { - BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe); - } - OPENSSL_free(hexe); - OPENSSL_free(dece); + if (!BN_set_word(bn, f4) + || !RSA_generate_multi_prime_key(rsa, num, primes, bn, cb)) + goto end; + + RSA_get0_key(rsa, NULL, &e, NULL); + hexe = BN_bn2hex(e); + dece = BN_bn2dec(e); + if (hexe && dece && verbose) { + BIO_printf(bio_err, "e is %s (0x%s)\n", dece, hexe); } - if (!PEM_write_bio_PrivateKey(out, pkey, enc, NULL, 0, NULL, passout)) + OPENSSL_free(hexe); + OPENSSL_free(dece); + cb_data.password = passout; + cb_data.prompt_info = outfile; + assert(private); + if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, + (pem_password_cb *)password_callback, + &cb_data)) goto end; ret = 0; end: BN_free(bn); BN_GENCB_free(cb); - EVP_PKEY_CTX_free(ctx); - EVP_PKEY_free(pkey); + RSA_free(rsa); BIO_free_all(out); release_engine(eng); OPENSSL_free(passout); - OPENSSL_free(ebuf); if (ret != 0) ERR_print_errors(bio_err); return ret; } -static int genrsa_cb(EVP_PKEY_CTX *ctx) +static int genrsa_cb(int p, int n, BN_GENCB *cb) { char c = '*'; - BIO *b = EVP_PKEY_CTX_get_app_data(ctx); - int p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); if (!verbose) return 1; @@ -242,7 +224,7 @@ static int genrsa_cb(EVP_PKEY_CTX *ctx) c = '*'; if (p == 3) c = '\n'; - BIO_write(b, &c, 1); - (void)BIO_flush(b); + BIO_write(BN_GENCB_get_arg(cb), &c, 1); + (void)BIO_flush(BN_GENCB_get_arg(cb)); return 1; } diff --git a/apps/include/apps.h b/apps/include/apps.h index b0512222..e9a63552 100644 --- a/apps/include/apps.h +++ b/apps/include/apps.h @@ -15,6 +15,7 @@ # include "internal/sockets.h" /* for openssl_fdset() */ # include +# include # include # ifndef OPENSSL_NO_POSIX_IO # include @@ -29,7 +30,6 @@ # include # include # include -# include # include # include "apps_ui.h" # include "opt.h" @@ -179,6 +179,7 @@ typedef struct ca_db_st { # endif } CA_DB; +void app_bail_out(char *fmt, ...); void* app_malloc(int sz, const char *what); BIGNUM *load_serial(const char *serialfile, int create, ASN1_INTEGER **retai); int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial, @@ -227,30 +228,6 @@ void print_cert_checks(BIO *bio, X509 *x, void store_setup_crl_download(X509_STORE *st); -typedef struct app_http_tls_info_st { - const char *server; - const char *port; - int use_proxy; - long timeout; - SSL_CTX *ssl_ctx; -} APP_HTTP_TLS_INFO; -BIO *app_http_tls_cb(BIO *hbio, /* APP_HTTP_TLS_INFO */ void *arg, - int connect, int detail); -# ifndef OPENSSL_NO_SOCK -ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy, - const char *no_proxy, SSL_CTX *ssl_ctx, - const STACK_OF(CONF_VALUE) *headers, - long timeout, const char *expected_content_type, - const ASN1_ITEM *it); -ASN1_VALUE *app_http_post_asn1(const char *host, const char *port, - const char *path, const char *proxy, - const char *no_proxy, SSL_CTX *ctx, - const STACK_OF(CONF_VALUE) *headers, - const char *content_type, - ASN1_VALUE *req, const ASN1_ITEM *req_it, - long timeout, const ASN1_ITEM *rsp_it); -# endif - # define EXT_COPY_NONE 0 # define EXT_COPY_ADD 1 # define EXT_COPY_ALL 2 diff --git a/apps/include/http_server.h b/apps/include/http_server.h index 8c655213..12647538 100644 --- a/apps/include/http_server.h +++ b/apps/include/http_server.h @@ -60,23 +60,29 @@ void log_message(const char *prog, int level, const char *fmt, ...); * returns a BIO for accepting requests, NULL on error */ BIO *http_server_init_bio(const char *prog, const char *port); + /*- * Accept an ASN.1-formatted HTTP request * it: the expected request ASN.1 type * preq: pointer to variable where to place the parsed request * pcbio: pointer to variable where to place the BIO for sending the response to + * ppath: pointer to variable where to place the request path, or NULL * acbio: the listening bio (typically as returned by http_server_init_bio()) * prog: the name of the current app - * accept_get: wheter to accept GET requests (in addition to POST requests) + * accept_get: whether to accept GET requests (in addition to POST requests) * timeout: connection timeout (in seconds), or 0 for none/infinite - * returns 0 in case caller should retry, then *preq == *pcbio == NULL - * returns -1 on fatal error; also in this case *preq == *pcbio == NULL - * returns 1 otherwise. In this case it is guaranteed that *pcbio != NULL - * while *preq == NULL if and only if request is invalid + * returns 0 in case caller should retry, then *preq == *ppath == *pcbio == NULL + * returns -1 on fatal error; also then holds *preq == *ppath == *pcbio == NULL + * returns 1 otherwise. In this case it is guaranteed that *pcbio != NULL while + * *ppath == NULL and *preq == NULL if and only if the request is invalid, + * On return value 1 the caller is responsible for sending an HTTP response, + * using http_server_send_asn1_resp() or http_server_send_status(). + * The caller must free any non-NULL *preq, *ppath, and *pcbio pointers. */ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, - BIO **pcbio, BIO *acbio, - const char *prog, int accept_get, int timeout); + char **ppath, BIO **pcbio, BIO *acbio, + const char *prog, int accept_get, int timeout); + /*- * Send an ASN.1-formatted HTTP response * cbio: destination BIO (typically as returned by http_server_get_asn1_req()) @@ -89,6 +95,16 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, */ int http_server_send_asn1_resp(BIO *cbio, const char *content_type, const ASN1_ITEM *it, const ASN1_VALUE *resp); + +/*- + * Send a trivial HTTP response, typically to report an error or OK + * cbio: destination BIO (typically as returned by http_server_get_asn1_req()) + * status: the status code to send + * reason: the corresponding human-readable string + * returns 1 on success, 0 on failure + */ +int http_server_send_status(BIO *cbio, int status, const char *reason); + # endif # ifdef HTTP_DAEMON diff --git a/apps/kdf.c b/apps/kdf.c index 8d11807f..dd6cc925 100644 --- a/apps/kdf.c +++ b/apps/kdf.c @@ -104,7 +104,7 @@ opthelp: goto opthelp; } - ctx = EVP_KDF_CTX_new(kdf); + ctx = EVP_KDF_new_ctx(kdf); if (ctx == NULL) goto err; @@ -116,7 +116,7 @@ opthelp: if (params == NULL) goto err; - if (!EVP_KDF_CTX_set_params(ctx, params)) { + if (!EVP_KDF_set_ctx_params(ctx, params)) { BIO_printf(bio_err, "KDF parameter error\n"); ERR_print_errors(bio_err); ok = 0; @@ -161,7 +161,7 @@ err: OPENSSL_clear_free(dkm_bytes, dkm_len); sk_OPENSSL_STRING_free(opts); EVP_KDF_free(kdf); - EVP_KDF_CTX_free(ctx); + EVP_KDF_free_ctx(ctx); BIO_free(out); OPENSSL_free(hexout); return ret; diff --git a/apps/lib/apps.c b/apps/lib/apps.c index 4337cc6c..f97f6a4b 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -438,10 +438,6 @@ X509 *load_cert_pass(const char *uri, int maybe_stdin, if (desc == NULL) desc = "certificate"; - if (uri == NULL) { - unbuffer(stdin); - uri = ""; - } (void)load_key_cert_crl(uri, maybe_stdin, pass, desc, NULL, &cert, NULL); if (cert == NULL) { BIO_printf(bio_err, "Unable to load %s\n", desc); @@ -453,7 +449,7 @@ X509 *load_cert_pass(const char *uri, int maybe_stdin, /* the format parameter is meanwhile not needed anymore and thus ignored */ X509 *load_cert(const char *uri, int format, const char *desc) { - return load_cert_pass(uri, 0, NULL, desc); + return load_cert_pass(uri, 1, NULL, desc); } /* the format parameter is meanwhile not needed anymore and thus ignored */ @@ -671,16 +667,24 @@ static int load_certs_crls(const char *file, int format, return rv; } +void app_bail_out(char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + BIO_vprintf(bio_err, fmt, args); + va_end(args); + ERR_print_errors(bio_err); + exit(1); +} + void* app_malloc(int sz, const char *what) { void *vp = OPENSSL_malloc(sz); - if (vp == NULL) { - BIO_printf(bio_err, "%s: Could not allocate %d bytes for %s\n", - opt_getprog(), sz, what); - ERR_print_errors(bio_err); - exit(1); - } + if (vp == NULL) + app_bail_out("%s: Could not allocate %d bytes for %s\n", + opt_getprog(), sz, what); return vp; } @@ -1627,7 +1631,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti) goto err; } - while (*cp) { + while (*cp != '\0') { char *bp = work; char *typestr = bp; unsigned char *valstr; @@ -1636,12 +1640,12 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti) nextismulti = 0; /* Collect the type */ - while (*cp && *cp != '=') + while (*cp != '\0' && *cp != '=') *bp++ = *cp++; if (*cp == '\0') { BIO_printf(bio_err, - "%s: Hit end of string before finding the '='\n", - opt_getprog()); + "%s: Hit end of string before finding the '='\n", + opt_getprog()); goto err; } *bp++ = '\0'; @@ -1649,7 +1653,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti) /* Collect the value. */ valstr = (unsigned char *)bp; - for (; *cp && *cp != '/'; *bp++ = *cp++) { + for (; *cp != '\0' && *cp != '/'; *bp++ = *cp++) { if (canmulti && *cp == '+') { nextismulti = 1; break; @@ -1664,7 +1668,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti) *bp++ = '\0'; /* If not at EOS (must be + or /), move forward. */ - if (*cp) + if (*cp != '\0') ++cp; /* Parse */ @@ -1683,6 +1687,7 @@ X509_NAME *parse_name(const char *cp, long chtype, int canmulti) if (!X509_NAME_add_entry_by_NID(n, nid, chtype, valstr, strlen((char *)valstr), -1, ismulti ? -1 : 0)) { + ERR_print_errors(bio_err); BIO_printf(bio_err, "%s: Error adding name attribute \"/%s=%s\"\n", opt_getprog(), typestr ,valstr); goto err; @@ -1949,137 +1954,6 @@ void store_setup_crl_download(X509_STORE *st) X509_STORE_set_lookup_crls_cb(st, crls_http_cb); } -#ifndef OPENSSL_NO_SOCK -static const char *tls_error_hint(void) -{ - unsigned long err = ERR_peek_error(); - - if (ERR_GET_LIB(err) != ERR_LIB_SSL) - err = ERR_peek_last_error(); - if (ERR_GET_LIB(err) != ERR_LIB_SSL) - return NULL; - - switch (ERR_GET_REASON(err)) { - case SSL_R_WRONG_VERSION_NUMBER: - return "The server does not support (a suitable version of) TLS"; - case SSL_R_UNKNOWN_PROTOCOL: - return "The server does not support HTTPS"; - case SSL_R_CERTIFICATE_VERIFY_FAILED: - return "Cannot authenticate server via its TLS certificate, likely due to mismatch with our trusted TLS certs or missing revocation status"; - case SSL_AD_REASON_OFFSET + TLS1_AD_UNKNOWN_CA: - return "Server did not accept our TLS certificate, likely due to mismatch with server's trust anchor or missing revocation status"; - case SSL_AD_REASON_OFFSET + SSL3_AD_HANDSHAKE_FAILURE: - return "TLS handshake failure. Possibly the server requires our TLS certificate but did not receive it"; - default: /* no error or no hint available for error */ - return NULL; - } -} - -/* HTTP callback function that supports TLS connection also via HTTPS proxy */ -BIO *app_http_tls_cb(BIO *hbio, void *arg, int connect, int detail) -{ - APP_HTTP_TLS_INFO *info = (APP_HTTP_TLS_INFO *)arg; - SSL_CTX *ssl_ctx = info->ssl_ctx; - SSL *ssl; - BIO *sbio = NULL; - - if (connect && detail) { /* connecting with TLS */ - if ((info->use_proxy - && !OSSL_HTTP_proxy_connect(hbio, info->server, info->port, - NULL, NULL, /* no proxy credentials */ - info->timeout, bio_err, opt_getprog())) - || (sbio = BIO_new(BIO_f_ssl())) == NULL) { - return NULL; - } - if (ssl_ctx == NULL || (ssl = SSL_new(ssl_ctx)) == NULL) { - BIO_free(sbio); - return NULL; - } - - SSL_set_tlsext_host_name(ssl, info->server); - - SSL_set_connect_state(ssl); - BIO_set_ssl(sbio, ssl, BIO_CLOSE); - - hbio = BIO_push(sbio, hbio); - } else if (!connect && !detail) { /* disconnecting after error */ - const char *hint = tls_error_hint(); - if (hint != NULL) - ERR_add_error_data(2, " : ", hint); - /* - * If we pop sbio and BIO_free() it this may lead to libssl double free. - * Rely on BIO_free_all() done by OSSL_HTTP_transfer() in http_client.c - */ - } - return hbio; -} - -ASN1_VALUE *app_http_get_asn1(const char *url, const char *proxy, - const char *no_proxy, SSL_CTX *ssl_ctx, - const STACK_OF(CONF_VALUE) *headers, - long timeout, const char *expected_content_type, - const ASN1_ITEM *it) -{ - APP_HTTP_TLS_INFO info; - char *server; - char *port; - int use_ssl; - ASN1_VALUE *resp = NULL; - - if (url == NULL || it == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - - if (!OSSL_HTTP_parse_url(url, &server, &port, NULL /* ppath */, &use_ssl)) - return NULL; - if (use_ssl && ssl_ctx == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - ERR_add_error_data(1, "missing SSL_CTX"); - goto end; - } - - info.server = server; - info.port = port; - info.use_proxy = proxy != NULL; - info.timeout = timeout; - info.ssl_ctx = ssl_ctx; - resp = OSSL_HTTP_get_asn1(url, proxy, no_proxy, - NULL, NULL, app_http_tls_cb, &info, - headers, 0 /* maxline */, 0 /* max_resp_len */, - timeout, expected_content_type, it); - end: - OPENSSL_free(server); - OPENSSL_free(port); - return resp; - -} - -ASN1_VALUE *app_http_post_asn1(const char *host, const char *port, - const char *path, const char *proxy, - const char *no_proxy, SSL_CTX *ssl_ctx, - const STACK_OF(CONF_VALUE) *headers, - const char *content_type, - ASN1_VALUE *req, const ASN1_ITEM *req_it, - long timeout, const ASN1_ITEM *rsp_it) -{ - APP_HTTP_TLS_INFO info; - - info.server = host; - info.port = port; - info.use_proxy = proxy != NULL; - info.timeout = timeout; - info.ssl_ctx = ssl_ctx; - return OSSL_HTTP_post_asn1(host, port, path, ssl_ctx != NULL, - proxy, no_proxy, - NULL, NULL, app_http_tls_cb, &info, - headers, content_type, req, req_it, - 0 /* maxline */, - 0 /* max_resp_len */, timeout, NULL, rsp_it); -} - -#endif - /* * Platform-specific sections */ @@ -2230,70 +2104,23 @@ double app_tminterval(int stop, int usertime) return ret; } -#elif defined(OPENSSL_SYSTEM_VMS) -# include -# include - -double app_tminterval(int stop, int usertime) -{ - static clock_t tmstart; - double ret = 0; - clock_t now; -# ifdef __TMS - struct tms rus; - - now = times(&rus); - if (usertime) - now = rus.tms_utime; -# else - if (usertime) - now = clock(); /* sum of user and kernel times */ - else { - struct timeval tv; - gettimeofday(&tv, NULL); - now = (clock_t)((unsigned long long)tv.tv_sec * CLK_TCK + - (unsigned long long)tv.tv_usec * (1000000 / CLK_TCK) - ); - } -# endif - if (stop == TM_START) - tmstart = now; - else - ret = (now - tmstart) / (double)(CLK_TCK); - - return ret; -} - #elif defined(_SC_CLK_TCK) /* by means of unistd.h */ # include double app_tminterval(int stop, int usertime) { double ret = 0; - clock_t now; - static clock_t tmstart; - long int tck = sysconf(_SC_CLK_TCK); -# ifdef __TMS struct tms rus; + clock_t now = times(&rus); + static clock_t tmstart; - now = times(&rus); if (usertime) now = rus.tms_utime; -# else - if (usertime) - now = clock(); /* sum of user and kernel times */ - else { - struct timeval tv; - gettimeofday(&tv, NULL); - now = (clock_t)((unsigned long long)tv.tv_sec * tck + - (unsigned long long)tv.tv_usec * (1000000 / tck) - ); - } -# endif if (stop == TM_START) { tmstart = now; } else { + long int tck = sysconf(_SC_CLK_TCK); ret = (now - tmstart) / (double)tck; } diff --git a/apps/lib/http_server.c b/apps/lib/http_server.c index 2b5c9f5d..11f0b1fc 100644 --- a/apps/lib/http_server.c +++ b/apps/lib/http_server.c @@ -255,17 +255,19 @@ static int urldecode(char *p) } int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, - BIO **pcbio, BIO *acbio, + char **ppath, BIO **pcbio, BIO *acbio, const char *prog, int accept_get, int timeout) { BIO *cbio = NULL, *getbio = NULL, *b64 = NULL; int len; char reqbuf[2048], inbuf[2048]; - char *url, *end; + char *meth, *url, *end; ASN1_VALUE *req; int ret = 1; *preq = NULL; + if (ppath != NULL) + *ppath = NULL; *pcbio = NULL; /* Connection loss before accept() is routine, ignore silently */ @@ -275,6 +277,7 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, cbio = BIO_pop(acbio); *pcbio = cbio; if (cbio == NULL) { + /* Cannot call http_server_send_status(cbio, ...) */ ret = -1; goto out; } @@ -288,16 +291,26 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, /* Read the request line. */ len = BIO_gets(cbio, reqbuf, sizeof(reqbuf)); - if (len <= 0) + if (len <= 0) { + log_message(prog, LOG_INFO, + "Request line read error or empty request"); + (void)http_server_send_status(cbio, 400, "Bad Request"); goto out; + } - if (accept_get && strncmp(reqbuf, "GET ", 4) == 0) { - /* Expecting GET {sp} /URL {sp} HTTP/1.x */ - for (url = reqbuf + 4; *url == ' '; ++url) - continue; + meth = reqbuf; + url = meth + 3; + if ((accept_get && strncmp(meth, "GET ", 4) == 0) + || (url++, strncmp(meth, "POST ", 5) == 0)) { + /* Expecting (GET|POST) {sp} /URL {sp} HTTP/1.x */ + *(url++) = '\0'; + while (*url == ' ') + url++; if (*url != '/') { log_message(prog, LOG_INFO, - "Invalid GET -- URL does not begin with '/': %s", url); + "Invalid %s -- URL does not begin with '/': %s", + meth, url); + (void)http_server_send_status(cbio, 400, "Bad Request"); goto out; } url++; @@ -308,7 +321,9 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, break; if (strncmp(end, " HTTP/1.", 7) != 0) { log_message(prog, LOG_INFO, - "Invalid GET -- bad HTTP/version string: %s", end + 1); + "Invalid %s -- bad HTTP/version string: %s", + meth, end + 1); + (void)http_server_send_status(cbio, 400, "Bad Request"); goto out; } *end = '\0'; @@ -318,39 +333,52 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, * 'url' was incremented above to point to the first byte *after* * the leading slash, so in case 'GET / ' it is now an empty string. */ - if (url[0] == '\0') + if (strlen(meth) == 3 && url[0] == '\0') { + (void)http_server_send_status(cbio, 200, "OK"); goto out; + } len = urldecode(url); - if (len <= 0) { + if (len < 0) { log_message(prog, LOG_INFO, - "Invalid GET request -- bad URL encoding: %s", url); + "Invalid %s request -- bad URL encoding: %s", + meth, url); + (void)http_server_send_status(cbio, 400, "Bad Request"); goto out; } - if ((getbio = BIO_new_mem_buf(url, len)) == NULL - || (b64 = BIO_new(BIO_f_base64())) == NULL) { - log_message(prog, LOG_ERR, - "Could not allocate base64 bio with size = %d", len); - BIO_free_all(cbio); - *pcbio = NULL; - ret = -1; - goto out; + if (strlen(meth) == 3) { /* GET */ + if ((getbio = BIO_new_mem_buf(url, len)) == NULL + || (b64 = BIO_new(BIO_f_base64())) == NULL) { + log_message(prog, LOG_ERR, + "Could not allocate base64 bio with size = %d", + len); + goto fatal; + } + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + getbio = BIO_push(b64, getbio); } - BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); - getbio = BIO_push(b64, getbio); - } else if (strncmp(reqbuf, "POST ", 5) != 0) { + } else { log_message(prog, LOG_INFO, "HTTP request does not start with GET/POST: %s", reqbuf); /* TODO provide better diagnosis in case client tries TLS */ + (void)http_server_send_status(cbio, 400, "Bad Request"); goto out; } + /* chop any further/duplicate leading or trailing '/' */ + while (*url == '/') + url++; + while (end >= url + 2 && end[-2] == '/' && end[-1] == '/') + end--; + *end = '\0'; + /* Read and skip past the headers. */ for (;;) { len = BIO_gets(cbio, inbuf, sizeof(inbuf)); if (len <= 0) { log_message(prog, LOG_ERR, "Error skipping remaining HTTP headers"); + (void)http_server_send_status(cbio, 400, "Bad Request"); goto out; } if ((inbuf[0] == '\r') || (inbuf[0] == '\n')) @@ -365,8 +393,14 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, /* Try to read and parse request */ req = ASN1_item_d2i_bio(it, getbio != NULL ? getbio : cbio, NULL); - if (req == NULL) + if (req == NULL) { log_message(prog, LOG_ERR, "Error parsing request"); + } else if (ppath != NULL && (*ppath = OPENSSL_strdup(url)) == NULL) { + log_message(prog, LOG_ERR, + "Out of memory allocating %d bytes", strlen(url) + 1); + ASN1_item_free(req, it); + goto fatal; + } *preq = req; @@ -378,6 +412,17 @@ int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq, acfd = (int)INVALID_SOCKET; # endif return ret; + + fatal: + (void)http_server_send_status(cbio, 500, "Internal Server Error"); + if (ppath != NULL) { + OPENSSL_free(*ppath); + *ppath = NULL; + } + BIO_free_all(cbio); + *pcbio = NULL; + ret = -1; + goto out; } /* assumes that cbio does not do an encoding that changes the output length */ @@ -392,4 +437,12 @@ int http_server_send_asn1_resp(BIO *cbio, const char *content_type, (void)BIO_flush(cbio); return ret; } + +int http_server_send_status(BIO *cbio, int status, const char *reason) +{ + int ret = BIO_printf(cbio, "HTTP/1.0 %d %s\r\n\r\n", status, reason) > 0; + + (void)BIO_flush(cbio); + return ret; +} #endif diff --git a/apps/lib/opt.c b/apps/lib/opt.c index 566de8ab..d6bfecc8 100644 --- a/apps/lib/opt.c +++ b/apps/lib/opt.c @@ -209,6 +209,7 @@ int opt_format(const char *s, unsigned long flags, int *result) { switch (*s) { default: + opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s); return 0; case 'D': case 'd': @@ -275,6 +276,7 @@ int opt_format(const char *s, unsigned long flags, int *result) return opt_format_error(s, flags); *result = FORMAT_PKCS12; } else { + opt_printf_stderr("%s: Bad format \"%s\"\n", prog, s); return 0; } break; @@ -740,40 +742,29 @@ int opt_next(void) break; case 'p': case 'n': - if (!opt_int(arg, &ival) - || (o->valtype == 'p' && ival <= 0)) { + if (!opt_int(arg, &ival)) + return -1; + if (o->valtype == 'p' && ival <= 0) { opt_printf_stderr("%s: Non-positive number \"%s\" for -%s\n", prog, arg, o->name); return -1; } break; case 'M': - if (!opt_imax(arg, &imval)) { - opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n", - prog, arg, o->name); + if (!opt_imax(arg, &imval)) return -1; - } break; case 'U': - if (!opt_umax(arg, &umval)) { - opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n", - prog, arg, o->name); + if (!opt_umax(arg, &umval)) return -1; - } break; case 'l': - if (!opt_long(arg, &lval)) { - opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n", - prog, arg, o->name); + if (!opt_long(arg, &lval)) return -1; - } break; case 'u': - if (!opt_ulong(arg, &ulval)) { - opt_printf_stderr("%s: Invalid number \"%s\" for -%s\n", - prog, arg, o->name); + if (!opt_ulong(arg, &ulval)) return -1; - } break; case 'c': case 'E': diff --git a/apps/lib/s_cb.c b/apps/lib/s_cb.c index 34bc4a99..d021c868 100644 --- a/apps/lib/s_cb.c +++ b/apps/lib/s_cb.c @@ -787,7 +787,7 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie, BIO_printf(bio_err, "HMAC not found\n"); goto end; } - ctx = EVP_MAC_CTX_new(hmac); + ctx = EVP_MAC_new_ctx(hmac); if (ctx == NULL) { BIO_printf(bio_err, "HMAC context allocation failed\n"); goto end; @@ -796,7 +796,7 @@ int generate_cookie_callback(SSL *ssl, unsigned char *cookie, *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, cookie_secret, COOKIE_SECRET_LENGTH); *p = OSSL_PARAM_construct_end(); - if (!EVP_MAC_CTX_set_params(ctx, params)) { + if (!EVP_MAC_set_ctx_params(ctx, params)) { BIO_printf(bio_err, "HMAC context parameter setting failed\n"); goto end; } diff --git a/apps/mac.c b/apps/mac.c index 30f0daab..e84321b8 100644 --- a/apps/mac.c +++ b/apps/mac.c @@ -114,7 +114,7 @@ opthelp: goto opthelp; } - ctx = EVP_MAC_CTX_new(mac); + ctx = EVP_MAC_new_ctx(mac); if (ctx == NULL) goto err; @@ -126,7 +126,7 @@ opthelp: if (params == NULL) goto err; - if (!EVP_MAC_CTX_set_params(ctx, params)) { + if (!EVP_MAC_set_ctx_params(ctx, params)) { BIO_printf(bio_err, "MAC parameter error\n"); ERR_print_errors(bio_err); ok = 0; @@ -199,7 +199,7 @@ err: sk_OPENSSL_STRING_free(opts); BIO_free(in); BIO_free(out); - EVP_MAC_CTX_free(ctx); + EVP_MAC_free_ctx(ctx); EVP_MAC_free(mac); return ret; } diff --git a/apps/ocsp.c b/apps/ocsp.c index fd03611f..95f63e2e 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -83,6 +83,13 @@ static char *prog; static int index_changed(CA_DB *); #endif +#ifndef OPENSSL_NO_SOCK +static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, + const char *path, + const STACK_OF(CONF_VALUE) *headers, + OCSP_REQUEST *req, int req_timeout); +#endif + typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, OPT_OUTFILE, OPT_TIMEOUT, OPT_URL, OPT_HOST, OPT_PORT, @@ -234,7 +241,7 @@ int ocsp_main(int argc, char **argv) int noCAfile = 0, noCApath = 0, noCAstore = 0; int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1; int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1; - int req_text = 0, resp_text = 0, ret = 1; + int req_text = 0, resp_text = 0, res, ret = 1; int req_timeout = -1; long nsec = MAX_VALIDITY_PERIOD, maxage = -1; unsigned long sign_flags = 0, verify_flags = 0, rflags = 0; @@ -274,8 +281,7 @@ int ocsp_main(int argc, char **argv) OPENSSL_free(tport); OPENSSL_free(tpath); thost = tport = tpath = NULL; - if (!OSSL_HTTP_parse_url(opt_arg(), - &host, &port, &path, &use_ssl)) { + if (!OCSP_parse_url(opt_arg(), &host, &port, &path, &use_ssl)) { BIO_printf(bio_err, "%s Error parsing URL\n", prog); goto end; } @@ -629,13 +635,17 @@ redo_accept: #endif req = NULL; - if (!do_responder(&req, &cbio, acbio, req_timeout)) + res = do_responder(&req, &cbio, acbio, req_timeout); + if (res == 0) goto redo_accept; if (req == NULL) { - resp = OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, - NULL); - send_ocsp_response(cbio, resp); + if (res == 1) { + resp = + OCSP_response_create(OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, + NULL); + send_ocsp_response(cbio, resp); + } goto done_resp; } } @@ -1151,7 +1161,7 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio, { #ifndef OPENSSL_NO_SOCK return http_server_get_asn1_req(ASN1_ITEM_rptr(OCSP_RESPONSE), - (ASN1_VALUE **)preq, pcbio, acbio, + (ASN1_VALUE **)preq, NULL, pcbio, acbio, prog, 1 /* accept_get */, timeout); #else BIO_printf(bio_err, @@ -1175,34 +1185,133 @@ static int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp) } #ifndef OPENSSL_NO_SOCK +static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, + const char *path, + const STACK_OF(CONF_VALUE) *headers, + OCSP_REQUEST *req, int req_timeout) +{ + int fd; + int rv; + int i; + int add_host = 1; + OCSP_REQ_CTX *ctx = NULL; + OCSP_RESPONSE *rsp = NULL; + fd_set confds; + struct timeval tv; + + if (req_timeout != -1) + BIO_set_nbio(cbio, 1); + + rv = BIO_do_connect(cbio); + + if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) { + BIO_puts(bio_err, "Error connecting BIO\n"); + return NULL; + } + + if (BIO_get_fd(cbio, &fd) < 0) { + BIO_puts(bio_err, "Can't get connection fd\n"); + goto err; + } + + if (req_timeout != -1 && rv <= 0) { + FD_ZERO(&confds); + openssl_fdset(fd, &confds); + tv.tv_usec = 0; + tv.tv_sec = req_timeout; + rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); + if (rv == 0) { + BIO_puts(bio_err, "Timeout on connect\n"); + return NULL; + } + } + + ctx = OCSP_sendreq_new(cbio, path, NULL, -1); + if (ctx == NULL) + return NULL; + + for (i = 0; i < sk_CONF_VALUE_num(headers); i++) { + CONF_VALUE *hdr = sk_CONF_VALUE_value(headers, i); + if (add_host == 1 && strcasecmp("host", hdr->name) == 0) + add_host = 0; + if (!OCSP_REQ_CTX_add1_header(ctx, hdr->name, hdr->value)) + goto err; + } + + if (add_host == 1 && OCSP_REQ_CTX_add1_header(ctx, "Host", host) == 0) + goto err; + + if (!OCSP_REQ_CTX_set1_req(ctx, req)) + goto err; + + for (;;) { + rv = OCSP_sendreq_nbio(&rsp, ctx); + if (rv != -1) + break; + if (req_timeout == -1) + continue; + FD_ZERO(&confds); + openssl_fdset(fd, &confds); + tv.tv_usec = 0; + tv.tv_sec = req_timeout; + if (BIO_should_read(cbio)) { + rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv); + } else if (BIO_should_write(cbio)) { + rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); + } else { + BIO_puts(bio_err, "Unexpected retry condition\n"); + goto err; + } + if (rv == 0) { + BIO_puts(bio_err, "Timeout on request\n"); + break; + } + if (rv == -1) { + BIO_puts(bio_err, "Select error\n"); + break; + } + + } + err: + OCSP_REQ_CTX_free(ctx); + + return rsp; +} + OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, const char *host, const char *path, const char *port, int use_ssl, STACK_OF(CONF_VALUE) *headers, int req_timeout) { + BIO *cbio = NULL; SSL_CTX *ctx = NULL; OCSP_RESPONSE *resp = NULL; + cbio = BIO_new_connect(host); + if (cbio == NULL) { + BIO_printf(bio_err, "Error creating connect BIO\n"); + goto end; + } + if (port != NULL) + BIO_set_conn_port(cbio, port); if (use_ssl == 1) { + BIO *sbio; ctx = SSL_CTX_new(TLS_client_method()); if (ctx == NULL) { BIO_printf(bio_err, "Error creating SSL context.\n"); goto end; } SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); + sbio = BIO_new_ssl(ctx, 1); + cbio = BIO_push(sbio, cbio); } - resp = (OCSP_RESPONSE *) - app_http_post_asn1(host, port, path, NULL, NULL /* no proxy used */, - ctx, headers, "application/ocsp-request", - (ASN1_VALUE *)req, ASN1_ITEM_rptr(OCSP_REQUEST), - req_timeout, ASN1_ITEM_rptr(OCSP_RESPONSE)); - + resp = query_responder(cbio, host, path, headers, req, req_timeout); if (resp == NULL) BIO_printf(bio_err, "Error querying OCSP responder\n"); - end: + BIO_free_all(cbio); SSL_CTX_free(ctx); return resp; } diff --git a/apps/openssl-vms.cnf b/apps/openssl-vms.cnf index c7e7abe9..2420e9c9 100644 --- a/apps/openssl-vms.cnf +++ b/apps/openssl-vms.cnf @@ -171,27 +171,9 @@ unstructuredName = An optional company name basicConstraints=CA:FALSE -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer @@ -206,13 +188,6 @@ authorityKeyIdentifier=keyid,issuer # Copy subject details # issuerAltName=issuer:copy -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - # This is required for TSA certificates. # extendedKeyUsage = critical,timeStamping @@ -242,9 +217,6 @@ basicConstraints = critical,CA:true # left out by default. # keyUsage = cRLSign, keyCertSign -# Some might want this also -# nsCertType = sslCA, emailCA - # Include email address in subject alt name: another PKIX recommendation # subjectAltName=email:copy # Copy issuer details @@ -272,27 +244,9 @@ authorityKeyIdentifier=keyid:always basicConstraints=CA:FALSE -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer @@ -307,13 +261,6 @@ authorityKeyIdentifier=keyid,issuer # Copy subject details # issuerAltName=issuer:copy -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - # This really needs to be in place for it to be a proxy certificate. proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo diff --git a/apps/openssl.c b/apps/openssl.c index 0a3c76e7..7b0ccbcc 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -30,9 +30,6 @@ #include "apps.h" #include "progs.h" -/* Special sentinel to exit the program. */ -#define EXIT_THE_PROGRAM (-1) - /* * The LHASH callbacks ("hash" & "cmp") have been replaced by functions with * the base prototypes (we cast each variable inside the function to the @@ -80,27 +77,6 @@ static void apps_shutdown(void) destroy_ui_method(); } -static char *make_config_name(void) -{ - const char *t; - size_t len; - char *p; - - if ((t = getenv("OPENSSL_CONF")) != NULL) - return OPENSSL_strdup(t); - - t = X509_get_default_cert_area(); - len = strlen(t) + 1 + strlen(OPENSSL_CONF) + 1; - p = app_malloc(len, "config filename buffer"); - strcpy(p, t); -#ifndef OPENSSL_SYS_VMS - strcat(p, "/"); -#endif - strcat(p, OPENSSL_CONF); - - return p; -} - #ifndef OPENSSL_NO_TRACE typedef struct tracedata_st { @@ -233,17 +209,14 @@ int main(int argc, char *argv[]) { FUNCTION f, *fp; LHASH_OF(FUNCTION) *prog = NULL; - char *p, *pname; - char buf[1024]; - const char *prompt; + char *pname; ARGS arg; - int first, n, i, ret = 0; + int ret = 0; arg.argv = NULL; arg.size = 0; /* Set up some of the environment. */ - default_config_file = make_config_name(); bio_in = dup_bio_in(FORMAT_TEXT); bio_out = dup_bio_out(FORMAT_TEXT); bio_err = dup_bio_err(FORMAT_TEXT); @@ -261,11 +234,6 @@ int main(int argc, char *argv[]) setup_trace(getenv("OPENSSL_TRACE")); #endif - if (getenv("OPENSSL_FIPS")) { - BIO_printf(bio_err, "FIPS mode not supported.\n"); - return 1; - } - if (!apps_startup()) { BIO_printf(bio_err, "FATAL: Startup failure (dev note: apps_startup() failed)\n"); @@ -284,92 +252,24 @@ int main(int argc, char *argv[]) } pname = opt_progname(argv[0]); + default_config_file = CONF_get1_default_config_file(); + if (default_config_file == NULL) + app_bail_out("%s: could not get default config file\n", pname); + /* first check the program name */ f.name = pname; fp = lh_FUNCTION_retrieve(prog, &f); - if (fp != NULL) { - argv[0] = pname; - if (fp->deprecated_alternative != NULL) - warn_deprecated(fp); - ret = fp->func(argc, argv); - goto end; - } - - /* If there is stuff on the command line, run with that. */ - if (argc != 1) { + if (fp == NULL) { + /* We assume we've been called as 'openssl cmd' */ argc--; argv++; - ret = do_cmd(prog, argc, argv); - if (ret < 0) - ret = 0; - goto end; } - /* ok, lets enter interactive mode */ - for (;;) { - ret = 0; - /* Read a line, continue reading if line ends with \ */ - for (p = buf, n = sizeof(buf), i = 0, first = 1; n > 0; first = 0) { - prompt = first ? "OpenSSL> " : "> "; - p[0] = '\0'; -#ifndef READLINE - fputs(prompt, stdout); - fflush(stdout); - if (!fgets(p, n, stdin)) - goto end; - if (p[0] == '\0') - goto end; - i = strlen(p); - if (i <= 1) - break; - if (p[i - 2] != '\\') - break; - i -= 2; - p += i; - n -= i; -#else - { - extern char *readline(const char *); - extern void add_history(const char *cp); - char *text; + /* If there's a command, run with that, otherwise "help". */ + ret = argc > 0 + ? do_cmd(prog, argc, argv) + : help_main(argc, argv); - text = readline(prompt); - if (text == NULL) - goto end; - i = strlen(text); - if (i == 0 || i > n) - break; - if (text[i - 1] != '\\') { - p += strlen(strcpy(p, text)); - free(text); - add_history(buf); - break; - } - - text[i - 1] = '\0'; - p += strlen(strcpy(p, text)); - free(text); - n -= i; - } -#endif - } - - if (!chopup_args(&arg, buf)) { - BIO_printf(bio_err, "Can't parse (no memory?)\n"); - break; - } - - ret = do_cmd(prog, arg.argc, arg.argv); - if (ret == EXIT_THE_PROGRAM) { - ret = 0; - goto end; - } - if (ret != 0) - BIO_printf(bio_err, "error in %s\n", arg.argv[0]); - (void)BIO_flush(bio_out); - (void)BIO_flush(bio_err); - } - ret = 1; end: app_providers_cleanup(); OPENSSL_free(default_config_file); @@ -502,10 +402,6 @@ static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]) BIO_printf(bio_out, "%s\n", argv[0] + 3); return 1; } - if (strcmp(argv[0], "quit") == 0 || strcmp(argv[0], "q") == 0 || - strcmp(argv[0], "exit") == 0 || strcmp(argv[0], "bye") == 0) - /* Special value to mean "exit the program. */ - return EXIT_THE_PROGRAM; BIO_printf(bio_err, "Invalid command '%s'; type \"help\" for a list.\n", argv[0]); diff --git a/apps/openssl.cnf b/apps/openssl.cnf index 52706ae1..4fd5286d 100644 --- a/apps/openssl.cnf +++ b/apps/openssl.cnf @@ -171,27 +171,9 @@ unstructuredName = An optional company name basicConstraints=CA:FALSE -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer @@ -206,13 +188,6 @@ authorityKeyIdentifier=keyid,issuer # Copy subject details # issuerAltName=issuer:copy -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - # This is required for TSA certificates. # extendedKeyUsage = critical,timeStamping @@ -242,9 +217,6 @@ basicConstraints = critical,CA:true # left out by default. # keyUsage = cRLSign, keyCertSign -# Some might want this also -# nsCertType = sslCA, emailCA - # Include email address in subject alt name: another PKIX recommendation # subjectAltName=email:copy # Copy issuer details @@ -272,27 +244,9 @@ authorityKeyIdentifier=keyid:always basicConstraints=CA:FALSE -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer @@ -307,13 +261,6 @@ authorityKeyIdentifier=keyid,issuer # Copy subject details # issuerAltName=issuer:copy -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - # This really needs to be in place for it to be a proxy certificate. proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo diff --git a/apps/rsa.c b/apps/rsa.c index 9f91b72d..0464729f 100644 --- a/apps/rsa.c +++ b/apps/rsa.c @@ -65,9 +65,9 @@ const OPTIONS rsa_options[] = { {"pvk-strong", OPT_PVK_STRONG, '-', "Enable 'Strong' PVK encoding level (default)"}, {"pvk-weak", OPT_PVK_WEAK, '-', "Enable 'Weak' PVK encoding level"}, {"pvk-none", OPT_PVK_NONE, '-', "Don't enforce PVK encoding"}, +#endif OPT_PROV_OPTIONS, -#endif {NULL} }; diff --git a/apps/s_client.c b/apps/s_client.c index 8bab4e28..ac5e49d1 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -81,6 +81,7 @@ static void print_stuff(BIO *berr, SSL *con, int full); static int ocsp_resp_cb(SSL *s, void *arg); #endif static int ldap_ExtendedResponse_parse(const char *buf, long rem); +static char *base64encode (const void *buf, size_t len); static int is_dNS_name(const char *host); static int saved_errno; @@ -576,7 +577,7 @@ typedef enum OPTION_choice { OPT_READ_BUF, OPT_KEYLOG_FILE, OPT_EARLY_DATA, OPT_REQCAFILE, OPT_V_ENUM, OPT_X_ENUM, - OPT_S_ENUM, + OPT_S_ENUM, OPT_IGNORE_UNEXPECTED_EOF, OPT_FALLBACKSCSV, OPT_NOCMDS, OPT_PROXY, OPT_PROXY_USER, OPT_PROXY_PASS, OPT_DANE_TLSA_DOMAIN, #ifndef OPENSSL_NO_CT @@ -718,6 +719,8 @@ const OPTIONS s_client_options[] = { "Do not send the server name (SNI) extension in the ClientHello"}, {"tlsextdebug", OPT_TLSEXTDEBUG, '-', "Hex dump of all TLS extensions received"}, + {"ignore_unexpected_eof", OPT_IGNORE_UNEXPECTED_EOF, '-', + "Do not treat lack of close_notify from a peer as an error"}, #ifndef OPENSSL_NO_OCSP {"status", OPT_STATUS, '-', "Request certificate status from server"}, #endif @@ -919,6 +922,7 @@ int s_client_main(int argc, char **argv) char *connectstr = NULL, *bindstr = NULL; char *cert_file = NULL, *key_file = NULL, *chain_file = NULL; char *chCApath = NULL, *chCAfile = NULL, *chCAstore = NULL, *host = NULL; + char *thost = NULL, *tport = NULL; char *port = OPENSSL_strdup(PORT); char *bindhost = NULL, *bindport = NULL; char *passarg = NULL, *pass = NULL; @@ -934,7 +938,7 @@ int s_client_main(int argc, char **argv) int prexit = 0; int sdebug = 0; int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0; - int ret = 1, in_init = 1, i, nbio_test = 0, sock = -1, k, width, state = 0; + int ret = 1, in_init = 1, i, nbio_test = 0, s = -1, k, width, state = 0; int sbuf_len, sbuf_off, cmdletters = 1; int socket_family = AF_UNSPEC, socket_type = SOCK_STREAM, protocol = 0; int starttls_proto = PROTO_OFF, crl_format = FORMAT_PEM, crl_download = 0; @@ -1001,6 +1005,7 @@ int s_client_main(int argc, char **argv) #ifndef OPENSSL_NO_SCTP int sctp_label_bug = 0; #endif + int ignore_unexpected_eof = 0; FD_ZERO(&readfds); FD_ZERO(&writefds); @@ -1180,6 +1185,9 @@ int s_client_main(int argc, char **argv) if (!args_excert(o, &exc)) goto end; break; + case OPT_IGNORE_UNEXPECTED_EOF: + ignore_unexpected_eof = 1; + break; case OPT_PREXIT: prexit = 1; break; @@ -1593,29 +1601,12 @@ int s_client_main(int argc, char **argv) goto opthelp; } #endif - if (proxystr != NULL) { + + if (connectstr != NULL) { int res; char *tmp_host = host, *tmp_port = port; - if (connectstr == NULL) { - BIO_printf(bio_err, "%s: -proxy requires use of -connect or target parameter\n", prog); - goto opthelp; - } - res = BIO_parse_hostserv(proxystr, &host, &port, BIO_PARSE_PRIO_HOST); - if (tmp_host != host) - OPENSSL_free(tmp_host); - if (tmp_port != port) - OPENSSL_free(tmp_port); - if (!res) { - BIO_printf(bio_err, - "%s: -proxy argument malformed or ambiguous\n", prog); - goto end; - } - } else { - int res = 1; - char *tmp_host = host, *tmp_port = port; - if (connectstr != NULL) - res = BIO_parse_hostserv(connectstr, &host, &port, - BIO_PARSE_PRIO_HOST); + + res = BIO_parse_hostserv(connectstr, &host, &port, BIO_PARSE_PRIO_HOST); if (tmp_host != host) OPENSSL_free(tmp_host); if (tmp_port != port) @@ -1628,6 +1619,35 @@ int s_client_main(int argc, char **argv) } } + if (proxystr != NULL) { + int res; + char *tmp_host = host, *tmp_port = port; + + if (host == NULL || port == NULL) { + BIO_printf(bio_err, "%s: -proxy requires use of -connect or target parameter\n", prog); + goto opthelp; + } + + /* Retain the original target host:port for use in the HTTP proxy connect string */ + thost = OPENSSL_strdup(host); + tport = OPENSSL_strdup(port); + if (thost == NULL || tport == NULL) { + BIO_printf(bio_err, "%s: out of memory\n", prog); + goto end; + } + + res = BIO_parse_hostserv(proxystr, &host, &port, BIO_PARSE_PRIO_HOST); + if (tmp_host != host) + OPENSSL_free(tmp_host); + if (tmp_port != port) + OPENSSL_free(tmp_port); + if (!res) { + BIO_printf(bio_err, + "%s: -proxy argument malformed or ambiguous\n", prog); + goto end; + } + } + if (bindstr != NULL) { int res; res = BIO_parse_hostserv(bindstr, &bindhost, &bindport, @@ -1776,6 +1796,9 @@ int s_client_main(int argc, char **argv) && SSL_CTX_set_max_proto_version(ctx, max_version) == 0) goto end; + if (ignore_unexpected_eof) + SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF); + if (vpmtouched && !SSL_CTX_set1_param(ctx, vpm)) { BIO_printf(bio_err, "Error setting verify params\n"); ERR_print_errors(bio_err); @@ -2077,16 +2100,16 @@ int s_client_main(int argc, char **argv) } re_start: - if (init_client(&sock, host, port, bindhost, bindport, socket_family, + if (init_client(&s, host, port, bindhost, bindport, socket_family, socket_type, protocol) == 0) { BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error()); - BIO_closesocket(sock); + BIO_closesocket(s); goto end; } - BIO_printf(bio_c_out, "CONNECTED(%08X)\n", sock); + BIO_printf(bio_c_out, "CONNECTED(%08X)\n", s); if (c_nbio) { - if (!BIO_socket_nbio(sock, 1)) { + if (!BIO_socket_nbio(s, 1)) { ERR_print_errors(bio_err); goto end; } @@ -2098,21 +2121,21 @@ int s_client_main(int argc, char **argv) #ifndef OPENSSL_NO_SCTP if (protocol == IPPROTO_SCTP) - sbio = BIO_new_dgram_sctp(sock, BIO_NOCLOSE); + sbio = BIO_new_dgram_sctp(s, BIO_NOCLOSE); else #endif - sbio = BIO_new_dgram(sock, BIO_NOCLOSE); + sbio = BIO_new_dgram(s, BIO_NOCLOSE); if ((peer_info.addr = BIO_ADDR_new()) == NULL) { BIO_printf(bio_err, "memory allocation failure\n"); - BIO_closesocket(sock); + BIO_closesocket(s); goto end; } - if (!BIO_sock_info(sock, BIO_SOCK_INFO_ADDRESS, &peer_info)) { + if (!BIO_sock_info(s, BIO_SOCK_INFO_ADDRESS, &peer_info)) { BIO_printf(bio_err, "getsockname:errno=%d\n", get_last_socket_error()); BIO_ADDR_free(peer_info.addr); - BIO_closesocket(sock); + BIO_closesocket(s); goto end; } @@ -2149,7 +2172,7 @@ int s_client_main(int argc, char **argv) } } else #endif /* OPENSSL_NO_DTLS */ - sbio = BIO_new_socket(sock, BIO_NOCLOSE); + sbio = BIO_new_socket(s, BIO_NOCLOSE); if (nbio_test) { BIO *test; @@ -2380,9 +2403,83 @@ int s_client_main(int argc, char **argv) } break; case PROTO_CONNECT: - if (!OSSL_HTTP_proxy_connect(sbio, host, port, proxyuser, proxypass, - 0 /* no timeout */, bio_err, prog)) - goto shut; + { + enum { + error_proto, /* Wrong protocol, not even HTTP */ + error_connect, /* CONNECT failed */ + success + } foundit = error_connect; + BIO *fbio = BIO_new(BIO_f_buffer()); + + BIO_push(fbio, sbio); + BIO_printf(fbio, "CONNECT %s HTTP/1.0\r\n", connectstr); + /* + * Workaround for broken proxies which would otherwise close + * the connection when entering tunnel mode (eg Squid 2.6) + */ + BIO_printf(fbio, "Proxy-Connection: Keep-Alive\r\n"); + + /* Support for basic (base64) proxy authentication */ + if (proxyuser != NULL) { + size_t l; + char *proxyauth, *proxyauthenc; + + l = strlen(proxyuser); + if (proxypass != NULL) + l += strlen(proxypass); + proxyauth = app_malloc(l + 2, "Proxy auth string"); + BIO_snprintf(proxyauth, l + 2, "%s:%s", proxyuser, + (proxypass != NULL) ? proxypass : ""); + proxyauthenc = base64encode(proxyauth, strlen(proxyauth)); + BIO_printf(fbio, "Proxy-Authorization: Basic %s\r\n", + proxyauthenc); + OPENSSL_clear_free(proxyauth, strlen(proxyauth)); + OPENSSL_clear_free(proxyauthenc, strlen(proxyauthenc)); + } + + /* Terminate the HTTP CONNECT request */ + BIO_printf(fbio, "\r\n"); + (void)BIO_flush(fbio); + /* + * The first line is the HTTP response. According to RFC 7230, + * it's formatted exactly like this: + * + * HTTP/d.d ddd Reason text\r\n + */ + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + if (mbuf_len < (int)strlen("HTTP/1.0 200")) { + BIO_printf(bio_err, + "%s: HTTP CONNECT failed, insufficient response " + "from proxy (got %d octets)\n", prog, mbuf_len); + (void)BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + goto shut; + } + if (mbuf[8] != ' ') { + BIO_printf(bio_err, + "%s: HTTP CONNECT failed, incorrect response " + "from proxy\n", prog); + foundit = error_proto; + } else if (mbuf[9] != '2') { + BIO_printf(bio_err, "%s: HTTP CONNECT failed: %s ", prog, + &mbuf[9]); + } else { + foundit = success; + } + if (foundit != error_proto) { + /* Read past all following headers */ + do { + mbuf_len = BIO_gets(fbio, mbuf, BUFSIZZ); + } while (mbuf_len > 2); + } + (void)BIO_flush(fbio); + BIO_pop(fbio); + BIO_free(fbio); + if (foundit != success) { + goto shut; + } + } break; case PROTO_IRC: { @@ -3100,8 +3197,8 @@ int s_client_main(int argc, char **argv) timeout.tv_usec = 500000; /* some extreme round-trip */ do { FD_ZERO(&readfds); - openssl_fdset(sock, &readfds); - } while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0 + openssl_fdset(s, &readfds); + } while (select(s + 1, &readfds, NULL, NULL, &timeout) > 0 && BIO_read(sbio, sbuf, BUFSIZZ) > 0); BIO_closesocket(SSL_get_fd(con)); @@ -3129,6 +3226,8 @@ int s_client_main(int argc, char **argv) OPENSSL_free(bindstr); OPENSSL_free(host); OPENSSL_free(port); + OPENSSL_free(thost); + OPENSSL_free(tport); X509_VERIFY_PARAM_free(vpm); ssl_excert_free(exc); sk_OPENSSL_STRING_free(ssl_args); @@ -3151,6 +3250,7 @@ static void print_stuff(BIO *bio, SSL *s, int full) X509 *peer = NULL; STACK_OF(X509) *sk; const SSL_CIPHER *c; + EVP_PKEY *public_key; int i, istls13 = (SSL_version(s) == TLS1_3_VERSION); long verify_result; #ifndef OPENSSL_NO_COMP @@ -3176,6 +3276,19 @@ static void print_stuff(BIO *bio, SSL *s, int full) BIO_printf(bio, " i:"); X509_NAME_print_ex(bio, X509_get_issuer_name(sk_X509_value(sk, i)), 0, get_nameopt()); BIO_puts(bio, "\n"); + public_key = X509_get_pubkey(sk_X509_value(sk, i)); + if (public_key != NULL) { + BIO_printf(bio, " a:PKEY: %s, %d (bit); sigalg: %s\n", + OBJ_nid2sn(EVP_PKEY_base_id(public_key)), + EVP_PKEY_bits(public_key), + OBJ_nid2sn(X509_get_signature_nid(sk_X509_value(sk, i)))); + EVP_PKEY_free(public_key); + } + BIO_printf(bio, " v:NotBefore: "); + ASN1_TIME_print(bio, X509_get0_notBefore(sk_X509_value(sk, i))); + BIO_printf(bio, "; NotAfter: "); + ASN1_TIME_print(bio, X509_get0_notAfter(sk_X509_value(sk, i))); + BIO_puts(bio, "\n"); if (c_showcerts) PEM_write_bio_X509(bio, sk_X509_value(sk, i)); } @@ -3477,6 +3590,29 @@ static int ldap_ExtendedResponse_parse(const char *buf, long rem) return ret; } +/* + * BASE64 encoder: used only for encoding basic proxy authentication credentials + */ +static char *base64encode (const void *buf, size_t len) +{ + int i; + size_t outl; + char *out; + + /* Calculate size of encoded data */ + outl = (len / 3); + if (len % 3 > 0) + outl++; + outl <<= 2; + out = app_malloc(outl + 1, "base64 encode buffer"); + + i = EVP_EncodeBlock((unsigned char *)out, buf, len); + assert(i <= (int)outl); + if (i < 0) + *out = '\0'; + return out; +} + /* * Host dNS Name verifier: used for checking that the hostname is in dNS format * before setting it as SNI diff --git a/apps/s_server.c b/apps/s_server.c index 09bcc0cf..4a7d3ede 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -534,8 +534,8 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx, x = SSL_get_certificate(s); aia = X509_get1_ocsp(x); if (aia != NULL) { - if (!OSSL_HTTP_parse_url(sk_OPENSSL_STRING_value(aia, 0), - &host, &port, &path, &use_ssl)) { + if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0), + &host, &port, &path, &use_ssl)) { BIO_puts(bio_err, "cert_status: can't parse AIA URL\n"); goto err; } @@ -761,7 +761,7 @@ typedef enum OPTION_choice { OPT_SRTP_PROFILES, OPT_KEYMATEXPORT, OPT_KEYMATEXPORTLEN, OPT_KEYLOG_FILE, OPT_MAX_EARLY, OPT_RECV_MAX_EARLY, OPT_EARLY_DATA, OPT_S_NUM_TICKETS, OPT_ANTI_REPLAY, OPT_NO_ANTI_REPLAY, OPT_SCTP_LABEL_BUG, - OPT_HTTP_SERVER_BINMODE, OPT_NOCANAMES, + OPT_HTTP_SERVER_BINMODE, OPT_NOCANAMES, OPT_IGNORE_UNEXPECTED_EOF, OPT_R_ENUM, OPT_S_ENUM, OPT_V_ENUM, @@ -850,6 +850,8 @@ const OPTIONS s_server_options[] = { "Disable caching and tickets if ephemeral (EC)DH is used"}, {"www", OPT_WWW, '-', "Respond to a 'GET /' with a status page"}, {"WWW", OPT_UPPER_WWW, '-', "Respond to a 'GET with the file ./path"}, + {"ignore_unexpected_eof", OPT_IGNORE_UNEXPECTED_EOF, '-', + "Do not treat lack of close_notify from a peer as an error"}, {"tlsextdebug", OPT_TLSEXTDEBUG, '-', "Hex dump of all TLS extensions received"}, {"HTTP", OPT_HTTP, '-', "Like -WWW but ./path includes HTTP headers"}, @@ -1094,6 +1096,7 @@ int s_server_main(int argc, char *argv[]) #ifndef OPENSSL_NO_SCTP int sctp_label_bug = 0; #endif + int ignore_unexpected_eof = 0; /* Init of few remaining global variables */ local_argc = argc; @@ -1403,9 +1406,10 @@ int s_server_main(int argc, char *argv[]) case OPT_STATUS_URL: #ifndef OPENSSL_NO_OCSP s_tlsextstatus = 1; - if (!OSSL_HTTP_parse_url(opt_arg(), - &tlscstatp.host, &tlscstatp.port, - &tlscstatp.path, &tlscstatp.use_ssl)) { + if (!OCSP_parse_url(opt_arg(), + &tlscstatp.host, + &tlscstatp.port, + &tlscstatp.path, &tlscstatp.use_ssl)) { BIO_printf(bio_err, "Error parsing URL\n"); goto end; } @@ -1667,6 +1671,9 @@ int s_server_main(int argc, char *argv[]) use_sendfile = 1; #endif break; + case OPT_IGNORE_UNEXPECTED_EOF: + ignore_unexpected_eof = 1; + break; } } argc = opt_num_rest(); @@ -1867,7 +1874,6 @@ int s_server_main(int argc, char *argv[]) goto end; } } - #ifndef OPENSSL_NO_SCTP if (protocol == IPPROTO_SCTP && sctp_label_bug == 1) SSL_CTX_set_mode(ctx, SSL_MODE_DTLS_SCTP_LABEL_LENGTH_BUG); @@ -1911,6 +1917,9 @@ int s_server_main(int argc, char *argv[]) SSL_CTX_set_options(ctx, SSL_OP_DISABLE_TLSEXT_CA_NAMES); } + if (ignore_unexpected_eof) + SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF); + if (max_send_fragment > 0 && !SSL_CTX_set_max_send_fragment(ctx, max_send_fragment)) { BIO_printf(bio_err, "%s: Max send fragment size %u is out of permitted range\n", @@ -3617,7 +3626,7 @@ static int generate_session_id(SSL *ssl, unsigned char *id, { unsigned int count = 0; unsigned int session_id_prefix_len = strlen(session_id_prefix); - + do { if (RAND_bytes(id, *id_len) <= 0) return 0; diff --git a/apps/speed.c b/apps/speed.c index 664be2f5..6435bab4 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -16,6 +16,7 @@ #define ECDH_SECONDS 10 #define EdDSA_SECONDS 10 #define SM2_SECONDS 10 +#define FFDH_SECONDS 10 /* We need to use some deprecated APIs */ #define OPENSSL_SUPPRESS_DEPRECATED @@ -98,6 +99,9 @@ # include # include "./testrsa.h" #endif +#ifndef OPENSSL_NO_DH +# include +#endif #include #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) # include @@ -125,6 +129,7 @@ #define MAX_MISALIGNMENT 63 #define MAX_ECDH_SIZE 256 #define MISALIGN 64 +#define MAX_FFDH_SIZE 1024 typedef struct openssl_speed_sec_st { int sym; @@ -134,6 +139,7 @@ typedef struct openssl_speed_sec_st { int ecdh; int eddsa; int sm2; + int ffdh; } openssl_speed_sec_t; static volatile int run = 0; @@ -435,6 +441,22 @@ static const OPT_PAIR rsa_choices[RSA_NUM] = { static double rsa_results[RSA_NUM][2]; /* 2 ops: sign then verify */ #endif /* OPENSSL_NO_RSA */ +#ifndef OPENSSL_NO_DH +enum ff_params_t { + R_FFDH_2048, R_FFDH_3072, R_FFDH_4096, R_FFDH_6144, R_FFDH_8192, FFDH_NUM +}; + +static const OPT_PAIR ffdh_choices[FFDH_NUM] = { + {"ffdh2048", R_FFDH_2048}, + {"ffdh3072", R_FFDH_3072}, + {"ffdh4096", R_FFDH_4096}, + {"ffdh6144", R_FFDH_6144}, + {"ffdh8192", R_FFDH_8192}, +}; + +static double ffdh_results[FFDH_NUM][1]; /* 1 op: derivation */ +#endif /* OPENSSL_NO_DH */ + #ifndef OPENSSL_NO_EC enum ec_curves_t { R_EC_P160, R_EC_P192, R_EC_P224, R_EC_P256, R_EC_P384, R_EC_P521, @@ -553,6 +575,7 @@ typedef struct loopargs_st { EC_KEY *ecdsa[ECDSA_NUM]; EVP_PKEY_CTX *ecdh_ctx[EC_NUM]; EVP_MD_CTX *eddsa_ctx[EdDSA_NUM]; + EVP_MD_CTX *eddsa_ctx2[EdDSA_NUM]; # ifndef OPENSSL_NO_SM2 EVP_MD_CTX *sm2_ctx[SM2_NUM]; EVP_MD_CTX *sm2_vfy_ctx[SM2_NUM]; @@ -561,6 +584,11 @@ typedef struct loopargs_st { unsigned char *secret_a; unsigned char *secret_b; size_t outlen[EC_NUM]; +#endif +#ifndef OPENSSL_NO_DH + EVP_PKEY_CTX *ffdh_ctx[FFDH_NUM]; + unsigned char *secret_ff_a; + unsigned char *secret_ff_b; #endif EVP_CIPHER_CTX *ctx; #ifndef OPENSSL_NO_DEPRECATED_3_0 @@ -1067,6 +1095,24 @@ static int RSA_verify_loop(void *args) } #endif +#ifndef OPENSSL_NO_DH +static long ffdh_c[FFDH_NUM][1]; + +static int FFDH_derive_key_loop(void *args) +{ + loopargs_t *tempargs = *(loopargs_t **) args; + EVP_PKEY_CTX *ffdh_ctx = tempargs->ffdh_ctx[testnum]; + unsigned char *derived_secret = tempargs->secret_ff_a; + size_t outlen = MAX_FFDH_SIZE; + int count; + + for (count = 0; COND(ffdh_c[testnum][0]); count++) + EVP_PKEY_derive(ffdh_ctx, derived_secret, &outlen); + + return count; +} +#endif /* OPENSSL_NO_DH */ + #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) static long dsa_c[DSA_NUM][2]; static int DSA_sign_loop(void *args) @@ -1197,7 +1243,7 @@ static int EdDSA_verify_loop(void *args) { loopargs_t *tempargs = *(loopargs_t **) args; unsigned char *buf = tempargs->buf; - EVP_MD_CTX **edctx = tempargs->eddsa_ctx; + EVP_MD_CTX **edctx = tempargs->eddsa_ctx2; unsigned char *eddsasig = tempargs->buf2; size_t eddsasigsize = tempargs->sigsize; int ret, count; @@ -1463,7 +1509,8 @@ int speed_main(int argc, char **argv) #endif openssl_speed_sec_t seconds = { SECONDS, RSA_SECONDS, DSA_SECONDS, ECDSA_SECONDS, ECDH_SECONDS, - EdDSA_SECONDS, SM2_SECONDS }; + EdDSA_SECONDS, SM2_SECONDS, + FFDH_SECONDS }; /* What follows are the buffers and key material. */ #if !defined(OPENSSL_NO_RC5) && !defined(OPENSSL_NO_DEPRECATED_3_0) @@ -1521,6 +1568,23 @@ int speed_main(int argc, char **argv) uint8_t rsa_doit[RSA_NUM] = { 0 }; int primes = RSA_DEFAULT_PRIME_NUM; #endif +#ifndef OPENSSL_NO_DH + typedef struct ffdh_params_st { + const char *name; + unsigned int nid; + unsigned int bits; + } FFDH_PARAMS; + + static const FFDH_PARAMS ffdh_params[FFDH_NUM] = { + {"ffdh2048", NID_ffdhe2048, 2048}, + {"ffdh3072", NID_ffdhe3072, 3072}, + {"ffdh4096", NID_ffdhe4096, 4096}, + {"ffdh6144", NID_ffdhe6144, 6144}, + {"ffdh8192", NID_ffdhe8192, 8192} + }; + uint8_t ffdh_doit[FFDH_NUM] = { 0 }; + +#endif /* OPENSSL_NO_DH */ #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) static const unsigned int dsa_bits[DSA_NUM] = { 512, 1024, 2048 }; uint8_t dsa_doit[DSA_NUM] = { 0 }; @@ -1718,7 +1782,7 @@ int speed_main(int argc, char **argv) case OPT_SECONDS: seconds.sym = seconds.rsa = seconds.dsa = seconds.ecdsa = seconds.ecdh = seconds.eddsa - = seconds.sm2 = atoi(opt_arg()); + = seconds.sm2 = seconds.ffdh = atoi(opt_arg()); break; case OPT_BYTES: lengths_single = atoi(opt_arg()); @@ -1765,6 +1829,18 @@ int speed_main(int argc, char **argv) } } #endif +#ifndef OPENSSL_NO_DH + if (strncmp(algo, "ffdh", 4) == 0) { + if (algo[4] == '\0') { + memset(ffdh_doit, 1, sizeof(ffdh_doit)); + continue; + } + if (opt_found(algo, ffdh_choices, &i)) { + ffdh_doit[i] = 2; + continue; + } + } +#endif #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) if (strncmp(algo, "dsa", 3) == 0) { if (algo[3] == '\0') { @@ -1899,6 +1975,10 @@ int speed_main(int argc, char **argv) #ifndef OPENSSL_NO_EC loopargs[i].secret_a = app_malloc(MAX_ECDH_SIZE, "ECDH secret a"); loopargs[i].secret_b = app_malloc(MAX_ECDH_SIZE, "ECDH secret b"); +#endif +#ifndef OPENSSL_NO_DH + loopargs[i].secret_ff_a = app_malloc(MAX_FFDH_SIZE, "FFDH secret a"); + loopargs[i].secret_ff_b = app_malloc(MAX_FFDH_SIZE, "FFDH secret b"); #endif } @@ -1914,9 +1994,21 @@ int speed_main(int argc, char **argv) if (argc == 0 && !doit[D_EVP] && !doit[D_EVP_HMAC] && !doit[D_EVP_CMAC]) { memset(doit, 1, sizeof(doit)); doit[D_EVP] = doit[D_EVP_HMAC] = doit[D_EVP_CMAC] = 0; +#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DEPRECATED_3_0) + doit[D_MDC2] = 0; +#endif +#if !defined(OPENSSL_NO_MD4) && !defined(OPENSSL_NO_DEPRECATED_3_0) + doit[D_MD4] = 0; +#endif +#if !defined(OPENSSL_NO_RMD160) && !defined(OPENSSL_NO_DEPRECATED_3_0) + doit[D_RMD160] = 0; +#endif #ifndef OPENSSL_NO_RSA memset(rsa_doit, 1, sizeof(rsa_doit)); #endif +#ifndef OPENSSL_NO_DH + memset(ffdh_doit, 1, sizeof(ffdh_doit)); +#endif #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) memset(dsa_doit, 1, sizeof(dsa_doit)); #endif @@ -2108,7 +2200,7 @@ int speed_main(int argc, char **argv) c[D_IGE_256_AES][i] = c[D_IGE_256_AES][i - 1] * l0 / l1; } -# ifndef OPENSSL_NO_RSA +# if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) rsa_c[R_RSA_512][0] = count / 2000; rsa_c[R_RSA_512][1] = count / 400; for (i = 1; i < RSA_NUM; i++) { @@ -2258,6 +2350,19 @@ int speed_main(int argc, char **argv) # endif # endif /* OPENSSL_NO_EC */ +# ifndef OPENSSL_NO_DH + ffdh_c[R_FFDH_2048][0] = count / 1000; + for (i = R_FFDH_3072; i <= R_FFDH_8192; i++) { + ffdh_c[i][0] = ffdh_c[i - 1][0] / 2; + if (ffdh_doit[i] <= 1 && ffdh_c[i][0] == 0) { + ffdh_doit[i] = 0; + } else { + if (ffdh_c[i][0] == 0) + ffdh_c[i][0] = 1; + } + } +# endif /* OPENSSL_NO_DH */ + # else /* not worth fixing */ # error "You cannot disable DES on systems without SIGALRM." @@ -3047,7 +3152,6 @@ int speed_main(int argc, char **argv) rsa_count = 1; } else { for (i = 0; i < loopargs_len; i++) { - EC_KEY_precompute_mult(loopargs[i].ecdsa[testnum], NULL); /* Perform ECDSA signature test */ EC_KEY_generate_key(loopargs[i].ecdsa[testnum]); st = ECDSA_sign(0, loopargs[i].buf, 20, loopargs[i].buf2, @@ -3284,6 +3388,11 @@ int speed_main(int argc, char **argv) st = 0; break; } + loopargs[i].eddsa_ctx2[testnum] = EVP_MD_CTX_new(); + if (loopargs[i].eddsa_ctx2[testnum] == NULL) { + st = 0; + break; + } if ((ed_pctx = EVP_PKEY_CTX_new_id(ed_curves[testnum].nid, NULL)) == NULL @@ -3301,6 +3410,13 @@ int speed_main(int argc, char **argv) EVP_PKEY_free(ed_pkey); break; } + if (!EVP_DigestVerifyInit(loopargs[i].eddsa_ctx2[testnum], NULL, + NULL, NULL, ed_pkey)) { + st = 0; + EVP_PKEY_free(ed_pkey); + break; + } + EVP_PKEY_free(ed_pkey); } if (st == 0) { @@ -3338,10 +3454,9 @@ int speed_main(int argc, char **argv) eddsa_results[testnum][0] = (double)count / d; rsa_count = count; } - /* Perform EdDSA verification test */ for (i = 0; i < loopargs_len; i++) { - st = EVP_DigestVerify(loopargs[i].eddsa_ctx[testnum], + st = EVP_DigestVerify(loopargs[i].eddsa_ctx2[testnum], loopargs[i].buf2, loopargs[i].sigsize, loopargs[i].buf, 20); if (st != 1) @@ -3509,8 +3624,188 @@ int speed_main(int argc, char **argv) } } # endif /* OPENSSL_NO_SM2 */ - #endif /* OPENSSL_NO_EC */ + +#ifndef OPENSSL_NO_DH + for (testnum = 0; testnum < FFDH_NUM; testnum++) { + int ffdh_checks = 1; + + if (!ffdh_doit[testnum]) + continue; + + for (i = 0; i < loopargs_len; i++) { + EVP_PKEY *pkey_A = NULL; + EVP_PKEY *pkey_B = NULL; + EVP_PKEY_CTX *ffdh_ctx = NULL; + EVP_PKEY_CTX *test_ctx = NULL; + size_t secret_size; + size_t test_out; + + /* Ensure that the error queue is empty */ + if (ERR_peek_error()) { + BIO_printf(bio_err, + "WARNING: the error queue contains previous unhandled errors.\n"); + ERR_print_errors(bio_err); + } + + pkey_A = EVP_PKEY_new(); + if (!pkey_A) { + BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + pkey_B = EVP_PKEY_new(); + if (!pkey_B) { + BIO_printf(bio_err, "Error while initialising EVP_PKEY (out of memory?).\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + + ffdh_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, NULL); + if (!ffdh_ctx) { + BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + + if (EVP_PKEY_keygen_init(ffdh_ctx) <= 0) { + BIO_printf(bio_err, "Error while initialising EVP_PKEY_CTX.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_CTX_set_dh_nid(ffdh_ctx, ffdh_params[testnum].nid) <= 0) { + BIO_printf(bio_err, "Error setting DH key size for keygen.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + + if (EVP_PKEY_keygen(ffdh_ctx, &pkey_A) <= 0 || + EVP_PKEY_keygen(ffdh_ctx, &pkey_B) <= 0) { + BIO_printf(bio_err, "FFDH key generation failure.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + + EVP_PKEY_CTX_free(ffdh_ctx); + + /* check if the derivation works correctly both ways so that + * we know if future derive calls will fail, and we can skip + * error checking in benchmarked code */ + ffdh_ctx = EVP_PKEY_CTX_new(pkey_A, NULL); + if (!ffdh_ctx) { + BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive_init(ffdh_ctx) <= 0) { + BIO_printf(bio_err, "FFDH derivation context init failure.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive_set_peer(ffdh_ctx, pkey_B) <= 0) { + BIO_printf(bio_err, "Assigning peer key for derivation failed.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive(ffdh_ctx, NULL, &secret_size) <= 0) { + BIO_printf(bio_err, "Checking size of shared secret failed.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (secret_size > MAX_FFDH_SIZE) { + BIO_printf(bio_err, "Assertion failure: shared secret too large.\n"); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (EVP_PKEY_derive(ffdh_ctx, + loopargs[i].secret_ff_a, + &secret_size) <= 0) { + BIO_printf(bio_err, "Shared secret derive failure.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + /* Now check from side B */ + test_ctx = EVP_PKEY_CTX_new(pkey_B, NULL); + if (!test_ctx) { + BIO_printf(bio_err, "Error while allocating EVP_PKEY_CTX.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + if (!EVP_PKEY_derive_init(test_ctx) || + !EVP_PKEY_derive_set_peer(test_ctx, pkey_A) || + !EVP_PKEY_derive(test_ctx, NULL, &test_out) || + !EVP_PKEY_derive(test_ctx, loopargs[i].secret_ff_b, &test_out) || + test_out != secret_size) { + BIO_printf(bio_err, "FFDH computation failure.\n"); + rsa_count = 1; + ffdh_checks = 0; + break; + } + + /* compare the computed secrets */ + if (CRYPTO_memcmp(loopargs[i].secret_ff_a, + loopargs[i].secret_ff_b, secret_size)) { + BIO_printf(bio_err, "FFDH computations don't match.\n"); + ERR_print_errors(bio_err); + rsa_count = 1; + ffdh_checks = 0; + break; + } + + loopargs[i].ffdh_ctx[testnum] = ffdh_ctx; + + EVP_PKEY_free(pkey_A); + pkey_A = NULL; + EVP_PKEY_free(pkey_B); + pkey_B = NULL; + EVP_PKEY_CTX_free(test_ctx); + test_ctx = NULL; + } + if (ffdh_checks != 0) { + pkey_print_message("", "ffdh", ffdh_c[testnum][0], + ffdh_params[testnum].bits, seconds.ffdh); + Time_F(START); + count = + run_benchmark(async_jobs, FFDH_derive_key_loop, loopargs); + d = Time_F(STOP); + BIO_printf(bio_err, + mr ? "+R12:%ld:%d:%.2f\n" : + "%ld %u-bits FFDH ops in %.2fs\n", count, + ffdh_params[testnum].bits, d); + ffdh_results[testnum][0] = (double)count / d; + rsa_count = count; + }; + if (rsa_count <= 1) { + /* if longer than 10s, don't do any more */ + stop_it(ffdh_doit, testnum); + } + } +#endif /* OPENSSL_NO_DH */ #ifndef NO_FORK show_res: #endif @@ -3687,6 +3982,26 @@ int speed_main(int argc, char **argv) } # endif #endif /* OPENSSL_NO_EC */ +#ifndef OPENSSL_NO_DH + testnum = 1; + for (k = 0; k < FFDH_NUM; k++) { + if (!ffdh_doit[k]) + continue; + if (testnum && !mr) { + printf("%23sop op/s\n", " "); + testnum = 0; + } + if (mr) + printf("+F8:%u:%u:%f:%f\n", + k, ffdh_params[k].bits, + ffdh_results[k][0], 1.0 / ffdh_results[k][0]); + + else + printf("%4u bits ffdh %8.4fs %8.1f\n", + ffdh_params[k].bits, + 1.0 / ffdh_results[k][0], ffdh_results[k][0]); + } +#endif /* OPENSSL_NO_DH */ ret = 0; @@ -3700,6 +4015,13 @@ int speed_main(int argc, char **argv) for (k = 0; k < RSA_NUM; k++) RSA_free(loopargs[i].rsa_key[k]); #endif +#ifndef OPENSSL_NO_DH + OPENSSL_free(loopargs[i].secret_ff_a); + OPENSSL_free(loopargs[i].secret_ff_b); + for (k = 0; k < FFDH_NUM; k++) { + EVP_PKEY_CTX_free(loopargs[i].ffdh_ctx[k]); + } +#endif #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DEPRECATED_3_0) for (k = 0; k < DSA_NUM; k++) DSA_free(loopargs[i].dsa_key[k]); @@ -3709,8 +4031,10 @@ int speed_main(int argc, char **argv) EC_KEY_free(loopargs[i].ecdsa[k]); for (k = 0; k < EC_NUM; k++) EVP_PKEY_CTX_free(loopargs[i].ecdh_ctx[k]); - for (k = 0; k < EdDSA_NUM; k++) + for (k = 0; k < EdDSA_NUM; k++) { EVP_MD_CTX_free(loopargs[i].eddsa_ctx[k]); + EVP_MD_CTX_free(loopargs[i].eddsa_ctx2[k]); + } # ifndef OPENSSL_NO_SM2 for (k = 0; k < SM2_NUM; k++) { EVP_PKEY_CTX *pctx = NULL; @@ -3978,7 +4302,20 @@ static int do_multi(int multi, int size_num) sm2_results[k][1] += d; } # endif /* OPENSSL_NO_SM2 */ -# endif +# endif /* OPENSSL_NO_EC */ +# ifndef OPENSSL_NO_DH + else if (strncmp(buf, "+F8:", 4) == 0) { + int k; + double d; + + p = buf + 4; + k = atoi(sstrsep(&p, sep)); + sstrsep(&p, sep); + + d = atof(sstrsep(&p, sep)); + ffdh_results[k][0] += d; + } +# endif /* OPENSSL_NO_DH */ else if (strncmp(buf, "+H:", 3) == 0) { ; diff --git a/appveyor.yml b/appveyor.yml index 949d6aad..ccca8bb2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -46,7 +46,8 @@ before_build: - cd .. - ps: >- if (-not $env:APPVEYOR_PULL_REQUEST_NUMBER` - -or (&git log -2 | Select-String "\[extended tests\]") ) { + -or (&git log -1 $env:APPVEYOR_PULL_REQUEST_HEAD_COMMIT | + Select-String "\[extended tests\]") ) { $env:EXTENDED_TESTS="yes" } diff --git a/crypto/aes/aes_ige.c b/crypto/aes/aes_ige.c index 51119186..bbe9bcd4 100644 --- a/crypto/aes/aes_ige.c +++ b/crypto/aes/aes_ige.c @@ -18,11 +18,6 @@ #include #include "aes_local.h" -#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long)) -typedef struct { - unsigned long data[N_WORDS]; -} aes_block_t; - /* XXX: probably some better way to do this */ #if defined(__i386__) || defined(__x86_64__) # define UNALIGNED_MEMOPS_ARE_FAST 1 @@ -30,6 +25,15 @@ typedef struct { # define UNALIGNED_MEMOPS_ARE_FAST 0 #endif +#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long)) +typedef struct { + unsigned long data[N_WORDS]; +#if defined(__GNUC__) && UNALIGNED_MEMOPS_ARE_FAST +} aes_block_t __attribute((__aligned__(1))); +#else +} aes_block_t; +#endif + #if UNALIGNED_MEMOPS_ARE_FAST # define load_block(d, s) (d) = *(const aes_block_t *)(s) # define store_block(d, s) *(aes_block_t *)(d) = (s) diff --git a/crypto/asn1/ameth_lib.c b/crypto/asn1/ameth_lib.c index a006c762..8c7df51f 100644 --- a/crypto/asn1/ameth_lib.c +++ b/crypto/asn1/ameth_lib.c @@ -277,7 +277,7 @@ void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth) void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, int (*pub_decode) (EVP_PKEY *pk, - X509_PUBKEY *pub), + const X509_PUBKEY *pub), int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk), int (*pub_cmp) (const EVP_PKEY *a, diff --git a/crypto/bio/b_print.c b/crypto/bio/b_print.c index 0d6fafcc..853f094a 100644 --- a/crypto/bio/b_print.c +++ b/crypto/bio/b_print.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -635,7 +635,11 @@ fmtfp(char **sbuffer, fvalue = tmpvalue; } ufvalue = abs_val(fvalue); - if (ufvalue > ULONG_MAX) { + /* + * By subtracting 65535 (2^16-1) we cancel the low order 15 bits + * of ULONG_MAX to avoid using imprecise floating point values. + */ + if (ufvalue >= (double)(ULONG_MAX - 65535) + 65536.0) { /* Number too big */ return 0; } diff --git a/crypto/bio/b_sock.c b/crypto/bio/b_sock.c index f5d2a627..a6342317 100644 --- a/crypto/bio/b_sock.c +++ b/crypto/bio/b_sock.c @@ -9,6 +9,7 @@ #include #include +#include #include "bio_local.h" #ifndef OPENSSL_NO_SOCK # define SOCKET_PROTOCOL IPPROTO_TCP @@ -23,13 +24,6 @@ static int wsa_init_done = 0; # endif -# ifndef _WIN32 -# include -# include -# else -# include /* for type fd_set */ -# endif - # ifndef OPENSSL_NO_DEPRECATED_1_1_0 int BIO_get_host_ip(const char *str, unsigned char *ip) { @@ -375,30 +369,4 @@ int BIO_sock_info(int sock, return 1; } -/* TODO simplify by BIO_socket_wait() further other uses of select() in apps/ */ -/* - * Wait on fd at most until max_time; succeed immediately if max_time == 0. - * If for_read == 0 then assume to wait for writing, else wait for reading. - * Returns -1 on error, 0 on timeout, and 1 on success. - */ -int BIO_socket_wait(int fd, int for_read, time_t max_time) -{ - fd_set confds; - struct timeval tv; - time_t now; - - if (max_time == 0) - return 1; - - now = time(NULL); - if (max_time <= now) - return 0; - - FD_ZERO(&confds); - openssl_fdset(fd, &confds); - tv.tv_usec = 0; - tv.tv_sec = (long)(max_time - now); /* might overflow */ - return select(fd + 1, for_read ? &confds : NULL, - for_read ? NULL : &confds, NULL, &tv); -} -#endif /* !defined(OPENSSL_NO_SOCK) */ +#endif diff --git a/crypto/bio/bio_err.c b/crypto/bio/bio_err.c index afeb6798..39a79ae7 100644 --- a/crypto/bio/bio_err.c +++ b/crypto/bio/bio_err.c @@ -22,7 +22,6 @@ static const ERR_STRING_DATA BIO_str_reasons[] = { {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BAD_FOPEN_MODE), "bad fopen mode"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BROKEN_PIPE), "broken pipe"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_ERROR), "connect error"}, - {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_TIMEOUT), "connect timeout"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), "gethostbyname addr is not af inet"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETSOCKNAME_ERROR), "getsockname error"}, @@ -46,8 +45,6 @@ static const ERR_STRING_DATA BIO_str_reasons[] = { {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_DEFINED), "no port defined"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "no such file"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NULL_PARAMETER), "null parameter"}, - {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_ERROR), "transfer error"}, - {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_TIMEOUT), "transfer timeout"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_BIND_SOCKET), "unable to bind socket"}, {ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_CREATE_SOCKET), diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c index 1579f7c3..10889184 100644 --- a/crypto/bio/bio_lib.c +++ b/crypto/bio/bio_lib.c @@ -784,102 +784,3 @@ void bio_cleanup(void) CRYPTO_THREAD_lock_free(bio_type_lock); bio_type_lock = NULL; } - -/* Internal variant of the below BIO_wait() not calling BIOerr() */ -static int bio_wait(BIO *bio, time_t max_time, unsigned int milliseconds) -{ -#ifndef OPENSSL_NO_SOCK - int fd; -#endif - - if (max_time == 0) - return 1; - -#ifndef OPENSSL_NO_SOCK - if (BIO_get_fd(bio, &fd) > 0) - return BIO_socket_wait(fd, BIO_should_read(bio), max_time); -#endif - if (milliseconds > 1000) { - long sec_diff = (long)(max_time - time(NULL)); /* might overflow */ - - if (sec_diff <= 0) - return 0; /* timeout */ - if ((unsigned long)sec_diff < milliseconds / 1000) - milliseconds = (unsigned long)sec_diff * 1000; - } - ossl_sleep(milliseconds); - return 1; -} - -/* - * Wait on (typically socket-based) BIO at most until max_time. - * Succeed immediately if max_time == 0. If sockets are not available succeed - * after waiting at most given milliseconds in order to avoid a tight busy loop. - * Call BIOerr(...) unless success. - * Returns -1 on error, 0 on timeout, and 1 on success. - */ -int BIO_wait(BIO *bio, time_t max_time, unsigned int milliseconds) -{ - int rv = bio_wait(bio, max_time, milliseconds); - - if (rv <= 0) - BIOerr(0, rv == 0 ? BIO_R_TRANSFER_TIMEOUT : BIO_R_TRANSFER_ERROR); - return rv; -} - -/* - * Connect via given BIO using BIO_do_handshake() until success/timeout/error. - * Parameter timeout == 0 means infinite, < 0 leads to immediate timeout error. - * Returns -1 on error, 0 on timeout, and 1 on success. - */ -int BIO_connect_retry(BIO *bio, int timeout) -{ - int blocking = timeout == 0; - time_t max_time = timeout > 0 ? time(NULL) + timeout : 0; - int rv; - - if (bio == NULL) { - BIOerr(0, ERR_R_PASSED_NULL_PARAMETER); - return -1; - } - - if (timeout < 0) { - BIOerr(0, BIO_R_CONNECT_TIMEOUT); - return 0; - } - - if (!blocking) - BIO_set_nbio(bio, 1); - - retry: /* it does not help here to set SSL_MODE_AUTO_RETRY */ - rv = BIO_do_handshake(bio); /* This indirectly calls ERR_clear_error(); */ - - if (rv <= 0) { - if (get_last_sys_error() == ETIMEDOUT) { - /* - * if blocking, despite blocking BIO, BIO_do_handshake() timed out - * when non-blocking, BIO_do_handshake() timed out early - * with rv == -1 and get_last_sys_error() == 0 - */ - ERR_clear_error(); - (void)BIO_reset(bio); - /* - * unless using BIO_reset(), blocking next connect() may crash and - * non-blocking next BIO_do_handshake() will fail - */ - goto retry; - } else if (BIO_should_retry(bio)) { - /* will not actually wait if timeout == 0 (i.e., blocking BIO) */ - rv = bio_wait(bio, max_time, 100 /* milliseconds */); - if (rv > 0) - goto retry; - BIOerr(0, rv == 0 ? BIO_R_CONNECT_TIMEOUT : BIO_R_CONNECT_ERROR); - } else { - rv = -1; - if (ERR_peek_error() == 0) /* missing error queue entry */ - BIOerr(0, BIO_R_CONNECT_ERROR); /* workaround: general error */ - } - } - - return rv; -} diff --git a/crypto/bio/bss_conn.c b/crypto/bio/bss_conn.c index d3bd33e9..31a5b58b 100644 --- a/crypto/bio/bss_conn.c +++ b/crypto/bio/bss_conn.c @@ -188,8 +188,17 @@ static int conn_state(BIO *b, BIO_CONNECT *c) case BIO_CONN_S_BLOCKED_CONNECT: i = BIO_sock_error(b->num); - if (i) { + if (i != 0) { BIO_clear_retry_flags(b); + if ((c->addr_iter = BIO_ADDRINFO_next(c->addr_iter)) != NULL) { + /* + * if there are more addresses to try, do that first + */ + BIO_closesocket(b->num); + c->state = BIO_CONN_S_CREATE_SOCKET; + ERR_clear_error(); + break; + } ERR_raise_data(ERR_LIB_SYS, i, "calling connect(%s, %s)", c->param_hostname, c->param_service); diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c index a72a4768..ff2bde7a 100644 --- a/crypto/bio/bss_sock.c +++ b/crypto/bio/bss_sock.c @@ -154,10 +154,11 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) long ret = 1; int *ip; # ifndef OPENSSL_NO_KTLS + size_t crypto_info_len; # ifdef __FreeBSD__ struct tls_enable *crypto_info; # else - struct tls12_crypto_info_aes_gcm_128 *crypto_info; + struct tls_crypto_info_all *crypto_info; # endif # endif @@ -191,10 +192,12 @@ static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_SET_KTLS: # ifdef __FreeBSD__ crypto_info = (struct tls_enable *)ptr; + crypto_info_len = sizeof(*crypto_info); # else - crypto_info = (struct tls12_crypto_info_aes_gcm_128 *)ptr; + crypto_info = (struct tls_crypto_info_all *)ptr; + crypto_info_len = crypto_info->tls_crypto_info_len; # endif - ret = ktls_start(b->num, crypto_info, sizeof(*crypto_info), num); + ret = ktls_start(b->num, crypto_info, crypto_info_len, num); if (ret) BIO_set_ktls_flag(b, num); break; diff --git a/crypto/bn/bn_dh.c b/crypto/bn/bn_dh.c index 9a7cc17f..74ce0240 100644 --- a/crypto/bn/bn_dh.c +++ b/crypto/bn/bn_dh.c @@ -29,7 +29,7 @@ * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 } * * RFC3526 specifies a generator of 2. - * RFC2312 specifies a generator of 22. + * RFC2412 specifies a generator of 22. */ static const BN_ULONG modp_1536_p[] = { BN_DEF(0xFFFFFFFF, 0xFFFFFFFF), BN_DEF(0xCA237327, 0xF1746C08), diff --git a/crypto/bn/bn_mpi.c b/crypto/bn/bn_mpi.c index 504cddff..b8e92e12 100644 --- a/crypto/bn/bn_mpi.c +++ b/crypto/bn/bn_mpi.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -45,7 +45,7 @@ BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain) int neg = 0; BIGNUM *a = NULL; - if (n < 4) { + if (n < 4 || (d[0] & 0x80) != 0) { BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH); return NULL; } diff --git a/crypto/build.info b/crypto/build.info index 83625029..a8de05ac 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -5,7 +5,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \ md2 md4 md5 sha mdc2 hmac ripemd whrlpool poly1305 \ siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \ seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \ - err comp http ocsp cms ts srp cmac ct async ess crmf cmp serializer \ + err comp ocsp cms ts srp cmac ct async ess crmf cmp serializer \ ffc LIBS=../libcrypto diff --git a/crypto/cast/build.info b/crypto/cast/build.info index 8763f224..01a3691d 100644 --- a/crypto/cast/build.info +++ b/crypto/cast/build.info @@ -2,7 +2,7 @@ LIBS=../../libcrypto $CASTASM=c_enc.c # CAST assembly source is not PIC -IF[{- !$disabled{asm} && !$disabled{pic} -}] +IF[{- !$disabled{asm} && $disabled{pic} -}] $CASTASM_x86=cast-586.s # Now that we have defined all the arch specific variables, use the diff --git a/crypto/cmac/cm_ameth.c b/crypto/cmac/cm_ameth.c index aa06cdc9..ece3d8f9 100644 --- a/crypto/cmac/cm_ameth.c +++ b/crypto/cmac/cm_ameth.c @@ -31,9 +31,9 @@ static int cmac_size(const EVP_PKEY *pkey) static void cmac_key_free(EVP_PKEY *pkey) { EVP_MAC_CTX *cmctx = EVP_PKEY_get0(pkey); - EVP_MAC *mac = cmctx == NULL ? NULL : EVP_MAC_CTX_mac(cmctx); + EVP_MAC *mac = cmctx == NULL ? NULL : EVP_MAC_get_ctx_mac(cmctx); - EVP_MAC_CTX_free(cmctx); + EVP_MAC_free_ctx(cmctx); EVP_MAC_free(mac); } diff --git a/crypto/cmac/cmac.c b/crypto/cmac/cmac.c index 7f55c465..81a64903 100644 --- a/crypto/cmac/cmac.c +++ b/crypto/cmac/cmac.c @@ -125,12 +125,18 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, return 1; } /* Initialise context */ - if (cipher && !EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL)) - return 0; + if (cipher != NULL) { + /* Ensure we can't use this ctx until we also have a key */ + ctx->nlast_block = -1; + if (!EVP_EncryptInit_ex(ctx->cctx, cipher, impl, NULL, NULL)) + return 0; + } /* Non-NULL key means initialisation complete */ - if (key) { + if (key != NULL) { int bl; + /* If anything fails then ensure we can't use this ctx */ + ctx->nlast_block = -1; if (!EVP_CIPHER_CTX_cipher(ctx->cctx)) return 0; if (!EVP_CIPHER_CTX_set_key_length(ctx->cctx, keylen)) @@ -139,7 +145,7 @@ int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, return 0; if ((bl = EVP_CIPHER_CTX_block_size(ctx->cctx)) < 0) return 0; - if (!EVP_Cipher(ctx->cctx, ctx->tbl, zero_iv, bl)) + if (EVP_Cipher(ctx->cctx, ctx->tbl, zero_iv, bl) <= 0) return 0; make_kn(ctx->k1, ctx->tbl, bl); make_kn(ctx->k2, ctx->k1, bl); @@ -180,12 +186,12 @@ int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) return 1; data += nleft; /* Else not final block so encrypt it */ - if (!EVP_Cipher(ctx->cctx, ctx->tbl, ctx->last_block, bl)) + if (EVP_Cipher(ctx->cctx, ctx->tbl, ctx->last_block, bl) <= 0) return 0; } /* Encrypt all but one of the complete blocks left */ while (dlen > (size_t)bl) { - if (!EVP_Cipher(ctx->cctx, ctx->tbl, data, bl)) + if (EVP_Cipher(ctx->cctx, ctx->tbl, data, bl) <= 0) return 0; dlen -= bl; data += bl; diff --git a/crypto/cmp/build.info b/crypto/cmp/build.info index a2a57c14..d3fbae24 100644 --- a/crypto/cmp/build.info +++ b/crypto/cmp/build.info @@ -1,4 +1,4 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]= cmp_asn.c cmp_ctx.c cmp_err.c cmp_util.c \ cmp_status.c cmp_hdr.c cmp_protect.c cmp_msg.c cmp_vfy.c \ - cmp_server.c cmp_client.c cmp_http.c + cmp_server.c cmp_client.c diff --git a/crypto/cmp/cmp_client.c b/crypto/cmp/cmp_client.c index d309f84a..1c62d6c9 100644 --- a/crypto/cmp/cmp_client.c +++ b/crypto/cmp/cmp_client.c @@ -146,7 +146,7 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, OSSL_CMP_transfer_cb_t transfer_cb = ctx->transfer_cb; if (transfer_cb == NULL) - transfer_cb = OSSL_CMP_MSG_http_perform; + transfer_cb = NULL; /* TODO: will be OSSL_CMP_MSG_http_perform of chunk 10 */ *rep = NULL; msg_timeout = ctx->msg_timeout; /* backup original value */ @@ -189,8 +189,8 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, */ ossl_cmp_log1(INFO, ctx, "received %s", ossl_cmp_bodytype_to_string(bt)); - if ((bt = ossl_cmp_msg_check_received(ctx, *rep, unprotected_exception, - expected_type)) < 0) + if (!ossl_cmp_msg_check_update(ctx, *rep, unprotected_exception, + expected_type)) return 0; if (bt == expected_type diff --git a/crypto/cmp/cmp_ctx.c b/crypto/cmp/cmp_ctx.c index 9aeee7f5..cbb8c850 100644 --- a/crypto/cmp/cmp_ctx.c +++ b/crypto/cmp/cmp_ctx.c @@ -43,6 +43,7 @@ X509_STORE *OSSL_CMP_CTX_get0_trustedStore(const OSSL_CMP_CTX *ctx) * Set certificate store containing trusted (root) CA certs and possibly CRLs * and a cert verification callback function used for CMP server authentication. * Any already existing store entry is freed. Given NULL, the entry is reset. + * returns 1 on success, 0 on error */ int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store) { @@ -55,7 +56,9 @@ int OSSL_CMP_CTX_set0_trustedStore(OSSL_CMP_CTX *ctx, X509_STORE *store) return 1; } -/* Get current list of non-trusted intermediate certs */ +/* + * Get current list of non-trusted intermediate certs + */ STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx) { if (ctx == NULL) { @@ -68,6 +71,7 @@ STACK_OF(X509) *OSSL_CMP_CTX_get0_untrusted_certs(const OSSL_CMP_CTX *ctx) /* * Set untrusted certificates for path construction in authentication of * the CMP server and potentially others (TLS server, newly enrolled cert). + * returns 1 on success, 0 on error */ int OSSL_CMP_CTX_set1_untrusted_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs) { @@ -104,6 +108,8 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void) ctx->status = -1; ctx->failInfoCode = -1; + ctx->serverPort = OSSL_CMP_DEFAULT_PORT; + ctx->proxyPort = OSSL_CMP_DEFAULT_PORT; ctx->msg_timeout = 2 * 60; if ((ctx->untrusted_certs = sk_X509_new_null()) == NULL) @@ -126,7 +132,9 @@ OSSL_CMP_CTX *OSSL_CMP_CTX_new(void) return NULL; } -/* Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX */ +/* + * Prepare the OSSL_CMP_CTX for next use, partly re-initializing OSSL_CMP_CTX + */ int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx) { if (ctx == NULL) { @@ -147,16 +155,17 @@ int OSSL_CMP_CTX_reinit(OSSL_CMP_CTX *ctx) && ossl_cmp_ctx_set1_recipNonce(ctx, NULL); } -/* Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new() */ +/* + * Frees OSSL_CMP_CTX variables allocated in OSSL_CMP_CTX_new() + */ void OSSL_CMP_CTX_free(OSSL_CMP_CTX *ctx) { if (ctx == NULL) return; OPENSSL_free(ctx->serverPath); - OPENSSL_free(ctx->server); - OPENSSL_free(ctx->proxy); - OPENSSL_free(ctx->no_proxy); + OPENSSL_free(ctx->serverName); + OPENSSL_free(ctx->proxyName); X509_free(ctx->srvCert); X509_free(ctx->validatedSrvCert); @@ -250,7 +259,11 @@ int ossl_cmp_ctx_set0_validatedSrvCert(OSSL_CMP_CTX *ctx, X509 *cert) return 1; } -/* Set callback function for checking if the cert is ok or should be rejected */ +/* + * Set callback function for checking if the cert is ok or should + * it be rejected. + * Returns 1 on success, 0 on error + */ int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb) { if (ctx == NULL) { @@ -264,6 +277,7 @@ int OSSL_CMP_CTX_set_certConf_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_certConf_cb_t cb) /* * Set argument, respectively a pointer to a structure containing arguments, * optionally to be used by the certConf callback. + * Returns 1 on success, 0 on error */ int OSSL_CMP_CTX_set_certConf_cb_arg(OSSL_CMP_CTX *ctx, void *arg) { @@ -373,7 +387,10 @@ int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx, return res; } -/* Set a callback function for error reporting and logging messages */ +/* + * Set a callback function for error reporting and logging messages. + * Returns 1 on success, 0 on error + */ int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb) { if (ctx == NULL) { @@ -393,7 +410,7 @@ int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb) } /* Print OpenSSL and CMP errors via the log cb of the ctx or ERR_print_errors */ -void OSSL_CMP_CTX_print_errors(OSSL_CMP_CTX *ctx) +void OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX *ctx) { OSSL_CMP_print_errors_cb(ctx == NULL ? NULL : ctx->log_cb); } @@ -401,6 +418,7 @@ void OSSL_CMP_CTX_print_errors(OSSL_CMP_CTX *ctx) /* * Set or clear the reference value to be used for identification * (i.e., the user name) when using PBMAC. + * Returns 1 on success, 0 on error */ int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx, const unsigned char *ref, int len) @@ -413,7 +431,10 @@ int OSSL_CMP_CTX_set1_referenceValue(OSSL_CMP_CTX *ctx, len); } -/* Set or clear the password to be used for protecting messages with PBMAC */ +/* + * Set or clear the password to be used for protecting messages with PBMAC. + * Returns 1 on success, 0 on error + */ int OSSL_CMP_CTX_set1_secretValue(OSSL_CMP_CTX *ctx, const unsigned char *sec, const int len) { @@ -451,6 +472,7 @@ STACK_OF(X509) *OSSL_CMP_CTX_get1_extraCertsIn(const OSSL_CMP_CTX *ctx) /* * Copies any given stack of inbound X509 certificates to extraCertsIn * of the OSSL_CMP_CTX structure so that they may be retrieved later. + * Returns 1 on success, 0 on error. */ int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx, STACK_OF(X509) *extraCertsIn) @@ -468,6 +490,7 @@ int ossl_cmp_ctx_set1_extraCertsIn(OSSL_CMP_CTX *ctx, /* * Duplicate and set the given stack as the new stack of X509 * certificates to send out in the extraCerts field. + * Returns 1 on success, 0 on error */ int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx, STACK_OF(X509) *extraCertsOut) @@ -487,6 +510,7 @@ int OSSL_CMP_CTX_set1_extraCertsOut(OSSL_CMP_CTX *ctx, /* * Add the given policy info object * to the X509_EXTENSIONS of the requested certificate template. + * Returns 1 on success, 0 on error. */ int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo) { @@ -502,7 +526,9 @@ int OSSL_CMP_CTX_push0_policy(OSSL_CMP_CTX *ctx, POLICYINFO *pinfo) return sk_POLICYINFO_push(ctx->policies, pinfo); } -/* Add an ITAV for geninfo of the PKI message header */ +/* + * Add an ITAV for geninfo of the PKI message header + */ int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav) { if (ctx == NULL) { @@ -512,7 +538,9 @@ int OSSL_CMP_CTX_push0_geninfo_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav) return OSSL_CMP_ITAV_push0_stack_item(&ctx->geninfo_ITAVs, itav); } -/* Add an itav for the body of outgoing general messages */ +/* + * Add an itav for the body of outgoing general messages + */ int OSSL_CMP_CTX_push0_genm_ITAV(OSSL_CMP_CTX *ctx, OSSL_CMP_ITAV *itav) { if (ctx == NULL) { @@ -541,6 +569,7 @@ STACK_OF(X509) *OSSL_CMP_CTX_get1_caPubs(const OSSL_CMP_CTX *ctx) /* * Duplicate and copy the given stack of certificates to the given * OSSL_CMP_CTX structure so that they may be retrieved later. + * Returns 1 on success, 0 on error */ int ossl_cmp_ctx_set1_caPubs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *caPubs) { @@ -592,25 +621,39 @@ int OSSL_CMP_CTX_set1_##FIELD(OSSL_CMP_CTX *ctx, TYPE *val) \ * Pins the server certificate to be directly trusted (even if it is expired) * for verifying response messages. * Cert pointer is not consumed. It may be NULL to clear the entry. + * Returns 1 on success, 0 on error */ DEFINE_OSSL_CMP_CTX_set1_up_ref(srvCert, X509) -/* Set the X509 name of the recipient. Set in the PKIHeader */ +/* + * Set the X509 name of the recipient. Set in the PKIHeader. + * returns 1 on success, 0 on error + */ DEFINE_OSSL_CMP_CTX_set1(recipient, X509_NAME) -/* Store the X509 name of the expected sender in the PKIHeader of responses */ +/* + * Store the X509 name of the expected sender in the PKIHeader of responses. + * Returns 1 on success, 0 on error + */ DEFINE_OSSL_CMP_CTX_set1(expected_sender, X509_NAME) -/* Set the X509 name of the issuer. Set in the PKIHeader */ +/* + * Set the X509 name of the issuer. Set in the PKIHeader. + * Returns 1 on success, 0 on error + */ DEFINE_OSSL_CMP_CTX_set1(issuer, X509_NAME) /* * Set the subject name that will be placed in the certificate * request. This will be the subject name on the received certificate. + * Returns 1 on success, 0 on error */ DEFINE_OSSL_CMP_CTX_set1(subjectName, X509_NAME) -/* Set the X.509v3 certificate request extensions to be used in IR/CR/KUR */ +/* + * Set the X.509v3 certificate request extensions to be used in IR/CR/KUR. + * Returns 1 on success, 0 on error + */ int OSSL_CMP_CTX_set0_reqExtensions(OSSL_CMP_CTX *ctx, X509_EXTENSIONS *exts) { if (ctx == NULL) { @@ -644,6 +687,7 @@ int OSSL_CMP_CTX_reqExtensions_have_SAN(OSSL_CMP_CTX *ctx) /* * Add a GENERAL_NAME structure that will be added to the CRMF * request's extensions field to request subject alternative names. + * Returns 1 on success, 0 on error */ int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx, const GENERAL_NAME *name) @@ -675,6 +719,7 @@ int OSSL_CMP_CTX_push1_subjectAltName(OSSL_CMP_CTX *ctx, /* * Set our own client certificate, used for example in KUR and when * doing the IR with existing certificate. + * Returns 1 on success, 0 on error */ DEFINE_OSSL_CMP_CTX_set1_up_ref(cert, X509) @@ -683,14 +728,19 @@ DEFINE_OSSL_CMP_CTX_set1_up_ref(cert, X509) * or the certificate to be revoked in RR, respectively. * Also used as reference cert (defaulting to cert) for deriving subject DN * and SANs. Its issuer is used as default recipient in the CMP message header. + * Returns 1 on success, 0 on error */ DEFINE_OSSL_CMP_CTX_set1_up_ref(oldCert, X509) -/* Set the PKCS#10 CSR to be sent in P10CR */ +/* + * Set the PKCS#10 CSR to be sent in P10CR. + * Returns 1 on success, 0 on error + */ DEFINE_OSSL_CMP_CTX_set1(p10CSR, X509_REQ) /* - * Set the (newly received in IP/KUP/CP) certificate in the context. + * Sets the (newly received in IP/KUP/CP) certificate in the context. + * Returns 1 on success, 0 on error * TODO: this only permits for one cert to be enrolled at a time. */ int ossl_cmp_ctx_set0_newCert(OSSL_CMP_CTX *ctx, X509 *cert) @@ -716,10 +766,16 @@ X509 *OSSL_CMP_CTX_get0_newCert(const OSSL_CMP_CTX *ctx) return ctx->newCert; } -/* Set the client's current private key */ +/* + * Set the client's current private key. + * Returns 1 on success, 0 on error + */ DEFINE_OSSL_CMP_CTX_set1_up_ref(pkey, EVP_PKEY) -/* Set new key pair. Used e.g. when doing Key Update */ +/* + * Set new key pair. Used e.g. when doing Key Update. + * Returns 1 on success, 0 on error + */ int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey) { if (ctx == NULL) { @@ -733,7 +789,9 @@ int OSSL_CMP_CTX_set0_newPkey(OSSL_CMP_CTX *ctx, int priv, EVP_PKEY *pkey) return 1; } -/* Get the private/public key to use for cert enrollment, or NULL on error */ +/* + * gets the private/public key to use for certificate enrollment, NULL on error + */ EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv) { if (ctx == NULL) { @@ -748,7 +806,10 @@ EVP_PKEY *OSSL_CMP_CTX_get0_newPkey(const OSSL_CMP_CTX *ctx, int priv) return ctx->pkey; /* may be NULL */ } -/* Set the given transactionID to the context */ +/* + * Sets the given transactionID to the context. + * Returns 1 on success, 0 on error + */ int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx, const ASN1_OCTET_STRING *id) { @@ -759,7 +820,11 @@ int OSSL_CMP_CTX_set1_transactionID(OSSL_CMP_CTX *ctx, return ossl_cmp_asn1_octet_string_set1(&ctx->transactionID, id); } -/* Set the nonce to be used for the recipNonce in the message created next */ +/* + * sets the given nonce to be used for the recipNonce in the next message to be + * created. + * returns 1 on success, 0 on error + */ int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx, const ASN1_OCTET_STRING *nonce) { @@ -768,7 +833,10 @@ int ossl_cmp_ctx_set1_recipNonce(OSSL_CMP_CTX *ctx, return ossl_cmp_asn1_octet_string_set1(&ctx->recipNonce, nonce); } -/* Stores the given nonce as the last senderNonce sent out */ +/* + * Stores the given nonce as the last senderNonce sent out. + * Returns 1 on success, 0 on error + */ int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx, const ASN1_OCTET_STRING *nonce) { @@ -779,17 +847,37 @@ int OSSL_CMP_CTX_set1_senderNonce(OSSL_CMP_CTX *ctx, return ossl_cmp_asn1_octet_string_set1(&ctx->senderNonce, nonce); } -/* Set the proxy server to use for HTTP(S) connections */ -DEFINE_OSSL_CMP_CTX_set1(proxy, char) +/* + * Set the host name of the (HTTP) proxy server to use for all connections + * returns 1 on success, 0 on error + */ +DEFINE_OSSL_CMP_CTX_set1(proxyName, char) -/* Set the (HTTP) host name of the CMP server */ -DEFINE_OSSL_CMP_CTX_set1(server, char) +/* + * Set the (HTTP) host name of the CA server. + * Returns 1 on success, 0 on error + */ +DEFINE_OSSL_CMP_CTX_set1(serverName, char) -/* Set the server exclusion list of the HTTP proxy server */ -DEFINE_OSSL_CMP_CTX_set1(no_proxy, char) +/* + * Sets the (HTTP) proxy port to be used. + * Returns 1 on success, 0 on error + */ +int OSSL_CMP_CTX_set_proxyPort(OSSL_CMP_CTX *ctx, int port) +{ + if (ctx == NULL) { + CMPerr(0, CMP_R_NULL_ARGUMENT); + return 0; + } + ctx->proxyPort = port; + return 1; +} -/* Set the http connect/disconnect callback function to be used for HTTP(S) */ -int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb) +/* + * sets the http connect/disconnect callback function to be used for HTTP(S) + * returns 1 on success, 0 on error + */ +int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_http_cb_t cb) { if (ctx == NULL) { CMPerr(0, CMP_R_NULL_ARGUMENT); @@ -799,7 +887,10 @@ int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb) return 1; } -/* Set argument optionally to be used by the http connect/disconnect callback */ +/* + * Set argument optionally to be used by the http connect/disconnect callback. + * Returns 1 on success, 0 on error + */ int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg) { if (ctx == NULL) { @@ -823,7 +914,10 @@ void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx) return ctx->http_cb_arg; } -/* Set callback function for sending CMP request and receiving response */ +/* + * Set callback function for sending CMP request and receiving response. + * Returns 1 on success, 0 on error + */ int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb) { if (ctx == NULL) { @@ -834,7 +928,10 @@ int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb) return 1; } -/* Set argument optionally to be used by the transfer callback */ +/* + * Set argument optionally to be used by the transfer callback. + * Returns 1 on success, 0 on error + */ int OSSL_CMP_CTX_set_transfer_cb_arg(OSSL_CMP_CTX *ctx, void *arg) { if (ctx == NULL) { @@ -858,7 +955,10 @@ void *OSSL_CMP_CTX_get_transfer_cb_arg(const OSSL_CMP_CTX *ctx) return ctx->transfer_cb_arg; } -/** Set the HTTP server port to be used */ +/* + * Sets the (HTTP) server port to be used. + * Returns 1 on success, 0 on error + */ int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port) { if (ctx == NULL) { @@ -869,10 +969,16 @@ int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port) return 1; } -/* Set the HTTP path to be used on the server (e.g "pkix/") */ +/* + * Sets the HTTP path to be used on the server (e.g "pkix/"). + * Returns 1 on success, 0 on error + */ DEFINE_OSSL_CMP_CTX_set1(serverPath, char) -/* Set the failInfo error code as bit encoding in OSSL_CMP_CTX */ +/* + * Set the failInfo error code as bit encoding in OSSL_CMP_CTX. + * Returns 1 on success, 0 on error + */ int ossl_cmp_ctx_set_failInfoCode(OSSL_CMP_CTX *ctx, int fail_info) { if (!ossl_assert(ctx != NULL)) @@ -894,7 +1000,10 @@ int OSSL_CMP_CTX_get_failInfoCode(const OSSL_CMP_CTX *ctx) return ctx->failInfoCode; } -/* Set a Boolean or integer option of the context to the "val" arg */ +/* + * Sets a Boolean or integer option of the context to the "val" arg. + * Returns 1 on success, 0 on error + */ int OSSL_CMP_CTX_set_option(OSSL_CMP_CTX *ctx, int opt, int val) { int min_val; diff --git a/crypto/cmp/cmp_err.c b/crypto/cmp/cmp_err.c index 0c3547c0..5f2f713b 100644 --- a/crypto/cmp/cmp_err.c +++ b/crypto/cmp/cmp_err.c @@ -76,6 +76,8 @@ static const ERR_STRING_DATA CMP_str_reasons[] = { "error unexpected certconf"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_PROTECTION), "error validating protection"}, + {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_SIGNATURE), + "error validating signature"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY), "failed extracting pubkey"}, {ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILURE_OBTAINING_RANDOM), diff --git a/crypto/cmp/cmp_hdr.c b/crypto/cmp/cmp_hdr.c index b07bf031..364d89a9 100644 --- a/crypto/cmp/cmp_hdr.c +++ b/crypto/cmp/cmp_hdr.c @@ -41,6 +41,14 @@ int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr) return (int)pvno; } +int ossl_cmp_hdr_get_protection_nid(const OSSL_CMP_PKIHEADER *hdr) +{ + if (!ossl_assert(hdr != NULL) + || hdr->protectionAlg == NULL) + return NID_undef; + return OBJ_obj2nid(hdr->protectionAlg->algorithm); +} + ASN1_OCTET_STRING *OSSL_CMP_HDR_get0_transactionID(const OSSL_CMP_PKIHEADER *hdr) { @@ -300,30 +308,26 @@ int ossl_cmp_hdr_init(OSSL_CMP_CTX *ctx, OSSL_CMP_PKIHEADER *hdr) return 0; /* - * The sender name is copied from the subject of the client cert, if any, - * or else from the subject name provided for certification requests. + * If neither protection cert nor oldCert nor subject are given, + * sender name is not known to the client and thus set to NULL-DN */ - sender = ctx->cert != NULL ? - X509_get_subject_name(ctx->cert) : ctx->subjectName; + sender = ctx->cert != NULL ? X509_get_subject_name(ctx->cert) : + ctx->oldCert != NULL ? X509_get_subject_name(ctx->oldCert) : + ctx->subjectName; if (!ossl_cmp_hdr_set1_sender(hdr, sender)) return 0; /* determine recipient entry in PKIHeader */ - if (ctx->srvCert != NULL) { - rcp = X509_get_subject_name(ctx->srvCert); - /* set also as expected_sender of responses unless set explicitly */ - if (ctx->expected_sender == NULL && rcp != NULL - && !OSSL_CMP_CTX_set1_expected_sender(ctx, rcp)) - return 0; - } else if (ctx->recipient != NULL) { + if (ctx->recipient != NULL) rcp = ctx->recipient; - } else if (ctx->issuer != NULL) { + else if (ctx->srvCert != NULL) + rcp = X509_get_subject_name(ctx->srvCert); + else if (ctx->issuer != NULL) rcp = ctx->issuer; - } else if (ctx->oldCert != NULL) { + else if (ctx->oldCert != NULL) rcp = X509_get_issuer_name(ctx->oldCert); - } else if (ctx->cert != NULL) { + else if (ctx->cert != NULL) rcp = X509_get_issuer_name(ctx->cert); - } if (!ossl_cmp_hdr_set1_recipient(hdr, rcp)) return 0; diff --git a/crypto/cmp/cmp_http.c b/crypto/cmp/cmp_http.c deleted file mode 100644 index 3804f249..00000000 --- a/crypto/cmp/cmp_http.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. - * Copyright Nokia 2007-2019 - * Copyright Siemens AG 2015-2019 - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include - -#include -#include -#include "internal/sockets.h" - -#include "openssl/cmp.h" -#include "cmp_local.h" - -/* explicit #includes not strictly needed since implied by the above: */ -#include -#include -#include -#include -#include -#include -#include - -DEFINE_STACK_OF(CONF_VALUE) - -/* - * Send the PKIMessage req and on success return the response, else NULL. - * Any previous error queue entries will likely be removed by ERR_clear_error(). - */ -OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, - const OSSL_CMP_MSG *req) -{ - char server_port[32] = { '\0' }; - STACK_OF(CONF_VALUE) *headers = NULL; - const char *const content_type_pkix = "application/pkixcmp"; - OSSL_CMP_MSG *res; - - if (ctx == NULL || req == NULL) { - CMPerr(0, CMP_R_NULL_ARGUMENT); - return NULL; - } - - if (!X509V3_add_value("Pragma", "no-cache", &headers)) - return NULL; - - if (ctx->serverPort != 0) - BIO_snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort); - - res = (OSSL_CMP_MSG *) - OSSL_HTTP_post_asn1(ctx->server, server_port, ctx->serverPath, - OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL, - ctx->proxy, ctx->no_proxy, NULL, NULL, - ctx->http_cb, OSSL_CMP_CTX_get_http_cb_arg(ctx), - headers, content_type_pkix, (const ASN1_VALUE *)req, - ASN1_ITEM_rptr(OSSL_CMP_MSG), - 0, 0, ctx->msg_timeout, content_type_pkix, - ASN1_ITEM_rptr(OSSL_CMP_MSG)); - - sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); - return res; -} diff --git a/crypto/cmp/cmp_local.h b/crypto/cmp/cmp_local.h index 04abcf50..5ab18995 100644 --- a/crypto/cmp/cmp_local.h +++ b/crypto/cmp/cmp_local.h @@ -36,15 +36,15 @@ struct ossl_cmp_ctx_st { void *transfer_cb_arg; /* allows to store optional argument to cb */ /* HTTP-based transfer */ char *serverPath; - char *server; + char *serverName; int serverPort; - char *proxy; - char *no_proxy; + char *proxyName; + int proxyPort; int msg_timeout; /* max seconds to wait for each CMP message round trip */ int total_timeout; /* max number of seconds an enrollment may take, incl. */ /* attempts polling for a response if a 'waiting' PKIStatus is received */ time_t end_time; /* session start time + totaltimeout */ - OSSL_HTTP_bio_cb_t http_cb; + OSSL_CMP_http_cb_t http_cb; void *http_cb_arg; /* allows to store optional argument to cb */ /* server authentication */ @@ -283,7 +283,6 @@ struct ossl_cmp_pkisi_st { OSSL_CMP_PKIFREETEXT *statusString; OSSL_CMP_PKIFAILUREINFO *failInfo; } /* OSSL_CMP_PKISI */; -DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID) /*- * RevReqContent ::= SEQUENCE OF RevDetails @@ -797,6 +796,7 @@ int ossl_cmp_pkisi_check_pkifailureinfo(const OSSL_CMP_PKISI *si, int index); /* from cmp_hdr.c */ int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno); int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr); +int ossl_cmp_hdr_get_protection_nid(const OSSL_CMP_PKIHEADER *hdr); ASN1_OCTET_STRING *ossl_cmp_hdr_get0_senderNonce(const OSSL_CMP_PKIHEADER *hdr); int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name); int ossl_cmp_hdr_set1_sender(OSSL_CMP_PKIHEADER *hdr, const X509_NAME *nm); @@ -909,8 +909,8 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg); typedef int (*ossl_cmp_allow_unprotected_cb_t)(const OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, int invalid_protection, int arg); -int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, - ossl_cmp_allow_unprotected_cb_t cb, int cb_arg); +int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, + ossl_cmp_allow_unprotected_cb_t cb, int cb_arg); int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified); /* from cmp_client.c */ diff --git a/crypto/cmp/cmp_msg.c b/crypto/cmp/cmp_msg.c index 7b338b2b..9735a1c0 100644 --- a/crypto/cmp/cmp_msg.c +++ b/crypto/cmp/cmp_msg.c @@ -23,6 +23,7 @@ DEFINE_STACK_OF(OSSL_CMP_CERTSTATUS) DEFINE_STACK_OF(OSSL_CMP_ITAV) DEFINE_STACK_OF(GENERAL_NAME) +DEFINE_STACK_OF(X509) DEFINE_STACK_OF(X509_EXTENSION) DEFINE_STACK_OF(OSSL_CMP_PKISI) DEFINE_STACK_OF(OSSL_CRMF_MSG) @@ -228,7 +229,7 @@ static OSSL_CRMF_MSG *crm_new(OSSL_CMP_CTX *ctx, int bodytype, int rid) X509_EXTENSIONS *exts = NULL; if (rkey == NULL) - rkey = ctx->pkey; /* default is independent of ctx->oldClCert */ + rkey = ctx->pkey; /* default is independent of ctx->oldCert */ if (rkey == NULL) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION CMPerr(0, CMP_R_NULL_ARGUMENT); @@ -426,9 +427,12 @@ OSSL_CMP_MSG *ossl_cmp_certRep_new(OSSL_CMP_CTX *ctx, int bodytype, if (bodytype == OSSL_CMP_PKIBODY_IP && caPubs != NULL && (repMsg->caPubs = X509_chain_up_ref(caPubs)) == NULL) goto err; - if (chain != NULL - && !ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain, 0, 1, 0)) + if (sk_X509_num(chain) > 0) { + msg->extraCerts = sk_X509_new_reserve(NULL, sk_X509_num(chain)); + if (msg->extraCerts == NULL + || !ossl_cmp_sk_X509_add1_certs(msg->extraCerts, chain, 0, 1, 0)) goto err; + } if (!unprotectedErrors || ossl_cmp_pkisi_get_status(si) != OSSL_CMP_PKISTATUS_rejection) diff --git a/crypto/cmp/cmp_protect.c b/crypto/cmp/cmp_protect.c index 97600a72..880051d3 100644 --- a/crypto/cmp/cmp_protect.c +++ b/crypto/cmp/cmp_protect.c @@ -26,8 +26,8 @@ DEFINE_STACK_OF(X509) * Calculate protection for given PKImessage utilizing the given credentials * and the algorithm parameters set inside the message header's protectionAlg. * - * Either secret or pkey must be set, the other must be NULL. Attempts doing - * PBMAC in case 'secret' is set and signature if 'pkey' is set - but will only + * secret or pkey must be set. Attempts doing PBMAC in case 'secret' is set + * and else signature if 'pkey' is set - but will only * do the protection already marked in msg->header->protectionAlg. * * returns ptr to ASN1_BIT_STRING containing protection on success, else NULL @@ -73,7 +73,7 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg, } X509_ALGOR_get0(&algorOID, &pptype, &ppval, msg->header->protectionAlg); - if (secret != NULL && pkey == NULL) { + if (secret != NULL) { if (ppval == NULL) { CMPerr(0, CMP_R_ERROR_CALCULATING_PROTECTION); goto end; @@ -94,7 +94,7 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_MSG *msg, secret->data, secret->length, &protection, &sig_len)) goto end; - } else if (secret == NULL && pkey != NULL) { + } else if (pkey != NULL) { /* TODO combine this with large parts of CRMF_poposigningkey_init() */ /* EVP_DigestSignInit() checks that pkey type is correct for the alg */ @@ -259,10 +259,8 @@ int ossl_cmp_msg_protect(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) goto err; } - if (msg->header->protectionAlg == NULL) - if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL) - goto err; - + if ((msg->header->protectionAlg = X509_ALGOR_new()) == NULL) + goto err; if (!OBJ_find_sigid_by_algs(&algNID, ctx->digest, EVP_PKEY_id(ctx->pkey))) { CMPerr(0, CMP_R_UNSUPPORTED_KEY_TYPE); diff --git a/crypto/cmp/cmp_server.c b/crypto/cmp/cmp_server.c index b805dc8b..8570885e 100644 --- a/crypto/cmp/cmp_server.c +++ b/crypto/cmp/cmp_server.c @@ -452,8 +452,10 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, const OSSL_CMP_MSG *req) { OSSL_CMP_CTX *ctx; + ASN1_OCTET_STRING *backup_secret; OSSL_CMP_PKIHEADER *hdr; int req_type, rsp_type; + int res; OSSL_CMP_MSG *rsp = NULL; if (srv_ctx == NULL || srv_ctx->ctx == NULL @@ -463,7 +465,12 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, return 0; } ctx = srv_ctx->ctx; + backup_secret = ctx->secretValue; + /* + * Some things need to be done already before validating the message in + * order to be able to send an error message as far as needed and possible. + */ if (hdr->sender->type != GEN_DIRNAME) { CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED); goto err; @@ -485,9 +492,10 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, tid = OPENSSL_buf2hexstr(ctx->transactionID->data, ctx->transactionID->length); - ossl_cmp_log1(WARN, ctx, - "Assuming that last transaction with ID=%s got aborted", - tid); + if (tid != NULL) + ossl_cmp_log1(WARN, ctx, + "Assuming that last transaction with ID=%s got aborted", + tid); OPENSSL_free(tid); } /* start of a new transaction, reset transactionID and senderNonce */ @@ -500,16 +508,17 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, if (ctx->transactionID == NULL) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION CMPerr(0, CMP_R_UNEXPECTED_PKIBODY); - /* ignore any (extra) error in next two function calls: */ - (void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID); - (void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce); goto err; #endif } } - if (ossl_cmp_msg_check_received(ctx, req, unprotected_exception, - srv_ctx->acceptUnprotected) < 0) + res = ossl_cmp_msg_check_update(ctx, req, unprotected_exception, + srv_ctx->acceptUnprotected); + if (ctx->secretValue != NULL && ctx->pkey != NULL + && ossl_cmp_hdr_get_protection_nid(hdr) != NID_id_PasswordBasedMAC) + ctx->secretValue = NULL; /* use MSG_SIG_ALG when protecting rsp */ + if (!res) goto err; switch (req_type) { @@ -568,16 +577,23 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, /* TODO fail_info could be more specific */ OSSL_CMP_PKISI *si = NULL; + if (ctx->transactionID == NULL) { + /* ignore any (extra) error in next two function calls: */ + (void)OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID); + (void)ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce); + } + if ((si = OSSL_CMP_STATUSINFO_new(OSSL_CMP_PKISTATUS_rejection, - fail_info, NULL)) == NULL) - return 0; - if (err != 0 && (flags & ERR_TXT_STRING) != 0) - data = ERR_reason_error_string(err); - rsp = ossl_cmp_error_new(srv_ctx->ctx, si, - err != 0 ? ERR_GET_REASON(err) : -1, - data, srv_ctx->sendUnprotectedErrors); - OSSL_CMP_PKISI_free(si); + fail_info, NULL)) != NULL) { + if (err != 0 && (flags & ERR_TXT_STRING) != 0) + data = ERR_reason_error_string(err); + rsp = ossl_cmp_error_new(srv_ctx->ctx, si, + err != 0 ? ERR_GET_REASON(err) : -1, + data, srv_ctx->sendUnprotectedErrors); + OSSL_CMP_PKISI_free(si); + } } + ctx->secretValue = backup_secret; /* possibly close the transaction */ rsp_type = diff --git a/crypto/cmp/cmp_vfy.c b/crypto/cmp/cmp_vfy.c index c124b063..c702b2ec 100644 --- a/crypto/cmp/cmp_vfy.c +++ b/crypto/cmp/cmp_vfy.c @@ -24,7 +24,7 @@ DEFINE_STACK_OF(X509) -/* +/*- * Verify a message protected by signature according to section 5.1.3.3 * (sha1+RSA/DSA or any other algorithm supported by OpenSSL). * @@ -70,7 +70,7 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx, prot_part_der_len = (size_t) len; /* verify signature of protected part */ - if (!OBJ_find_sigid_algs(OBJ_obj2nid(msg->header->protectionAlg->algorithm), + if (!OBJ_find_sigid_algs(ossl_cmp_hdr_get_protection_nid(msg->header), &digest_nid, &pk_nid) || digest_nid == NID_undef || pk_nid == NID_undef || (digest = EVP_get_digestbynid(digest_nid)) == NULL) { @@ -95,7 +95,7 @@ static int verify_signature(const OSSL_CMP_CTX *cmp_ctx, sig_err: res = x509_print_ex_brief(bio, cert, X509_FLAG_NO_EXTENSIONS); - CMPerr(0, CMP_R_ERROR_VALIDATING_PROTECTION); + CMPerr(0, CMP_R_ERROR_VALIDATING_SIGNATURE); if (res) ERR_add_error_mem_bio("\n", bio); res = 0; @@ -132,15 +132,15 @@ static int verify_PBMAC(const OSSL_CMP_MSG *msg, return valid; } -/* +/*- * Attempt to validate certificate and path using any given store with trusted * certs (possibly including CRLs and a cert verification callback function) * and non-trusted intermediate certs from the given ctx. * * Returns 1 on successful validation and 0 otherwise. */ -int OSSL_CMP_validate_cert_path(OSSL_CMP_CTX *ctx, X509_STORE *trusted_store, - X509 *cert) +int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx, + X509_STORE *trusted_store, X509 *cert) { int valid = 0; X509_STORE_CTX *csc = NULL; @@ -176,7 +176,7 @@ int OSSL_CMP_validate_cert_path(OSSL_CMP_CTX *ctx, X509_STORE *trusted_store, } /* Return 0 if expect_name != NULL and there is no matching actual_name */ -static int check_name(OSSL_CMP_CTX *ctx, +static int check_name(const OSSL_CMP_CTX *ctx, int log_success, const char *actual_desc, const X509_NAME *actual_name, const char *expect_desc, const X509_NAME *expect_name) { @@ -190,10 +190,16 @@ static int check_name(OSSL_CMP_CTX *ctx, ossl_cmp_log1(WARN, ctx, "missing %s", actual_desc); return 0; } - if (X509_NAME_cmp(actual_name, expect_name) == 0) + str = X509_NAME_oneline(actual_name, NULL, 0); + if (X509_NAME_cmp(actual_name, expect_name) == 0) { + if (log_success && str != NULL) + ossl_cmp_log2(INFO, ctx, " subject matches %s: %s", expect_desc, + str); + OPENSSL_free(str); return 1; + } - if ((str = X509_NAME_oneline(actual_name, NULL, 0)) != NULL) + if (str != NULL) ossl_cmp_log2(INFO, ctx, " actual name in %s = %s", actual_desc, str); OPENSSL_free(str); if ((str = X509_NAME_oneline(expect_name, NULL, 0)) != NULL) @@ -203,11 +209,11 @@ static int check_name(OSSL_CMP_CTX *ctx, } /* Return 0 if skid != NULL and there is no matching subject key ID in cert */ -static int check_kid(OSSL_CMP_CTX *ctx, - X509 *cert, const ASN1_OCTET_STRING *skid) +static int check_kid(const OSSL_CMP_CTX *ctx, + const ASN1_OCTET_STRING *ckid, + const ASN1_OCTET_STRING *skid) { - char *actual, *expect; - const ASN1_OCTET_STRING *ckid = X509_get0_subject_key_id(cert); + char *str; if (skid == NULL) return 1; /* no expectation, thus trivially fulfilled */ @@ -217,19 +223,25 @@ static int check_kid(OSSL_CMP_CTX *ctx, ossl_cmp_warn(ctx, "missing Subject Key Identifier in certificate"); return 0; } - if (ASN1_OCTET_STRING_cmp(ckid, skid) == 0) + str = OPENSSL_buf2hexstr(ckid->data, ckid->length); + if (ASN1_OCTET_STRING_cmp(ckid, skid) == 0) { + if (str != NULL) + ossl_cmp_log1(INFO, ctx, " subjectKID matches senderKID: %s", str); + OPENSSL_free(str); return 1; + } - if ((actual = OPENSSL_buf2hexstr(ckid->data, ckid->length)) != NULL) - ossl_cmp_log1(INFO, ctx, " cert Subject Key Identifier = %s", actual); - if ((expect = OPENSSL_buf2hexstr(skid->data, skid->length)) != NULL) - ossl_cmp_log1(INFO, ctx, " does not match senderKID = %s", expect); - OPENSSL_free(expect); - OPENSSL_free(actual); + if (str != NULL) + ossl_cmp_log1(INFO, ctx, " cert Subject Key Identifier = %s", str); + OPENSSL_free(str); + if ((str = OPENSSL_buf2hexstr(skid->data, skid->length)) != NULL) + ossl_cmp_log1(INFO, ctx, " does not match senderKID = %s", str); + OPENSSL_free(str); return 0; } -static int already_checked(X509 *cert, const STACK_OF(X509) *already_checked) +static int already_checked(const X509 *cert, + const STACK_OF(X509) *already_checked) { int i; @@ -239,7 +251,7 @@ static int already_checked(X509 *cert, const STACK_OF(X509) *already_checked) return 0; } -/* +/*- * Check if the given cert is acceptable as sender cert of the given message. * The subject DN must match, the subject key ID as well if present in the msg, * and the cert must be current (checked if ctx->trusted is not NULL). @@ -247,7 +259,7 @@ static int already_checked(X509 *cert, const STACK_OF(X509) *already_checked) * * Returns 0 on error or not acceptable, else 1. */ -static int cert_acceptable(OSSL_CMP_CTX *ctx, +static int cert_acceptable(const OSSL_CMP_CTX *ctx, const char *desc1, const char *desc2, X509 *cert, const STACK_OF(X509) *already_checked1, const STACK_OF(X509) *already_checked2, @@ -285,19 +297,19 @@ static int cert_acceptable(OSSL_CMP_CTX *ctx, return 0; } - if (!check_name(ctx, + if (!check_name(ctx, 1, "cert subject", X509_get_subject_name(cert), "sender field", msg->header->sender->d.directoryName)) return 0; - if (!check_kid(ctx, cert, msg->header->senderKID)) + if (!check_kid(ctx, X509_get0_subject_key_id(cert), msg->header->senderKID)) return 0; /* acceptable also if there is no senderKID in msg header */ ossl_cmp_info(ctx, " cert seems acceptable"); return 1; } -static int check_msg_valid_cert(OSSL_CMP_CTX *ctx, X509_STORE *store, +static int check_msg_valid_cert(const OSSL_CMP_CTX *ctx, X509_STORE *store, X509 *scrt, const OSSL_CMP_MSG *msg) { if (!verify_signature(ctx, msg, scrt)) { @@ -319,7 +331,7 @@ static int check_msg_valid_cert(OSSL_CMP_CTX *ctx, X509_STORE *store, * from extraCerts as trust anchor to validate sender cert and msg - * provided it also can validate the newly enrolled certificate */ -static int check_msg_valid_cert_3gpp(OSSL_CMP_CTX *ctx, X509 *scrt, +static int check_msg_valid_cert_3gpp(const OSSL_CMP_CTX *ctx, X509 *scrt, const OSSL_CMP_MSG *msg) { int valid = 0; @@ -361,11 +373,21 @@ static int check_msg_valid_cert_3gpp(OSSL_CMP_CTX *ctx, X509 *scrt, return valid; } -/* +static int check_msg_given_cert(const OSSL_CMP_CTX *ctx, X509 *cert, + const OSSL_CMP_MSG *msg) +{ + return cert_acceptable(ctx, "previously validated", "sender cert", + cert, NULL, NULL, msg) + && (check_msg_valid_cert(ctx, ctx->trusted, cert, msg) + || check_msg_valid_cert_3gpp(ctx, cert, msg)); +} + +/*- * Try all certs in given list for verifying msg, normally or in 3GPP mode. * If already_checked1 == NULL then certs are assumed to be the msg->extraCerts. + * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). */ -static int check_msg_with_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs, +static int check_msg_with_certs(OSSL_CMP_CTX *ctx, const STACK_OF(X509) *certs, const char *desc, const STACK_OF(X509) *already_checked1, const STACK_OF(X509) *already_checked2, @@ -406,9 +428,10 @@ static int check_msg_with_certs(OSSL_CMP_CTX *ctx, STACK_OF(X509) *certs, return 0; } -/* +/*- * Verify msg trying first ctx->untrusted_certs, which should include extraCerts * at its front, then trying the trusted certs in truststore (if any) of ctx. + * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). */ static int check_msg_all_certs(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, int mode_3gpp) @@ -451,7 +474,10 @@ static int no_log_cb(const char *func, const char *file, int line, return 1; } -/* verify message signature with any acceptable and valid candidate cert */ +/*- + * Verify message signature with any acceptable and valid candidate cert. + * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). + */ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) { X509 *scrt = ctx->validatedSrvCert; /* previous successful sender cert */ @@ -472,29 +498,28 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) /* dump any hitherto errors to avoid confusion when printing further ones */ OSSL_CMP_CTX_print_errors(ctx); + /* enable clearing irrelevant errors in attempts to validate sender certs */ + (void)ERR_set_mark(); + ctx->log_cb = no_log_cb; /* temporarily disable logging */ + /* * try first cached scrt, used successfully earlier in same transaction, * for validating this and any further msgs where extraCerts may be left out */ if (scrt != NULL) { - (void)ERR_set_mark(); - ossl_cmp_info(ctx, - "trying to verify msg signature with previously validated cert"); - if (cert_acceptable(ctx, "previously validated", "sender cert", scrt, - NULL, NULL, msg) - && (check_msg_valid_cert(ctx, ctx->trusted, scrt, msg) - || check_msg_valid_cert_3gpp(ctx, scrt, msg))) { + if (check_msg_given_cert(ctx, scrt, msg)) { + ctx->log_cb = backup_log_cb; (void)ERR_pop_to_mark(); return 1; } - (void)ERR_pop_to_mark(); /* cached sender cert has shown to be no more successfully usable */ (void)ossl_cmp_ctx_set0_validatedSrvCert(ctx, NULL); + /* re-do the above check (just) for adding diagnostic information */ + ossl_cmp_info(ctx, + "trying to verify msg signature with previously validated cert"); + (void)check_msg_given_cert(ctx, scrt, msg); } - /* enable clearing irrelevant errors in attempts to validate sender certs */ - (void)ERR_set_mark(); - ctx->log_cb = no_log_cb; /* temporarily disable logging */ res = check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */) || check_msg_all_certs(ctx, msg, 1 /* 3gpp */); ctx->log_cb = backup_log_cb; @@ -518,8 +543,8 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) else ossl_cmp_info(ctx, "while msg header does not contain senderKID"); /* re-do the above checks (just) for adding diagnostic information */ - check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */); - check_msg_all_certs(ctx, msg, 1 /* 3gpp */); + (void)check_msg_all_certs(ctx, msg, 0 /* using ctx->trusted */); + (void)check_msg_all_certs(ctx, msg, 1 /* 3gpp */); } CMPerr(0, CMP_R_NO_SUITABLE_SENDER_CERT); @@ -538,12 +563,13 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) return res; } -/* +/*- * Validate the protection of the given PKIMessage using either password- * based mac (PBM) or a signature algorithm. In the case of signature algorithm, * the sender certificate can have been pinned by providing it in ctx->srvCert, * else it is searched in msg->extraCerts, ctx->untrusted_certs, in ctx->trusted * (in this order) and is path is validated against ctx->trusted. + * On success cache the found cert using ossl_cmp_ctx_set0_validatedSrvCert(). * * If ctx->permitTAInExtraCertsForIR is true and when validating a CMP IP msg, * the trust anchor for validating the IP msg may be taken from msg->extraCerts @@ -555,9 +581,6 @@ static int check_msg_find_cert(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) */ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) { - X509_ALGOR *alg; - int nid = NID_undef, pk_nid = NID_undef; - const ASN1_OBJECT *algorOID = NULL; X509 *scrt; if (ctx == NULL || msg == NULL @@ -566,17 +589,13 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) return 0; } - if ((alg = msg->header->protectionAlg) == NULL /* unprotected message */ + if (msg->header->protectionAlg == NULL /* unprotected message */ || msg->protection == NULL || msg->protection->data == NULL) { CMPerr(0, CMP_R_MISSING_PROTECTION); return 0; } - /* determine the nid for the used protection algorithm */ - X509_ALGOR_get0(&algorOID, NULL, NULL, alg); - nid = OBJ_obj2nid(algorOID); - - switch (nid) { + switch (ossl_cmp_hdr_get_protection_nid(msg->header)) { /* 5.1.3.1. Shared Secret Information */ case NID_id_PasswordBasedMAC: if (ctx->secretValue == 0) { @@ -584,34 +603,8 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) break; } - if (verify_PBMAC(msg, ctx->secretValue)) { - /* - * RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is - * "shared secret information", then any certificate transported in - * the caPubs field may be directly trusted as a root CA - * certificate by the initiator.' - */ - switch (ossl_cmp_msg_get_bodytype(msg)) { - case -1: - return 0; - case OSSL_CMP_PKIBODY_IP: - case OSSL_CMP_PKIBODY_CP: - case OSSL_CMP_PKIBODY_KUP: - case OSSL_CMP_PKIBODY_CCP: - if (ctx->trusted != NULL) { - STACK_OF(X509) *certs = msg->body->value.ip->caPubs; - /* value.ip is same for cp, kup, and ccp */ - - if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0)) - /* adds both self-issued and not self-issued certs */ - return 0; - } - break; - default: - break; - } + if (verify_PBMAC(msg, ctx->secretValue)) return 1; - } break; /* @@ -626,28 +619,6 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) * 5.1.3.3. Signature */ default: - if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), NULL, &pk_nid) - || pk_nid == NID_undef) { - CMPerr(0, CMP_R_UNKNOWN_ALGORITHM_ID); - break; - } - /* validate sender name of received msg */ - if (msg->header->sender->type != GEN_DIRNAME) { - CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED); - break; /* FR#42: support for more than X509_NAME */ - } - /* - * Compare actual sender name of response with expected sender name. - * Expected name can be set explicitly or the subject of ctx->srvCert. - * Mitigates risk to accept misused certificate of an unauthorized - * entity of a trusted hierarchy. - */ - if (!check_name(ctx, "sender DN field", - msg->header->sender->d.directoryName, - "expected sender", ctx->expected_sender)) - break; - /* Note: if recipient was NULL-DN it could be learned here if needed */ - scrt = ctx->srvCert; if (scrt == NULL) { if (check_msg_find_cert(ctx, msg)) @@ -656,9 +627,6 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) /* use ctx->srvCert for signature check even if not acceptable */ if (verify_signature(ctx, msg, scrt)) return 1; - /* call cert_acceptable() for adding diagnostic information */ - (void)cert_acceptable(ctx, "explicitly set", "sender cert", scrt, - NULL, NULL, msg); ossl_cmp_warn(ctx, "msg signature verification failed"); CMPerr(0, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG); } @@ -670,9 +638,11 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) /*- * Check received message (i.e., response by server or request from client) - * Any msg->extraCerts are prepended to ctx->untrusted_certs + * Any msg->extraCerts are prepended to ctx->untrusted_certs. * * Ensures that: + * its sender is of appropriate type (curently only X509_NAME) and + * matches any expected sender or srvCert subject given in the ctx * it has a valid body type * its protection is valid (or invalid/absent, but only if a callback function * is present and yields a positive result using also the supplied argument) @@ -681,30 +651,63 @@ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg) * * If everything is fine: * learns the senderNonce from the received message, - * learns the transaction ID if it is not yet in ctx. + * learns the transaction ID if it is not yet in ctx, + * and makes any certs in caPubs directly trusted. * - * returns body type (which is >= 0) of the message on success, -1 on error + * Returns 1 on success, 0 on error. */ -int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, - ossl_cmp_allow_unprotected_cb_t cb, int cb_arg) +int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, + ossl_cmp_allow_unprotected_cb_t cb, int cb_arg) { - int rcvd_type; + OSSL_CMP_PKIHEADER *hdr; + const X509_NAME *expected_sender; - if (!ossl_assert(ctx != NULL && msg != NULL)) - return -1; + if (!ossl_assert(ctx != NULL && msg != NULL && msg->header != NULL)) + return 0; + hdr = OSSL_CMP_MSG_get0_header(msg); + + /* validate sender name of received msg */ + if (hdr->sender->type != GEN_DIRNAME) { + CMPerr(0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED); + return 0; /* TODO FR#42: support for more than X509_NAME */ + } + /* + * Compare actual sender name of response with expected sender name. + * Mitigates risk to accept misused PBM secret + * or misused certificate of an unauthorized entity of a trusted hierarchy. + */ + expected_sender = ctx->expected_sender; + if (expected_sender == NULL && ctx->srvCert != NULL) + expected_sender = X509_get_subject_name(ctx->srvCert); + if (!check_name(ctx, 0, "sender DN field", hdr->sender->d.directoryName, + "expected sender", expected_sender)) + return 0; + /* Note: if recipient was NULL-DN it could be learned here if needed */ if (sk_X509_num(msg->extraCerts) > 10) ossl_cmp_warn(ctx, "received CMP message contains more than 10 extraCerts"); + /* + * Store any provided extraCerts in ctx for use in OSSL_CMP_validate_msg() + * and for future use, such that they are available to ctx->certConf_cb and + * the peer does not need to send them again in the same transaction. + * Note that it does not help validating the message before storing the + * extraCerts because they do not belong to the protected msg part anyway. + * For efficiency, the extraCerts are prepended so they get used first. + */ + if (!ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, msg->extraCerts, + 0 /* this allows self-issued certs */, + 1 /* no_dups */, 1 /* prepend */)) + return 0; /* validate message protection */ - if (msg->header->protectionAlg != 0) { + if (hdr->protectionAlg != NULL) { /* detect explicitly permitted exceptions for invalid protection */ if (!OSSL_CMP_validate_msg(ctx, msg) && (cb == NULL || (*cb)(ctx, msg, 1, cb_arg) <= 0)) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION CMPerr(0, CMP_R_ERROR_VALIDATING_PROTECTION); - return -1; + return 0; #endif } } else { @@ -712,34 +715,34 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, if (cb == NULL || (*cb)(ctx, msg, 0, cb_arg) <= 0) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION CMPerr(0, CMP_R_MISSING_PROTECTION); - return -1; + return 0; #endif } } /* check CMP version number in header */ - if (ossl_cmp_hdr_get_pvno(OSSL_CMP_MSG_get0_header(msg)) != OSSL_CMP_PVNO) { + if (ossl_cmp_hdr_get_pvno(hdr) != OSSL_CMP_PVNO) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION CMPerr(0, CMP_R_UNEXPECTED_PVNO); - return -1; + return 0; #endif } - if ((rcvd_type = ossl_cmp_msg_get_bodytype(msg)) < 0) { + if (ossl_cmp_msg_get_bodytype(msg) < 0) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION CMPerr(0, CMP_R_PKIBODY_ERROR); - return -1; + return 0; #endif } /* compare received transactionID with the expected one in previous msg */ if (ctx->transactionID != NULL - && (msg->header->transactionID == NULL + && (hdr->transactionID == NULL || ASN1_OCTET_STRING_cmp(ctx->transactionID, - msg->header->transactionID) != 0)) { + hdr->transactionID) != 0)) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION CMPerr(0, CMP_R_TRANSACTIONID_UNMATCHED); - return -1; + return 0; #endif } @@ -747,10 +750,10 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, if (ctx->senderNonce != NULL && (msg->header->recipNonce == NULL || ASN1_OCTET_STRING_cmp(ctx->senderNonce, - msg->header->recipNonce) != 0)) { + hdr->recipNonce) != 0)) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION CMPerr(0, CMP_R_RECIPNONCE_UNMATCHED); - return -1; + return 0; #endif } @@ -759,26 +762,40 @@ int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, * the senderNonce of the previous message in the transaction. * --> Store for setting in next message */ - if (!ossl_cmp_ctx_set1_recipNonce(ctx, msg->header->senderNonce)) - return -1; + if (!ossl_cmp_ctx_set1_recipNonce(ctx, hdr->senderNonce)) + return 0; /* if not yet present, learn transactionID */ if (ctx->transactionID == NULL - && !OSSL_CMP_CTX_set1_transactionID(ctx, msg->header->transactionID)) - return -1; + && !OSSL_CMP_CTX_set1_transactionID(ctx, hdr->transactionID)) + return 0; - /* - * Store any provided extraCerts in ctx for future use, - * such that they are available to ctx->certConf_cb and - * the peer does not need to send them again in the same transaction. - * For efficiency, the extraCerts are prepended so they get used first. - */ - if (!ossl_cmp_sk_X509_add1_certs(ctx->untrusted_certs, msg->extraCerts, - 0 /* this allows self-issued certs */, - 1 /* no_dups */, 1 /* prepend */)) - return -1; + if (ossl_cmp_hdr_get_protection_nid(hdr) == NID_id_PasswordBasedMAC) { + /* + * RFC 4210, 5.3.2: 'Note that if the PKI Message Protection is + * "shared secret information", then any certificate transported in + * the caPubs field may be directly trusted as a root CA + * certificate by the initiator.' + */ + switch (ossl_cmp_msg_get_bodytype(msg)) { + case OSSL_CMP_PKIBODY_IP: + case OSSL_CMP_PKIBODY_CP: + case OSSL_CMP_PKIBODY_KUP: + case OSSL_CMP_PKIBODY_CCP: + if (ctx->trusted != NULL) { + STACK_OF(X509) *certs = msg->body->value.ip->caPubs; + /* value.ip is same for cp, kup, and ccp */ - return rcvd_type; + if (!ossl_cmp_X509_STORE_add1_certs(ctx->trusted, certs, 0)) + /* adds both self-issued and not self-issued certs */ + return 0; + } + break; + default: + break; + } + } + return 1; } int ossl_cmp_verify_popo(const OSSL_CMP_MSG *msg, int accept_RAVerified) diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c index 526d7735..16e25afc 100644 --- a/crypto/cms/cms_err.c +++ b/crypto/cms/cms_err.c @@ -52,6 +52,10 @@ static const ERR_STRING_DATA CMS_str_reasons[] = { {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_KEY), "error setting key"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_RECIPIENTINFO), "error setting recipientinfo"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE), + "ess no signing certid attribute"}, + {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR), + "ess signing certid mismatch error"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH), "invalid encrypted key length"}, {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER), diff --git a/crypto/cms/cms_ess.c b/crypto/cms/cms_ess.c index 39010740..e3604f7d 100644 --- a/crypto/cms/cms_ess.c +++ b/crypto/cms/cms_ess.c @@ -21,6 +21,9 @@ DEFINE_STACK_OF(GENERAL_NAMES) DEFINE_STACK_OF(CMS_SignerInfo) +DEFINE_STACK_OF(ESS_CERT_ID) +DEFINE_STACK_OF(ESS_CERT_ID_V2) +DEFINE_STACK_OF(X509) IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) @@ -29,33 +32,100 @@ IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr) { ASN1_STRING *str; - CMS_ReceiptRequest *rr = NULL; - if (prr) + CMS_ReceiptRequest *rr; + ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_receiptRequest); + + if (prr != NULL) *prr = NULL; - str = CMS_signed_get0_data_by_OBJ(si, - OBJ_nid2obj - (NID_id_smime_aa_receiptRequest), -3, - V_ASN1_SEQUENCE); - if (!str) + str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE); + if (str == NULL) return 0; rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest)); - if (!rr) + if (rr == NULL) return -1; - if (prr) + if (prr != NULL) *prr = rr; else CMS_ReceiptRequest_free(rr); return 1; } +/* + First, get the ESS_SIGNING_CERT(V2) signed attribute from |si|. + Then check matching of each cert of trust |chain| with one of + the |cert_ids|(Hash+IssuerID) list from this ESS_SIGNING_CERT. + Derived from ts_check_signing_certs() +*/ +int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain) +{ + ESS_SIGNING_CERT *ss = NULL; + ESS_SIGNING_CERT_V2 *ssv2 = NULL; + X509 *cert; + int i = 0, ret = 0; + + if (cms_signerinfo_get_signing_cert(si, &ss) > 0 && ss->cert_ids != NULL) { + STACK_OF(ESS_CERT_ID) *cert_ids = ss->cert_ids; + + cert = sk_X509_value(chain, 0); + if (ess_find_cert(cert_ids, cert) != 0) + goto err; + + /* + * Check the other certificates of the chain. + * Fail if no signing certificate ids found for each certificate. + */ + if (sk_ESS_CERT_ID_num(cert_ids) > 1) { + /* for each chain cert, try to find its cert id */ + for (i = 1; i < sk_X509_num(chain); ++i) { + cert = sk_X509_value(chain, i); + if (ess_find_cert(cert_ids, cert) < 0) + goto err; + } + } + } else if (cms_signerinfo_get_signing_cert_v2(si, &ssv2) > 0 + && ssv2->cert_ids!= NULL) { + STACK_OF(ESS_CERT_ID_V2) *cert_ids_v2 = ssv2->cert_ids; + + cert = sk_X509_value(chain, 0); + if (ess_find_cert_v2(cert_ids_v2, cert) != 0) + goto err; + + /* + * Check the other certificates of the chain. + * Fail if no signing certificate ids found for each certificate. + */ + if (sk_ESS_CERT_ID_V2_num(cert_ids_v2) > 1) { + /* for each chain cert, try to find its cert id */ + for (i = 1; i < sk_X509_num(chain); ++i) { + cert = sk_X509_value(chain, i); + if (ess_find_cert_v2(cert_ids_v2, cert) < 0) + goto err; + } + } + } else { + CMSerr(CMS_F_ESS_CHECK_SIGNING_CERTS, + CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE); + return 0; + } + ret = 1; + err: + if (!ret) + CMSerr(CMS_F_ESS_CHECK_SIGNING_CERTS, + CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR); + + ESS_SIGNING_CERT_free(ss); + ESS_SIGNING_CERT_V2_free(ssv2); + return ret; +} + CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, int allorfirst, STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo) { - CMS_ReceiptRequest *rr = NULL; + CMS_ReceiptRequest *rr; rr = CMS_ReceiptRequest_new(); if (rr == NULL) @@ -145,6 +215,7 @@ static int cms_msgSigDigest(CMS_SignerInfo *si, unsigned char *dig, unsigned int *diglen) { const EVP_MD *md; + md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); if (md == NULL) return 0; @@ -160,6 +231,7 @@ int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) { unsigned char dig[EVP_MAX_MD_SIZE]; unsigned int diglen; + if (!cms_msgSigDigest(src, dig, &diglen)) { CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR); return 0; diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h index 00ea9006..68c88562 100644 --- a/crypto/cms/cms_local.h +++ b/crypto/cms/cms_local.h @@ -421,6 +421,9 @@ int cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, CMS_RecipientInfo * /* SignerInfo routines */ int CMS_si_check_attributes(const CMS_SignerInfo *si); +/* ESS routines */ +int ess_check_signing_certs(CMS_SignerInfo *si, STACK_OF(X509) *chain); + DECLARE_ASN1_ITEM(CMS_CertificateChoices) DECLARE_ASN1_ITEM(CMS_DigestedData) DECLARE_ASN1_ITEM(CMS_EncryptedData) diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c index dbdc815e..a83edce0 100644 --- a/crypto/cms/cms_smime.c +++ b/crypto/cms/cms_smime.c @@ -233,7 +233,8 @@ CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, X509_STORE *store, STACK_OF(X509) *certs, - STACK_OF(X509_CRL) *crls) + STACK_OF(X509_CRL) *crls, + STACK_OF(X509) **chain) { X509_STORE_CTX *ctx = X509_STORE_CTX_new(); X509 *signer; @@ -262,6 +263,10 @@ static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, goto err; } r = 1; + + /* also send back the trust chain when required */ + if (chain != NULL) + *chain = X509_STORE_CTX_get1_chain(ctx); err: X509_STORE_CTX_free(ctx); return r; @@ -275,9 +280,11 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, STACK_OF(CMS_SignerInfo) *sinfos; STACK_OF(X509) *cms_certs = NULL; STACK_OF(X509_CRL) *crls = NULL; + STACK_OF(X509) **si_chains = NULL; X509 *signer; int i, scount = 0, ret = 0; BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL; + int cadesVerify = (flags & CMS_CADES) != 0; if (!dcont && !check_content(cms)) return 0; @@ -312,27 +319,44 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, } /* Attempt to verify all signers certs */ + /* at this point scount == sk_CMS_SignerInfo_num(sinfos) */ - if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) { + if ((flags & CMS_NO_SIGNER_CERT_VERIFY) == 0 || cadesVerify) { + if (cadesVerify) { + /* Certificate trust chain is required to check CAdES signature */ + si_chains = OPENSSL_zalloc(scount * sizeof(si_chains[0])); + if (si_chains == NULL) { + CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + } cms_certs = CMS_get1_certs(cms); if (!(flags & CMS_NOCRL)) crls = CMS_get1_crls(cms); - for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + for (i = 0; i < scount; i++) { si = sk_CMS_SignerInfo_value(sinfos, i); - if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls)) + + if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls, + si_chains ? &si_chains[i] : NULL)) goto err; } } /* Attempt to verify all SignerInfo signed attribute signatures */ - if (!(flags & CMS_NO_ATTR_VERIFY)) { - for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + if ((flags & CMS_NO_ATTR_VERIFY) == 0 || cadesVerify) { + for (i = 0; i < scount; i++) { si = sk_CMS_SignerInfo_value(sinfos, i); if (CMS_signed_get_attr_count(si) < 0) continue; if (CMS_SignerInfo_verify(si) <= 0) goto err; + if (cadesVerify) { + STACK_OF(X509) *si_chain = si_chains ? si_chains[i] : NULL; + + if (ess_check_signing_certs(si, si_chain) <= 0) + goto err; + } } } @@ -420,6 +444,11 @@ int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, BIO_free_all(tmpout); err2: + if (si_chains != NULL) { + for (i = 0; i < scount; ++i) + sk_X509_pop_free(si_chains[i], X509_free); + OPENSSL_free(si_chains); + } sk_X509_pop_free(cms_certs, X509_free); sk_X509_CRL_pop_free(crls, X509_CRL_free); diff --git a/crypto/conf/conf_mod.c b/crypto/conf/conf_mod.c index 504d9b18..9d3db8eb 100644 --- a/crypto/conf/conf_mod.c +++ b/crypto/conf/conf_mod.c @@ -516,25 +516,23 @@ void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data) char *CONF_get1_default_config_file(void) { + const char *t; char *file, *sep = ""; - int len; + size_t size; if ((file = ossl_safe_getenv("OPENSSL_CONF")) != NULL) return OPENSSL_strdup(file); - len = strlen(X509_get_default_cert_area()); + t = X509_get_default_cert_area(); #ifndef OPENSSL_SYS_VMS - len++; sep = "/"; #endif - len += strlen(OPENSSL_CONF); - - file = OPENSSL_malloc(len + 1); + size = strlen(t) + strlen(sep) + strlen(OPENSSL_CONF) + 1; + file = OPENSSL_malloc(size); if (file == NULL) return NULL; - BIO_snprintf(file, len + 1, "%s%s%s", X509_get_default_cert_area(), - sep, OPENSSL_CONF); + BIO_snprintf(file, size, "%s%s%s", t, sep, OPENSSL_CONF); return file; } diff --git a/crypto/core_algorithm.c b/crypto/core_algorithm.c index 79625fde..f2e0e06f 100644 --- a/crypto/core_algorithm.c +++ b/crypto/core_algorithm.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -16,8 +16,11 @@ struct algorithm_data_st { OPENSSL_CTX *libctx; int operation_id; /* May be zero for finding them all */ + int (*pre)(OSSL_PROVIDER *, int operation_id, void *data, int *result); void (*fn)(OSSL_PROVIDER *, const OSSL_ALGORITHM *, int no_store, void *data); + int (*post)(OSSL_PROVIDER *, int operation_id, int no_store, void *data, + int *result); void *data; }; @@ -36,19 +39,48 @@ static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata) for (cur_operation = first_operation; cur_operation <= last_operation; cur_operation++) { - const OSSL_ALGORITHM *map = - ossl_provider_query_operation(provider, cur_operation, - &no_store); + const OSSL_ALGORITHM *map = NULL; + int ret; + /* Do we fulfill pre-conditions? */ + if (data->pre == NULL) { + /* If there is no pre-condition function, assume "yes" */ + ret = 1; + } else { + if (!data->pre(provider, cur_operation, data->data, &ret)) + /* Error, bail out! */ + return 0; + } + + /* If pre-condition not fulfilled, go to the next operation */ + if (!ret) + continue; + + map = ossl_provider_query_operation(provider, cur_operation, + &no_store); if (map == NULL) continue; - ok = 1; /* As long as we've found *something* */ while (map->algorithm_names != NULL) { const OSSL_ALGORITHM *thismap = map++; data->fn(provider, thismap, no_store, data->data); } + + /* Do we fulfill post-conditions? */ + if (data->post == NULL) { + /* If there is no post-condition function, assume "yes" */ + ret = 1; + } else { + if (!data->post(provider, cur_operation, no_store, data->data, + &ret)) + /* Error, bail out! */ + return 0; + } + + /* If post-condition fulfilled, set general success */ + if (ret) + ok = 1; } return ok; @@ -56,16 +88,22 @@ static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata) void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id, OSSL_PROVIDER *provider, + int (*pre)(OSSL_PROVIDER *, int operation_id, + void *data, int *result), void (*fn)(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo, int no_store, void *data), + int (*post)(OSSL_PROVIDER *, int operation_id, + int no_store, void *data, int *result), void *data) { - struct algorithm_data_st cbdata; + struct algorithm_data_st cbdata = { 0, }; cbdata.libctx = libctx; cbdata.operation_id = operation_id; + cbdata.pre = pre; cbdata.fn = fn; + cbdata.post = post; cbdata.data = data; if (provider == NULL) diff --git a/crypto/core_fetch.c b/crypto/core_fetch.c index 7f815a50..89a44ddb 100644 --- a/crypto/core_fetch.c +++ b/crypto/core_fetch.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -24,6 +24,42 @@ struct construct_data_st { void *mcm_data; }; +static int ossl_method_construct_precondition(OSSL_PROVIDER *provider, + int operation_id, void *cbdata, + int *result) +{ + if (!ossl_assert(result != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!ossl_provider_test_operation_bit(provider, operation_id, result)) + return 0; + + /* + * The result we get tells if methods have already been constructed. + * However, we want to tell whether construction should happen (true) + * or not (false), which is the opposite of what we got. + */ + *result = !*result; + + return 1; +} + +static int ossl_method_construct_postcondition(OSSL_PROVIDER *provider, + int operation_id, int no_store, + void *cbdata, int *result) +{ + if (!ossl_assert(result != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + *result = 1; + return no_store != 0 + || ossl_provider_set_operation_bit(provider, operation_id); +} + static void ossl_method_construct_this(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo, int no_store, void *cbdata) @@ -86,7 +122,10 @@ void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id, cbdata.mcm = mcm; cbdata.mcm_data = mcm_data; ossl_algorithm_do_all(libctx, operation_id, NULL, - ossl_method_construct_this, &cbdata); + ossl_method_construct_precondition, + ossl_method_construct_this, + ossl_method_construct_postcondition, + &cbdata); method = mcm->get(libctx, cbdata.store, mcm_data); mcm->dealloc_tmp_store(cbdata.store); diff --git a/crypto/crmf/crmf_lib.c b/crypto/crmf/crmf_lib.c index 89eb2c37..c20a6da0 100644 --- a/crypto/crmf/crmf_lib.c +++ b/crypto/crmf/crmf_lib.c @@ -461,25 +461,6 @@ int OSSL_CRMF_MSG_create_popo(OSSL_CRMF_MSG *crm, EVP_PKEY *pkey, return 0; } -/* returns 0 for equal, -1 for a < b or error on a, 1 for a > b or error on b */ -static int X509_PUBKEY_cmp(X509_PUBKEY *a, X509_PUBKEY *b) -{ - X509_ALGOR *algA = NULL, *algB = NULL; - int res = 0; - - if (a == b) - return 0; - if (a == NULL || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algA, a) - || algA == NULL) - return -1; - if (b == NULL || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algB, b) - || algB == NULL) - return 1; - if ((res = X509_ALGOR_cmp(algA, algB)) != 0) - return res; - return EVP_PKEY_cmp(X509_PUBKEY_get0(a), X509_PUBKEY_get0(b)); -} - /* verifies the Proof-of-Possession of the request with the given rid in reqs */ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, int rid, int acceptRAVerified) @@ -522,7 +503,7 @@ int OSSL_CRMF_MSGS_verify_popo(const OSSL_CRMF_MSGS *reqs, CRMFerr(0, CRMF_R_POPO_MISSING_PUBLIC_KEY); return 0; } - if (X509_PUBKEY_cmp(pubkey, sig->poposkInput->publicKey) != 0) { + if (X509_PUBKEY_eq(pubkey, sig->poposkInput->publicKey) != 1) { CRMFerr(0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY); return 0; } diff --git a/crypto/crmf/crmf_local.h b/crypto/crmf/crmf_local.h index a367d777..b4d66987 100644 --- a/crypto/crmf/crmf_local.h +++ b/crypto/crmf/crmf_local.h @@ -108,7 +108,6 @@ struct ossl_crmf_certid_st { GENERAL_NAME *issuer; ASN1_INTEGER *serialNumber; } /* OSSL_CRMF_CERTID */; -DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID) /*- * SinglePubInfo ::= SEQUENCE { diff --git a/crypto/crmf/crmf_pbm.c b/crypto/crmf/crmf_pbm.c index f674eeef..a087bc44 100644 --- a/crypto/crmf/crmf_pbm.c +++ b/crypto/crmf/crmf_pbm.c @@ -202,8 +202,8 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, macparams[1] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, basekey, bklen); if ((mac = EVP_MAC_fetch(NULL, "HMAC", NULL)) == NULL - || (mctx = EVP_MAC_CTX_new(mac)) == NULL - || !EVP_MAC_CTX_set_params(mctx, macparams) + || (mctx = EVP_MAC_new_ctx(mac)) == NULL + || !EVP_MAC_set_ctx_params(mctx, macparams) || !EVP_MAC_init(mctx) || !EVP_MAC_update(mctx, msg, msglen) || !EVP_MAC_final(mctx, mac_res, outlen, EVP_MAX_MD_SIZE)) @@ -214,7 +214,7 @@ int OSSL_CRMF_pbm_new(const OSSL_CRMF_PBMPARAMETER *pbmp, err: /* cleanup */ OPENSSL_cleanse(basekey, bklen); - EVP_MAC_CTX_free(mctx); + EVP_MAC_free_ctx(mctx); EVP_MAC_free(mac); EVP_MD_CTX_free(ctx); diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c index e76b655f..d5e5f725 100644 --- a/crypto/dh/dh_ameth.c +++ b/crypto/dh/dh_ameth.c @@ -52,7 +52,7 @@ static void int_dh_free(EVP_PKEY *pkey) DH_free(pkey->pkey.dh); } -static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +static int dh_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) { const unsigned char *p, *pm; int pklen, pmlen; @@ -438,7 +438,7 @@ static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: return dh_buf2key(EVP_PKEY_get0_DH(pkey), arg2, arg1); case ASN1_PKEY_CTRL_GET1_TLS_ENCPT: - return dh_key2buf(EVP_PKEY_get0_DH(pkey), arg2); + return dh_key2buf(EVP_PKEY_get0_DH(pkey), arg2, 0, 1); default: return -2; } diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c index e5eb3238..a8243ec9 100644 --- a/crypto/dh/dh_err.c +++ b/crypto/dh/dh_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,6 +14,7 @@ #ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA DH_str_reasons[] = { + {ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_FFC_PARAMETERS), "bad ffc parameters"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR), "bad generator"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_DECODE_ERROR), "bn decode error"}, {ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_ERROR), "bn error"}, diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c index 327f6ff6..8c1518ad 100644 --- a/crypto/dh/dh_gen.c +++ b/crypto/dh/dh_gen.c @@ -68,7 +68,7 @@ int dh_get_named_group_uid_from_size(int pbits) * Just choose an approved safe prime group. * The alternative to this is to generate FIPS186-4 domain parameters i.e. * return dh_generate_ffc_parameters(ret, prime_len, 0, NULL, cb); - * As the FIPS186-4 generated params are for backwards compatability, + * As the FIPS186-4 generated params are for backwards compatibility, * the safe prime group should be used as the default. */ int nid; diff --git a/crypto/dh/dh_kdf.c b/crypto/dh/dh_kdf.c index 1b8a320d..50a1df85 100644 --- a/crypto/dh/dh_kdf.c +++ b/crypto/dh/dh_kdf.c @@ -46,7 +46,7 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen, return 0; kdf = EVP_KDF_fetch(provctx, OSSL_KDF_NAME_X942KDF, NULL); - if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL) + if ((kctx = EVP_KDF_new_ctx(kdf)) == NULL) goto err; *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (char *)mdname, 0); @@ -58,10 +58,10 @@ int DH_KDF_X9_42(unsigned char *out, size_t outlen, *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CEK_ALG, (char *)oid_sn, 0); *p = OSSL_PARAM_construct_end(); - ret = EVP_KDF_CTX_set_params(kctx, params) > 0 + ret = EVP_KDF_set_ctx_params(kctx, params) > 0 && EVP_KDF_derive(kctx, out, outlen) > 0; err: - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); EVP_KDF_free(kdf); return ret; } diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index 1893b487..5d2acca2 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -351,10 +351,10 @@ err: return 0; } -size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out) +size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out, size_t size, int alloc) { const BIGNUM *pubkey; - unsigned char *pbuf; + unsigned char *pbuf = NULL; const BIGNUM *p; int p_size; @@ -366,19 +366,29 @@ size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out) DHerr(DH_F_DH_KEY2BUF, DH_R_INVALID_PUBKEY); return 0; } - if ((pbuf = OPENSSL_malloc(p_size)) == NULL) { - DHerr(DH_F_DH_KEY2BUF, ERR_R_MALLOC_FAILURE); - return 0; + if (pbuf_out != NULL && (alloc || *pbuf_out != NULL)) { + if (!alloc) { + if (size >= (size_t)p_size) + pbuf = *pbuf_out; + } else { + pbuf = OPENSSL_malloc(p_size); + } + + if (pbuf == NULL) { + DHerr(DH_F_DH_KEY2BUF, ERR_R_MALLOC_FAILURE); + return 0; + } + /* + * As per Section 4.2.8.1 of RFC 8446 left pad public + * key with zeros to the size of p + */ + if (BN_bn2binpad(pubkey, pbuf, p_size) < 0) { + if (alloc) + OPENSSL_free(pbuf); + DHerr(DH_F_DH_KEY2BUF, DH_R_BN_ERROR); + return 0; + } + *pbuf_out = pbuf; } - /* - * As per Section 4.2.8.1 of RFC 8446 left pad public - * key with zeros to the size of p - */ - if (BN_bn2binpad(pubkey, pbuf, p_size) < 0) { - OPENSSL_free(pbuf); - DHerr(DH_F_DH_KEY2BUF, DH_R_BN_ERROR); - return 0; - } - *pbuf_out = pbuf; return p_size; } diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c index c3585f26..3a523c35 100644 --- a/crypto/dh/dh_lib.c +++ b/crypto/dh/dh_lib.c @@ -475,7 +475,7 @@ int EVP_PKEY_CTX_set_dh_paramgen_generator(EVP_PKEY_CTX *ctx, int gen) EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL); #endif - *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_FFC_GENERATOR, &gen); + *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_DH_GENERATOR, &gen); *p++ = OSSL_PARAM_construct_end(); return EVP_PKEY_CTX_set_params(ctx, params); @@ -500,7 +500,7 @@ int EVP_PKEY_CTX_set_dh_rfc5114(EVP_PKEY_CTX *ctx, int gen) if (name == NULL) return 0; - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_GROUP, + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DH_GROUP, (void *)name, 0); *p++ = OSSL_PARAM_construct_end(); return EVP_PKEY_CTX_set_params(ctx, params); @@ -531,7 +531,7 @@ int EVP_PKEY_CTX_set_dh_nid(EVP_PKEY_CTX *ctx, int nid) if (name == NULL) return 0; - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_FFC_GROUP, + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DH_GROUP, (void *)name, 0); *p++ = OSSL_PARAM_construct_end(); return EVP_PKEY_CTX_set_params(ctx, params); diff --git a/crypto/dh/dh_local.h b/crypto/dh/dh_local.h index a54d25f4..51c3f974 100644 --- a/crypto/dh/dh_local.h +++ b/crypto/dh/dh_local.h @@ -58,6 +58,3 @@ struct dh_method { int (*generate_params) (DH *dh, int prime_len, int generator, BN_GENCB *cb); }; - -int dh_buf2key(DH *key, const unsigned char *buf, size_t len); -size_t dh_key2buf(const DH *dh, unsigned char **pbuf); diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index f74b50ee..651b4632 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -27,7 +27,7 @@ #include "internal/ffc.h" #include "dsa_local.h" -static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +static int dsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) { const unsigned char *p, *pm; int pklen, pmlen; diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c index f4d187e4..6bf7acca 100644 --- a/crypto/dsa/dsa_err.c +++ b/crypto/dsa/dsa_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,6 +14,7 @@ #ifndef OPENSSL_NO_ERR static const ERR_STRING_DATA DSA_str_reasons[] = { + {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BAD_FFC_PARAMETERS), "bad ffc parameters"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BAD_Q_VALUE), "bad q value"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BN_DECODE_ERROR), "bn decode error"}, {ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BN_ERROR), "bn error"}, diff --git a/crypto/dsa/dsa_pmeth.c b/crypto/dsa/dsa_pmeth.c index 750d0168..7f7f57f6 100644 --- a/crypto/dsa/dsa_pmeth.c +++ b/crypto/dsa/dsa_pmeth.c @@ -221,7 +221,7 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) dctx->nbits, dctx->qbits, dctx->pmd, &res, pcb); BN_GENCB_free(pcb); - if (ret) + if (ret > 0) EVP_PKEY_assign_DSA(pkey, dsa); else DSA_free(dsa); diff --git a/crypto/ec/asm/ecp_nistz256-avx2.pl b/crypto/ec/asm/ecp_nistz256-avx2.pl deleted file mode 100755 index 15bca9b0..00000000 --- a/crypto/ec/asm/ecp_nistz256-avx2.pl +++ /dev/null @@ -1,2082 +0,0 @@ -#! /usr/bin/env perl -# Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. -# Copyright (c) 2014, Intel Corporation. All Rights Reserved. -# -# Licensed under the Apache License 2.0 (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html -# -# Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) -# (1) Intel Corporation, Israel Development Center, Haifa, Israel -# (2) University of Haifa, Israel -# -# Reference: -# S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with -# 256 Bit Primes" - -# $output is the last argument if it looks like a file (it has an extension) -# $flavour is the first argument if it doesn't look like a file -$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; -$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; - -$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); - -$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; -( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or -( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or -die "can't locate x86_64-xlate.pl"; - -open OUT,"| \"$^X\" $xlate $flavour \"$output\"" - or die "can't call $xlate: $!"; -*STDOUT=*OUT; - -if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` - =~ /GNU assembler version ([2-9]\.[0-9]+)/) { - $avx = ($1>=2.19) + ($1>=2.22); - $addx = ($1>=2.23); -} - -if (!$addx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) && - `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/) { - $avx = ($1>=2.09) + ($1>=2.10); - $addx = ($1>=2.10); -} - -if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && - `ml64 2>&1` =~ /Version ([0-9]+)\./) { - $avx = ($1>=10) + ($1>=11); - $addx = ($1>=12); -} - -if (!$addx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|based on LLVM) ([0-9]+)\.([0-9]+)/) { - my $ver = $2 + $3/100.0; # 3.1->3.01, 3.10->3.10 - $avx = ($ver>=3.0) + ($ver>=3.01); - $addx = ($ver>=3.03); -} - -if ($avx>=2) {{ -$digit_size = "\$29"; -$n_digits = "\$9"; - -$code.=<<___; -.text - -.align 64 -.LAVX2_AND_MASK: -.LAVX2_POLY: -.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff -.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff -.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff -.quad 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff -.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000 -.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000 -.quad 0x00040000, 0x00040000, 0x00040000, 0x00040000 -.quad 0x1fe00000, 0x1fe00000, 0x1fe00000, 0x1fe00000 -.quad 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff - -.LAVX2_POLY_x2: -.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC -.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC -.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC -.quad 0x400007FC, 0x400007FC, 0x400007FC, 0x400007FC -.quad 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE -.quad 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE, 0x3FFFFFFE -.quad 0x400FFFFE, 0x400FFFFE, 0x400FFFFE, 0x400FFFFE -.quad 0x7F7FFFFE, 0x7F7FFFFE, 0x7F7FFFFE, 0x7F7FFFFE -.quad 0x03FFFFFC, 0x03FFFFFC, 0x03FFFFFC, 0x03FFFFFC - -.LAVX2_POLY_x8: -.quad 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8 -.quad 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8 -.quad 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8, 0xFFFFFFF8 -.quad 0x80000FF8, 0x80000FF8, 0x80000FF8, 0x80000FF8 -.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC -.quad 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC, 0x7FFFFFFC -.quad 0x801FFFFC, 0x801FFFFC, 0x801FFFFC, 0x801FFFFC -.quad 0xFEFFFFFC, 0xFEFFFFFC, 0xFEFFFFFC, 0xFEFFFFFC -.quad 0x07FFFFF8, 0x07FFFFF8, 0x07FFFFF8, 0x07FFFFF8 - -.LONE: -.quad 0x00000020, 0x00000020, 0x00000020, 0x00000020 -.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000 -.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000 -.quad 0x1fffc000, 0x1fffc000, 0x1fffc000, 0x1fffc000 -.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff -.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff -.quad 0x1f7fffff, 0x1f7fffff, 0x1f7fffff, 0x1f7fffff -.quad 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff -.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000 - -# RR = 2^266 mod p in AVX2 format, to transform from the native OpenSSL -# Montgomery form (*2^256) to our format (*2^261) - -.LTO_MONT_AVX2: -.quad 0x00000400, 0x00000400, 0x00000400, 0x00000400 -.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000 -.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000 -.quad 0x1ff80000, 0x1ff80000, 0x1ff80000, 0x1ff80000 -.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff -.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff -.quad 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff -.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff -.quad 0x00000003, 0x00000003, 0x00000003, 0x00000003 - -.LFROM_MONT_AVX2: -.quad 0x00000001, 0x00000001, 0x00000001, 0x00000001 -.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000 -.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000 -.quad 0x1ffffe00, 0x1ffffe00, 0x1ffffe00, 0x1ffffe00 -.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff -.quad 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff -.quad 0x1ffbffff, 0x1ffbffff, 0x1ffbffff, 0x1ffbffff -.quad 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff -.quad 0x00000000, 0x00000000, 0x00000000, 0x00000000 - -.LIntOne: -.long 1,1,1,1,1,1,1,1 -___ - -{ -# This function receives a pointer to an array of four affine points -# (X, Y, <1>) and rearranges the data for AVX2 execution, while -# converting it to 2^29 radix redundant form - -my ($X0,$X1,$X2,$X3, $Y0,$Y1,$Y2,$Y3, - $T0,$T1,$T2,$T3, $T4,$T5,$T6,$T7)=map("%ymm$_",(0..15)); - -$code.=<<___; -.globl ecp_nistz256_avx2_transpose_convert -.type ecp_nistz256_avx2_transpose_convert,\@function,2 -.align 64 -ecp_nistz256_avx2_transpose_convert: - vzeroupper -___ -$code.=<<___ if ($win64); - lea -8-16*10(%rsp), %rsp - vmovaps %xmm6, -8-16*10(%rax) - vmovaps %xmm7, -8-16*9(%rax) - vmovaps %xmm8, -8-16*8(%rax) - vmovaps %xmm9, -8-16*7(%rax) - vmovaps %xmm10, -8-16*6(%rax) - vmovaps %xmm11, -8-16*5(%rax) - vmovaps %xmm12, -8-16*4(%rax) - vmovaps %xmm13, -8-16*3(%rax) - vmovaps %xmm14, -8-16*2(%rax) - vmovaps %xmm15, -8-16*1(%rax) -___ -$code.=<<___; - # Load the data - vmovdqa 32*0(%rsi), $X0 - lea 112(%rsi), %rax # size optimization - vmovdqa 32*1(%rsi), $Y0 - lea .LAVX2_AND_MASK(%rip), %rdx - vmovdqa 32*2(%rsi), $X1 - vmovdqa 32*3(%rsi), $Y1 - vmovdqa 32*4-112(%rax), $X2 - vmovdqa 32*5-112(%rax), $Y2 - vmovdqa 32*6-112(%rax), $X3 - vmovdqa 32*7-112(%rax), $Y3 - - # Transpose X and Y independently - vpunpcklqdq $X1, $X0, $T0 # T0 = [B2 A2 B0 A0] - vpunpcklqdq $X3, $X2, $T1 # T1 = [D2 C2 D0 C0] - vpunpckhqdq $X1, $X0, $T2 # T2 = [B3 A3 B1 A1] - vpunpckhqdq $X3, $X2, $T3 # T3 = [D3 C3 D1 C1] - - vpunpcklqdq $Y1, $Y0, $T4 - vpunpcklqdq $Y3, $Y2, $T5 - vpunpckhqdq $Y1, $Y0, $T6 - vpunpckhqdq $Y3, $Y2, $T7 - - vperm2i128 \$0x20, $T1, $T0, $X0 # X0 = [D0 C0 B0 A0] - vperm2i128 \$0x20, $T3, $T2, $X1 # X1 = [D1 C1 B1 A1] - vperm2i128 \$0x31, $T1, $T0, $X2 # X2 = [D2 C2 B2 A2] - vperm2i128 \$0x31, $T3, $T2, $X3 # X3 = [D3 C3 B3 A3] - - vperm2i128 \$0x20, $T5, $T4, $Y0 - vperm2i128 \$0x20, $T7, $T6, $Y1 - vperm2i128 \$0x31, $T5, $T4, $Y2 - vperm2i128 \$0x31, $T7, $T6, $Y3 - vmovdqa (%rdx), $T7 - - vpand (%rdx), $X0, $T0 # out[0] = in[0] & mask; - vpsrlq \$29, $X0, $X0 - vpand $T7, $X0, $T1 # out[1] = (in[0] >> shift) & mask; - vpsrlq \$29, $X0, $X0 - vpsllq \$6, $X1, $T2 - vpxor $X0, $T2, $T2 - vpand $T7, $T2, $T2 # out[2] = ((in[0] >> (shift*2)) ^ (in[1] << (64-shift*2))) & mask; - vpsrlq \$23, $X1, $X1 - vpand $T7, $X1, $T3 # out[3] = (in[1] >> ((shift*3)%64)) & mask; - vpsrlq \$29, $X1, $X1 - vpsllq \$12, $X2, $T4 - vpxor $X1, $T4, $T4 - vpand $T7, $T4, $T4 # out[4] = ((in[1] >> ((shift*4)%64)) ^ (in[2] << (64*2-shift*4))) & mask; - vpsrlq \$17, $X2, $X2 - vpand $T7, $X2, $T5 # out[5] = (in[2] >> ((shift*5)%64)) & mask; - vpsrlq \$29, $X2, $X2 - vpsllq \$18, $X3, $T6 - vpxor $X2, $T6, $T6 - vpand $T7, $T6, $T6 # out[6] = ((in[2] >> ((shift*6)%64)) ^ (in[3] << (64*3-shift*6))) & mask; - vpsrlq \$11, $X3, $X3 - vmovdqa $T0, 32*0(%rdi) - lea 112(%rdi), %rax # size optimization - vpand $T7, $X3, $T0 # out[7] = (in[3] >> ((shift*7)%64)) & mask; - vpsrlq \$29, $X3, $X3 # out[8] = (in[3] >> ((shift*8)%64)) & mask; - - vmovdqa $T1, 32*1(%rdi) - vmovdqa $T2, 32*2(%rdi) - vmovdqa $T3, 32*3(%rdi) - vmovdqa $T4, 32*4-112(%rax) - vmovdqa $T5, 32*5-112(%rax) - vmovdqa $T6, 32*6-112(%rax) - vmovdqa $T0, 32*7-112(%rax) - vmovdqa $X3, 32*8-112(%rax) - lea 448(%rdi), %rax # size optimization - - vpand $T7, $Y0, $T0 # out[0] = in[0] & mask; - vpsrlq \$29, $Y0, $Y0 - vpand $T7, $Y0, $T1 # out[1] = (in[0] >> shift) & mask; - vpsrlq \$29, $Y0, $Y0 - vpsllq \$6, $Y1, $T2 - vpxor $Y0, $T2, $T2 - vpand $T7, $T2, $T2 # out[2] = ((in[0] >> (shift*2)) ^ (in[1] << (64-shift*2))) & mask; - vpsrlq \$23, $Y1, $Y1 - vpand $T7, $Y1, $T3 # out[3] = (in[1] >> ((shift*3)%64)) & mask; - vpsrlq \$29, $Y1, $Y1 - vpsllq \$12, $Y2, $T4 - vpxor $Y1, $T4, $T4 - vpand $T7, $T4, $T4 # out[4] = ((in[1] >> ((shift*4)%64)) ^ (in[2] << (64*2-shift*4))) & mask; - vpsrlq \$17, $Y2, $Y2 - vpand $T7, $Y2, $T5 # out[5] = (in[2] >> ((shift*5)%64)) & mask; - vpsrlq \$29, $Y2, $Y2 - vpsllq \$18, $Y3, $T6 - vpxor $Y2, $T6, $T6 - vpand $T7, $T6, $T6 # out[6] = ((in[2] >> ((shift*6)%64)) ^ (in[3] << (64*3-shift*6))) & mask; - vpsrlq \$11, $Y3, $Y3 - vmovdqa $T0, 32*9-448(%rax) - vpand $T7, $Y3, $T0 # out[7] = (in[3] >> ((shift*7)%64)) & mask; - vpsrlq \$29, $Y3, $Y3 # out[8] = (in[3] >> ((shift*8)%64)) & mask; - - vmovdqa $T1, 32*10-448(%rax) - vmovdqa $T2, 32*11-448(%rax) - vmovdqa $T3, 32*12-448(%rax) - vmovdqa $T4, 32*13-448(%rax) - vmovdqa $T5, 32*14-448(%rax) - vmovdqa $T6, 32*15-448(%rax) - vmovdqa $T0, 32*16-448(%rax) - vmovdqa $Y3, 32*17-448(%rax) - - vzeroupper -___ -$code.=<<___ if ($win64); - movaps 16*0(%rsp), %xmm6 - movaps 16*1(%rsp), %xmm7 - movaps 16*2(%rsp), %xmm8 - movaps 16*3(%rsp), %xmm9 - movaps 16*4(%rsp), %xmm10 - movaps 16*5(%rsp), %xmm11 - movaps 16*6(%rsp), %xmm12 - movaps 16*7(%rsp), %xmm13 - movaps 16*8(%rsp), %xmm14 - movaps 16*9(%rsp), %xmm15 - lea 8+16*10(%rsp), %rsp -___ -$code.=<<___; - ret -.size ecp_nistz256_avx2_transpose_convert,.-ecp_nistz256_avx2_transpose_convert -___ -} -{ -################################################################################ -# This function receives a pointer to an array of four AVX2 formatted points -# (X, Y, Z) convert the data to normal representation, and rearranges the data - -my ($D0,$D1,$D2,$D3, $D4,$D5,$D6,$D7, $D8)=map("%ymm$_",(0..8)); -my ($T0,$T1,$T2,$T3, $T4,$T5,$T6)=map("%ymm$_",(9..15)); - -$code.=<<___; - -.globl ecp_nistz256_avx2_convert_transpose_back -.type ecp_nistz256_avx2_convert_transpose_back,\@function,2 -.align 32 -ecp_nistz256_avx2_convert_transpose_back: - vzeroupper -___ -$code.=<<___ if ($win64); - lea -8-16*10(%rsp), %rsp - vmovaps %xmm6, -8-16*10(%rax) - vmovaps %xmm7, -8-16*9(%rax) - vmovaps %xmm8, -8-16*8(%rax) - vmovaps %xmm9, -8-16*7(%rax) - vmovaps %xmm10, -8-16*6(%rax) - vmovaps %xmm11, -8-16*5(%rax) - vmovaps %xmm12, -8-16*4(%rax) - vmovaps %xmm13, -8-16*3(%rax) - vmovaps %xmm14, -8-16*2(%rax) - vmovaps %xmm15, -8-16*1(%rax) -___ -$code.=<<___; - mov \$3, %ecx - -.Lconv_loop: - vmovdqa 32*0(%rsi), $D0 - lea 160(%rsi), %rax # size optimization - vmovdqa 32*1(%rsi), $D1 - vmovdqa 32*2(%rsi), $D2 - vmovdqa 32*3(%rsi), $D3 - vmovdqa 32*4-160(%rax), $D4 - vmovdqa 32*5-160(%rax), $D5 - vmovdqa 32*6-160(%rax), $D6 - vmovdqa 32*7-160(%rax), $D7 - vmovdqa 32*8-160(%rax), $D8 - - vpsllq \$29, $D1, $D1 - vpsllq \$58, $D2, $T0 - vpaddq $D1, $D0, $D0 - vpaddq $T0, $D0, $D0 # out[0] = (in[0]) ^ (in[1] << shift*1) ^ (in[2] << shift*2); - - vpsrlq \$6, $D2, $D2 - vpsllq \$23, $D3, $D3 - vpsllq \$52, $D4, $T1 - vpaddq $D2, $D3, $D3 - vpaddq $D3, $T1, $D1 # out[1] = (in[2] >> (64*1-shift*2)) ^ (in[3] << shift*3%64) ^ (in[4] << shift*4%64); - - vpsrlq \$12, $D4, $D4 - vpsllq \$17, $D5, $D5 - vpsllq \$46, $D6, $T2 - vpaddq $D4, $D5, $D5 - vpaddq $D5, $T2, $D2 # out[2] = (in[4] >> (64*2-shift*4)) ^ (in[5] << shift*5%64) ^ (in[6] << shift*6%64); - - vpsrlq \$18, $D6, $D6 - vpsllq \$11, $D7, $D7 - vpsllq \$40, $D8, $T3 - vpaddq $D6, $D7, $D7 - vpaddq $D7, $T3, $D3 # out[3] = (in[6] >> (64*3-shift*6)) ^ (in[7] << shift*7%64) ^ (in[8] << shift*8%64); - - vpunpcklqdq $D1, $D0, $T0 # T0 = [B2 A2 B0 A0] - vpunpcklqdq $D3, $D2, $T1 # T1 = [D2 C2 D0 C0] - vpunpckhqdq $D1, $D0, $T2 # T2 = [B3 A3 B1 A1] - vpunpckhqdq $D3, $D2, $T3 # T3 = [D3 C3 D1 C1] - - vperm2i128 \$0x20, $T1, $T0, $D0 # X0 = [D0 C0 B0 A0] - vperm2i128 \$0x20, $T3, $T2, $D1 # X1 = [D1 C1 B1 A1] - vperm2i128 \$0x31, $T1, $T0, $D2 # X2 = [D2 C2 B2 A2] - vperm2i128 \$0x31, $T3, $T2, $D3 # X3 = [D3 C3 B3 A3] - - vmovdqa $D0, 32*0(%rdi) - vmovdqa $D1, 32*3(%rdi) - vmovdqa $D2, 32*6(%rdi) - vmovdqa $D3, 32*9(%rdi) - - lea 32*9(%rsi), %rsi - lea 32*1(%rdi), %rdi - - dec %ecx - jnz .Lconv_loop - - vzeroupper -___ -$code.=<<___ if ($win64); - movaps 16*0(%rsp), %xmm6 - movaps 16*1(%rsp), %xmm7 - movaps 16*2(%rsp), %xmm8 - movaps 16*3(%rsp), %xmm9 - movaps 16*4(%rsp), %xmm10 - movaps 16*5(%rsp), %xmm11 - movaps 16*6(%rsp), %xmm12 - movaps 16*7(%rsp), %xmm13 - movaps 16*8(%rsp), %xmm14 - movaps 16*9(%rsp), %xmm15 - lea 8+16*10(%rsp), %rsp -___ -$code.=<<___; - ret -.size ecp_nistz256_avx2_convert_transpose_back,.-ecp_nistz256_avx2_convert_transpose_back -___ -} -{ -my ($r_ptr,$a_ptr,$b_ptr,$itr)=("%rdi","%rsi","%rdx","%ecx"); -my ($ACC0,$ACC1,$ACC2,$ACC3,$ACC4,$ACC5,$ACC6,$ACC7,$ACC8)=map("%ymm$_",(0..8)); -my ($B,$Y,$T0,$AND_MASK,$OVERFLOW)=map("%ymm$_",(9..13)); - -sub NORMALIZE { -my $ret=<<___; - vpsrlq $digit_size, $ACC0, $T0 - vpand $AND_MASK, $ACC0, $ACC0 - vpaddq $T0, $ACC1, $ACC1 - - vpsrlq $digit_size, $ACC1, $T0 - vpand $AND_MASK, $ACC1, $ACC1 - vpaddq $T0, $ACC2, $ACC2 - - vpsrlq $digit_size, $ACC2, $T0 - vpand $AND_MASK, $ACC2, $ACC2 - vpaddq $T0, $ACC3, $ACC3 - - vpsrlq $digit_size, $ACC3, $T0 - vpand $AND_MASK, $ACC3, $ACC3 - vpaddq $T0, $ACC4, $ACC4 - - vpsrlq $digit_size, $ACC4, $T0 - vpand $AND_MASK, $ACC4, $ACC4 - vpaddq $T0, $ACC5, $ACC5 - - vpsrlq $digit_size, $ACC5, $T0 - vpand $AND_MASK, $ACC5, $ACC5 - vpaddq $T0, $ACC6, $ACC6 - - vpsrlq $digit_size, $ACC6, $T0 - vpand $AND_MASK, $ACC6, $ACC6 - vpaddq $T0, $ACC7, $ACC7 - - vpsrlq $digit_size, $ACC7, $T0 - vpand $AND_MASK, $ACC7, $ACC7 - vpaddq $T0, $ACC8, $ACC8 - #vpand $AND_MASK, $ACC8, $ACC8 -___ - $ret; -} - -sub STORE { -my $ret=<<___; - vmovdqa $ACC0, 32*0(%rdi) - lea 160(%rdi), %rax # size optimization - vmovdqa $ACC1, 32*1(%rdi) - vmovdqa $ACC2, 32*2(%rdi) - vmovdqa $ACC3, 32*3(%rdi) - vmovdqa $ACC4, 32*4-160(%rax) - vmovdqa $ACC5, 32*5-160(%rax) - vmovdqa $ACC6, 32*6-160(%rax) - vmovdqa $ACC7, 32*7-160(%rax) - vmovdqa $ACC8, 32*8-160(%rax) -___ - $ret; -} - -$code.=<<___; -.type avx2_normalize,\@abi-omnipotent -.align 32 -avx2_normalize: - vpsrlq $digit_size, $ACC0, $T0 - vpand $AND_MASK, $ACC0, $ACC0 - vpaddq $T0, $ACC1, $ACC1 - - vpsrlq $digit_size, $ACC1, $T0 - vpand $AND_MASK, $ACC1, $ACC1 - vpaddq $T0, $ACC2, $ACC2 - - vpsrlq $digit_size, $ACC2, $T0 - vpand $AND_MASK, $ACC2, $ACC2 - vpaddq $T0, $ACC3, $ACC3 - - vpsrlq $digit_size, $ACC3, $T0 - vpand $AND_MASK, $ACC3, $ACC3 - vpaddq $T0, $ACC4, $ACC4 - - vpsrlq $digit_size, $ACC4, $T0 - vpand $AND_MASK, $ACC4, $ACC4 - vpaddq $T0, $ACC5, $ACC5 - - vpsrlq $digit_size, $ACC5, $T0 - vpand $AND_MASK, $ACC5, $ACC5 - vpaddq $T0, $ACC6, $ACC6 - - vpsrlq $digit_size, $ACC6, $T0 - vpand $AND_MASK, $ACC6, $ACC6 - vpaddq $T0, $ACC7, $ACC7 - - vpsrlq $digit_size, $ACC7, $T0 - vpand $AND_MASK, $ACC7, $ACC7 - vpaddq $T0, $ACC8, $ACC8 - #vpand $AND_MASK, $ACC8, $ACC8 - - ret -.size avx2_normalize,.-avx2_normalize - -.type avx2_normalize_n_store,\@abi-omnipotent -.align 32 -avx2_normalize_n_store: - vpsrlq $digit_size, $ACC0, $T0 - vpand $AND_MASK, $ACC0, $ACC0 - vpaddq $T0, $ACC1, $ACC1 - - vpsrlq $digit_size, $ACC1, $T0 - vpand $AND_MASK, $ACC1, $ACC1 - vmovdqa $ACC0, 32*0(%rdi) - lea 160(%rdi), %rax # size optimization - vpaddq $T0, $ACC2, $ACC2 - - vpsrlq $digit_size, $ACC2, $T0 - vpand $AND_MASK, $ACC2, $ACC2 - vmovdqa $ACC1, 32*1(%rdi) - vpaddq $T0, $ACC3, $ACC3 - - vpsrlq $digit_size, $ACC3, $T0 - vpand $AND_MASK, $ACC3, $ACC3 - vmovdqa $ACC2, 32*2(%rdi) - vpaddq $T0, $ACC4, $ACC4 - - vpsrlq $digit_size, $ACC4, $T0 - vpand $AND_MASK, $ACC4, $ACC4 - vmovdqa $ACC3, 32*3(%rdi) - vpaddq $T0, $ACC5, $ACC5 - - vpsrlq $digit_size, $ACC5, $T0 - vpand $AND_MASK, $ACC5, $ACC5 - vmovdqa $ACC4, 32*4-160(%rax) - vpaddq $T0, $ACC6, $ACC6 - - vpsrlq $digit_size, $ACC6, $T0 - vpand $AND_MASK, $ACC6, $ACC6 - vmovdqa $ACC5, 32*5-160(%rax) - vpaddq $T0, $ACC7, $ACC7 - - vpsrlq $digit_size, $ACC7, $T0 - vpand $AND_MASK, $ACC7, $ACC7 - vmovdqa $ACC6, 32*6-160(%rax) - vpaddq $T0, $ACC8, $ACC8 - #vpand $AND_MASK, $ACC8, $ACC8 - vmovdqa $ACC7, 32*7-160(%rax) - vmovdqa $ACC8, 32*8-160(%rax) - - ret -.size avx2_normalize_n_store,.-avx2_normalize_n_store - -################################################################################ -# void avx2_mul_x4(void* RESULTx4, void *Ax4, void *Bx4); -.type avx2_mul_x4,\@abi-omnipotent -.align 32 -avx2_mul_x4: - lea .LAVX2_POLY(%rip), %rax - - vpxor $ACC0, $ACC0, $ACC0 - vpxor $ACC1, $ACC1, $ACC1 - vpxor $ACC2, $ACC2, $ACC2 - vpxor $ACC3, $ACC3, $ACC3 - vpxor $ACC4, $ACC4, $ACC4 - vpxor $ACC5, $ACC5, $ACC5 - vpxor $ACC6, $ACC6, $ACC6 - vpxor $ACC7, $ACC7, $ACC7 - - vmovdqa 32*7(%rax), %ymm14 - vmovdqa 32*8(%rax), %ymm15 - - mov $n_digits, $itr - lea -512($a_ptr), $a_ptr # strategic bias to control u-op density - jmp .Lavx2_mul_x4_loop - -.align 32 -.Lavx2_mul_x4_loop: - vmovdqa 32*0($b_ptr), $B - lea 32*1($b_ptr), $b_ptr - - vpmuludq 32*0+512($a_ptr), $B, $T0 - vpmuludq 32*1+512($a_ptr), $B, $OVERFLOW # borrow $OVERFLOW - vpaddq $T0, $ACC0, $ACC0 - vpmuludq 32*2+512($a_ptr), $B, $T0 - vpaddq $OVERFLOW, $ACC1, $ACC1 - vpand $AND_MASK, $ACC0, $Y - vpmuludq 32*3+512($a_ptr), $B, $OVERFLOW - vpaddq $T0, $ACC2, $ACC2 - vpmuludq 32*4+512($a_ptr), $B, $T0 - vpaddq $OVERFLOW, $ACC3, $ACC3 - vpmuludq 32*5+512($a_ptr), $B, $OVERFLOW - vpaddq $T0, $ACC4, $ACC4 - vpmuludq 32*6+512($a_ptr), $B, $T0 - vpaddq $OVERFLOW, $ACC5, $ACC5 - vpmuludq 32*7+512($a_ptr), $B, $OVERFLOW - vpaddq $T0, $ACC6, $ACC6 - - # Skip some multiplications, optimizing for the constant poly - vpmuludq $AND_MASK, $Y, $T0 - vpaddq $OVERFLOW, $ACC7, $ACC7 - vpmuludq 32*8+512($a_ptr), $B, $ACC8 - vpaddq $T0, $ACC0, $OVERFLOW - vpaddq $T0, $ACC1, $ACC0 - vpsrlq $digit_size, $OVERFLOW, $OVERFLOW - vpaddq $T0, $ACC2, $ACC1 - vpmuludq 32*3(%rax), $Y, $T0 - vpaddq $OVERFLOW, $ACC0, $ACC0 - vpaddq $T0, $ACC3, $ACC2 - .byte 0x67 - vmovdqa $ACC4, $ACC3 - vpsllq \$18, $Y, $OVERFLOW - .byte 0x67 - vmovdqa $ACC5, $ACC4 - vpmuludq %ymm14, $Y, $T0 - vpaddq $OVERFLOW, $ACC6, $ACC5 - vpmuludq %ymm15, $Y, $OVERFLOW - vpaddq $T0, $ACC7, $ACC6 - vpaddq $OVERFLOW, $ACC8, $ACC7 - - dec $itr - jnz .Lavx2_mul_x4_loop - - vpxor $ACC8, $ACC8, $ACC8 - - ret -.size avx2_mul_x4,.-avx2_mul_x4 - -# Function optimized for the constant 1 -################################################################################ -# void avx2_mul_by1_x4(void* RESULTx4, void *Ax4); -.type avx2_mul_by1_x4,\@abi-omnipotent -.align 32 -avx2_mul_by1_x4: - lea .LAVX2_POLY(%rip), %rax - - vpxor $ACC0, $ACC0, $ACC0 - vpxor $ACC1, $ACC1, $ACC1 - vpxor $ACC2, $ACC2, $ACC2 - vpxor $ACC3, $ACC3, $ACC3 - vpxor $ACC4, $ACC4, $ACC4 - vpxor $ACC5, $ACC5, $ACC5 - vpxor $ACC6, $ACC6, $ACC6 - vpxor $ACC7, $ACC7, $ACC7 - vpxor $ACC8, $ACC8, $ACC8 - - vmovdqa 32*3+.LONE(%rip), %ymm14 - vmovdqa 32*7+.LONE(%rip), %ymm15 - - mov $n_digits, $itr - jmp .Lavx2_mul_by1_x4_loop - -.align 32 -.Lavx2_mul_by1_x4_loop: - vmovdqa 32*0($a_ptr), $B - .byte 0x48,0x8d,0xb6,0x20,0,0,0 # lea 32*1($a_ptr), $a_ptr - - vpsllq \$5, $B, $OVERFLOW - vpmuludq %ymm14, $B, $T0 - vpaddq $OVERFLOW, $ACC0, $ACC0 - vpaddq $T0, $ACC3, $ACC3 - .byte 0x67 - vpmuludq $AND_MASK, $B, $T0 - vpand $AND_MASK, $ACC0, $Y - vpaddq $T0, $ACC4, $ACC4 - vpaddq $T0, $ACC5, $ACC5 - vpaddq $T0, $ACC6, $ACC6 - vpsllq \$23, $B, $T0 - - .byte 0x67,0x67 - vpmuludq %ymm15, $B, $OVERFLOW - vpsubq $T0, $ACC6, $ACC6 - - vpmuludq $AND_MASK, $Y, $T0 - vpaddq $OVERFLOW, $ACC7, $ACC7 - vpaddq $T0, $ACC0, $OVERFLOW - vpaddq $T0, $ACC1, $ACC0 - .byte 0x67,0x67 - vpsrlq $digit_size, $OVERFLOW, $OVERFLOW - vpaddq $T0, $ACC2, $ACC1 - vpmuludq 32*3(%rax), $Y, $T0 - vpaddq $OVERFLOW, $ACC0, $ACC0 - vpaddq $T0, $ACC3, $ACC2 - vmovdqa $ACC4, $ACC3 - vpsllq \$18, $Y, $OVERFLOW - vmovdqa $ACC5, $ACC4 - vpmuludq 32*7(%rax), $Y, $T0 - vpaddq $OVERFLOW, $ACC6, $ACC5 - vpaddq $T0, $ACC7, $ACC6 - vpmuludq 32*8(%rax), $Y, $ACC7 - - dec $itr - jnz .Lavx2_mul_by1_x4_loop - - ret -.size avx2_mul_by1_x4,.-avx2_mul_by1_x4 - -################################################################################ -# void avx2_sqr_x4(void* RESULTx4, void *Ax4, void *Bx4); -.type avx2_sqr_x4,\@abi-omnipotent -.align 32 -avx2_sqr_x4: - lea .LAVX2_POLY(%rip), %rax - - vmovdqa 32*7(%rax), %ymm14 - vmovdqa 32*8(%rax), %ymm15 - - vmovdqa 32*0($a_ptr), $B - vmovdqa 32*1($a_ptr), $ACC1 - vmovdqa 32*2($a_ptr), $ACC2 - vmovdqa 32*3($a_ptr), $ACC3 - vmovdqa 32*4($a_ptr), $ACC4 - vmovdqa 32*5($a_ptr), $ACC5 - vmovdqa 32*6($a_ptr), $ACC6 - vmovdqa 32*7($a_ptr), $ACC7 - vpaddq $ACC1, $ACC1, $ACC1 # 2*$ACC0..7 - vmovdqa 32*8($a_ptr), $ACC8 - vpaddq $ACC2, $ACC2, $ACC2 - vmovdqa $ACC1, 32*0(%rcx) - vpaddq $ACC3, $ACC3, $ACC3 - vmovdqa $ACC2, 32*1(%rcx) - vpaddq $ACC4, $ACC4, $ACC4 - vmovdqa $ACC3, 32*2(%rcx) - vpaddq $ACC5, $ACC5, $ACC5 - vmovdqa $ACC4, 32*3(%rcx) - vpaddq $ACC6, $ACC6, $ACC6 - vmovdqa $ACC5, 32*4(%rcx) - vpaddq $ACC7, $ACC7, $ACC7 - vmovdqa $ACC6, 32*5(%rcx) - vpaddq $ACC8, $ACC8, $ACC8 - vmovdqa $ACC7, 32*6(%rcx) - vmovdqa $ACC8, 32*7(%rcx) - - #itr 1 - vpmuludq $B, $B, $ACC0 - vpmuludq $B, $ACC1, $ACC1 - vpand $AND_MASK, $ACC0, $Y - vpmuludq $B, $ACC2, $ACC2 - vpmuludq $B, $ACC3, $ACC3 - vpmuludq $B, $ACC4, $ACC4 - vpmuludq $B, $ACC5, $ACC5 - vpmuludq $B, $ACC6, $ACC6 - vpmuludq $AND_MASK, $Y, $T0 - vpmuludq $B, $ACC7, $ACC7 - vpmuludq $B, $ACC8, $ACC8 - vmovdqa 32*1($a_ptr), $B - - vpaddq $T0, $ACC0, $OVERFLOW - vpaddq $T0, $ACC1, $ACC0 - vpsrlq $digit_size, $OVERFLOW, $OVERFLOW - vpaddq $T0, $ACC2, $ACC1 - vpmuludq 32*3(%rax), $Y, $T0 - vpaddq $OVERFLOW, $ACC0, $ACC0 - vpaddq $T0, $ACC3, $ACC2 - vmovdqa $ACC4, $ACC3 - vpsllq \$18, $Y, $T0 - vmovdqa $ACC5, $ACC4 - vpmuludq %ymm14, $Y, $OVERFLOW - vpaddq $T0, $ACC6, $ACC5 - vpmuludq %ymm15, $Y, $T0 - vpaddq $OVERFLOW, $ACC7, $ACC6 - vpaddq $T0, $ACC8, $ACC7 - - #itr 2 - vpmuludq $B, $B, $OVERFLOW - vpand $AND_MASK, $ACC0, $Y - vpmuludq 32*1(%rcx), $B, $T0 - vpaddq $OVERFLOW, $ACC1, $ACC1 - vpmuludq 32*2(%rcx), $B, $OVERFLOW - vpaddq $T0, $ACC2, $ACC2 - vpmuludq 32*3(%rcx), $B, $T0 - vpaddq $OVERFLOW, $ACC3, $ACC3 - vpmuludq 32*4(%rcx), $B, $OVERFLOW - vpaddq $T0, $ACC4, $ACC4 - vpmuludq 32*5(%rcx), $B, $T0 - vpaddq $OVERFLOW, $ACC5, $ACC5 - vpmuludq 32*6(%rcx), $B, $OVERFLOW - vpaddq $T0, $ACC6, $ACC6 - - vpmuludq $AND_MASK, $Y, $T0 - vpaddq $OVERFLOW, $ACC7, $ACC7 - vpmuludq 32*7(%rcx), $B, $ACC8 - vmovdqa 32*2($a_ptr), $B - vpaddq $T0, $ACC0, $OVERFLOW - vpaddq $T0, $ACC1, $ACC0 - vpsrlq $digit_size, $OVERFLOW, $OVERFLOW - vpaddq $T0, $ACC2, $ACC1 - vpmuludq 32*3(%rax), $Y, $T0 - vpaddq $OVERFLOW, $ACC0, $ACC0 - vpaddq $T0, $ACC3, $ACC2 - vmovdqa $ACC4, $ACC3 - vpsllq \$18, $Y, $T0 - vmovdqa $ACC5, $ACC4 - vpmuludq %ymm14, $Y, $OVERFLOW - vpaddq $T0, $ACC6, $ACC5 - vpmuludq %ymm15, $Y, $T0 - vpaddq $OVERFLOW, $ACC7, $ACC6 - vpaddq $T0, $ACC8, $ACC7 - - #itr 3 - vpmuludq $B, $B, $T0 - vpand $AND_MASK, $ACC0, $Y - vpmuludq 32*2(%rcx), $B, $OVERFLOW - vpaddq $T0, $ACC2, $ACC2 - vpmuludq 32*3(%rcx), $B, $T0 - vpaddq $OVERFLOW, $ACC3, $ACC3 - vpmuludq 32*4(%rcx), $B, $OVERFLOW - vpaddq $T0, $ACC4, $ACC4 - vpmuludq 32*5(%rcx), $B, $T0 - vpaddq $OVERFLOW, $ACC5, $ACC5 - vpmuludq 32*6(%rcx), $B, $OVERFLOW - vpaddq $T0, $ACC6, $ACC6 - - vpmuludq $AND_MASK, $Y, $T0 - vpaddq $OVERFLOW, $ACC7, $ACC7 - vpmuludq 32*7(%rcx), $B, $ACC8 - vmovdqa 32*3($a_ptr), $B - vpaddq $T0, $ACC0, $OVERFLOW - vpaddq $T0, $ACC1, $ACC0 - vpsrlq $digit_size, $OVERFLOW, $OVERFLOW - vpaddq $T0, $ACC2, $ACC1 - vpmuludq 32*3(%rax), $Y, $T0 - vpaddq $OVERFLOW, $ACC0, $ACC0 - vpaddq $T0, $ACC3, $ACC2 - vmovdqa $ACC4, $ACC3 - vpsllq \$18, $Y, $T0 - vmovdqa $ACC5, $ACC4 - vpmuludq %ymm14, $Y, $OVERFLOW - vpaddq $T0, $ACC6, $ACC5 - vpmuludq %ymm15, $Y, $T0 - vpand $AND_MASK, $ACC0, $Y - vpaddq $OVERFLOW, $ACC7, $ACC6 - vpaddq $T0, $ACC8, $ACC7 - - #itr 4 - vpmuludq $B, $B, $OVERFLOW - vpmuludq 32*3(%rcx), $B, $T0 - vpaddq $OVERFLOW, $ACC3, $ACC3 - vpmuludq 32*4(%rcx), $B, $OVERFLOW - vpaddq $T0, $ACC4, $ACC4 - vpmuludq 32*5(%rcx), $B, $T0 - vpaddq $OVERFLOW, $ACC5, $ACC5 - vpmuludq 32*6(%rcx), $B, $OVERFLOW - vpaddq $T0, $ACC6, $ACC6 - - vpmuludq $AND_MASK, $Y, $T0 - vpaddq $OVERFLOW, $ACC7, $ACC7 - vpmuludq 32*7(%rcx), $B, $ACC8 - vmovdqa 32*4($a_ptr), $B - vpaddq $T0, $ACC0, $OVERFLOW - vpaddq $T0, $ACC1, $ACC0 - vpsrlq $digit_size, $OVERFLOW, $OVERFLOW - vpaddq $T0, $ACC2, $ACC1 - vpmuludq 32*3(%rax), $Y, $T0 - vpaddq $OVERFLOW, $ACC0, $ACC0 - vpaddq $T0, $ACC3, $ACC2 - vmovdqa $ACC4, $ACC3 - vpsllq \$18, $Y, $T0 - vmovdqa $ACC5, $ACC4 - vpmuludq %ymm14, $Y, $OVERFLOW - vpaddq $T0, $ACC6, $ACC5 - vpmuludq %ymm15, $Y, $T0 - vpand $AND_MASK, $ACC0, $Y - vpaddq $OVERFLOW, $ACC7, $ACC6 - vpaddq $T0, $ACC8, $ACC7 - - #itr 5 - vpmuludq $B, $B, $T0 - vpmuludq 32*4(%rcx), $B, $OVERFLOW - vpaddq $T0, $ACC4, $ACC4 - vpmuludq 32*5(%rcx), $B, $T0 - vpaddq $OVERFLOW, $ACC5, $ACC5 - vpmuludq 32*6(%rcx), $B, $OVERFLOW - vpaddq $T0, $ACC6, $ACC6 - - vpmuludq $AND_MASK, $Y, $T0 - vpaddq $OVERFLOW, $ACC7, $ACC7 - vpmuludq 32*7(%rcx), $B, $ACC8 - vmovdqa 32*5($a_ptr), $B - vpaddq $T0, $ACC0, $OVERFLOW - vpsrlq $digit_size, $OVERFLOW, $OVERFLOW - vpaddq $T0, $ACC1, $ACC0 - vpaddq $T0, $ACC2, $ACC1 - vpmuludq 32*3+.LAVX2_POLY(%rip), $Y, $T0 - vpaddq $OVERFLOW, $ACC0, $ACC0 - vpaddq $T0, $ACC3, $ACC2 - vmovdqa $ACC4, $ACC3 - vpsllq \$18, $Y, $T0 - vmovdqa $ACC5, $ACC4 - vpmuludq %ymm14, $Y, $OVERFLOW - vpaddq $T0, $ACC6, $ACC5 - vpmuludq %ymm15, $Y, $T0 - vpand $AND_MASK, $ACC0, $Y - vpaddq $OVERFLOW, $ACC7, $ACC6 - vpaddq $T0, $ACC8, $ACC7 - - #itr 6 - vpmuludq $B, $B, $OVERFLOW - vpmuludq 32*5(%rcx), $B, $T0 - vpaddq $OVERFLOW, $ACC5, $ACC5 - vpmuludq 32*6(%rcx), $B, $OVERFLOW - vpaddq $T0, $ACC6, $ACC6 - - vpmuludq $AND_MASK, $Y, $T0 - vpaddq $OVERFLOW, $ACC7, $ACC7 - vpmuludq 32*7(%rcx), $B, $ACC8 - vmovdqa 32*6($a_ptr), $B - vpaddq $T0, $ACC0, $OVERFLOW - vpaddq $T0, $ACC1, $ACC0 - vpsrlq $digit_size, $OVERFLOW, $OVERFLOW - vpaddq $T0, $ACC2, $ACC1 - vpmuludq 32*3(%rax), $Y, $T0 - vpaddq $OVERFLOW, $ACC0, $ACC0 - vpaddq $T0, $ACC3, $ACC2 - vmovdqa $ACC4, $ACC3 - vpsllq \$18, $Y, $T0 - vmovdqa $ACC5, $ACC4 - vpmuludq %ymm14, $Y, $OVERFLOW - vpaddq $T0, $ACC6, $ACC5 - vpmuludq %ymm15, $Y, $T0 - vpand $AND_MASK, $ACC0, $Y - vpaddq $OVERFLOW, $ACC7, $ACC6 - vpaddq $T0, $ACC8, $ACC7 - - #itr 7 - vpmuludq $B, $B, $T0 - vpmuludq 32*6(%rcx), $B, $OVERFLOW - vpaddq $T0, $ACC6, $ACC6 - - vpmuludq $AND_MASK, $Y, $T0 - vpaddq $OVERFLOW, $ACC7, $ACC7 - vpmuludq 32*7(%rcx), $B, $ACC8 - vmovdqa 32*7($a_ptr), $B - vpaddq $T0, $ACC0, $OVERFLOW - vpsrlq $digit_size, $OVERFLOW, $OVERFLOW - vpaddq $T0, $ACC1, $ACC0 - vpaddq $T0, $ACC2, $ACC1 - vpmuludq 32*3(%rax), $Y, $T0 - vpaddq $OVERFLOW, $ACC0, $ACC0 - vpaddq $T0, $ACC3, $ACC2 - vmovdqa $ACC4, $ACC3 - vpsllq \$18, $Y, $T0 - vmovdqa $ACC5, $ACC4 - vpmuludq %ymm14, $Y, $OVERFLOW - vpaddq $T0, $ACC6, $ACC5 - vpmuludq %ymm15, $Y, $T0 - vpand $AND_MASK, $ACC0, $Y - vpaddq $OVERFLOW, $ACC7, $ACC6 - vpaddq $T0, $ACC8, $ACC7 - - #itr 8 - vpmuludq $B, $B, $OVERFLOW - - vpmuludq $AND_MASK, $Y, $T0 - vpaddq $OVERFLOW, $ACC7, $ACC7 - vpmuludq 32*7(%rcx), $B, $ACC8 - vmovdqa 32*8($a_ptr), $B - vpaddq $T0, $ACC0, $OVERFLOW - vpsrlq $digit_size, $OVERFLOW, $OVERFLOW - vpaddq $T0, $ACC1, $ACC0 - vpaddq $T0, $ACC2, $ACC1 - vpmuludq 32*3(%rax), $Y, $T0 - vpaddq $OVERFLOW, $ACC0, $ACC0 - vpaddq $T0, $ACC3, $ACC2 - vmovdqa $ACC4, $ACC3 - vpsllq \$18, $Y, $T0 - vmovdqa $ACC5, $ACC4 - vpmuludq %ymm14, $Y, $OVERFLOW - vpaddq $T0, $ACC6, $ACC5 - vpmuludq %ymm15, $Y, $T0 - vpand $AND_MASK, $ACC0, $Y - vpaddq $OVERFLOW, $ACC7, $ACC6 - vpaddq $T0, $ACC8, $ACC7 - - #itr 9 - vpmuludq $B, $B, $ACC8 - - vpmuludq $AND_MASK, $Y, $T0 - vpaddq $T0, $ACC0, $OVERFLOW - vpsrlq $digit_size, $OVERFLOW, $OVERFLOW - vpaddq $T0, $ACC1, $ACC0 - vpaddq $T0, $ACC2, $ACC1 - vpmuludq 32*3(%rax), $Y, $T0 - vpaddq $OVERFLOW, $ACC0, $ACC0 - vpaddq $T0, $ACC3, $ACC2 - vmovdqa $ACC4, $ACC3 - vpsllq \$18, $Y, $T0 - vmovdqa $ACC5, $ACC4 - vpmuludq %ymm14, $Y, $OVERFLOW - vpaddq $T0, $ACC6, $ACC5 - vpmuludq %ymm15, $Y, $T0 - vpaddq $OVERFLOW, $ACC7, $ACC6 - vpaddq $T0, $ACC8, $ACC7 - - vpxor $ACC8, $ACC8, $ACC8 - - ret -.size avx2_sqr_x4,.-avx2_sqr_x4 - -################################################################################ -# void avx2_sub_x4(void* RESULTx4, void *Ax4, void *Bx4); -.type avx2_sub_x4,\@abi-omnipotent -.align 32 -avx2_sub_x4: - vmovdqa 32*0($a_ptr), $ACC0 - lea 160($a_ptr), $a_ptr - lea .LAVX2_POLY_x8+128(%rip), %rax - lea 128($b_ptr), $b_ptr - vmovdqa 32*1-160($a_ptr), $ACC1 - vmovdqa 32*2-160($a_ptr), $ACC2 - vmovdqa 32*3-160($a_ptr), $ACC3 - vmovdqa 32*4-160($a_ptr), $ACC4 - vmovdqa 32*5-160($a_ptr), $ACC5 - vmovdqa 32*6-160($a_ptr), $ACC6 - vmovdqa 32*7-160($a_ptr), $ACC7 - vmovdqa 32*8-160($a_ptr), $ACC8 - - vpaddq 32*0-128(%rax), $ACC0, $ACC0 - vpaddq 32*1-128(%rax), $ACC1, $ACC1 - vpaddq 32*2-128(%rax), $ACC2, $ACC2 - vpaddq 32*3-128(%rax), $ACC3, $ACC3 - vpaddq 32*4-128(%rax), $ACC4, $ACC4 - vpaddq 32*5-128(%rax), $ACC5, $ACC5 - vpaddq 32*6-128(%rax), $ACC6, $ACC6 - vpaddq 32*7-128(%rax), $ACC7, $ACC7 - vpaddq 32*8-128(%rax), $ACC8, $ACC8 - - vpsubq 32*0-128($b_ptr), $ACC0, $ACC0 - vpsubq 32*1-128($b_ptr), $ACC1, $ACC1 - vpsubq 32*2-128($b_ptr), $ACC2, $ACC2 - vpsubq 32*3-128($b_ptr), $ACC3, $ACC3 - vpsubq 32*4-128($b_ptr), $ACC4, $ACC4 - vpsubq 32*5-128($b_ptr), $ACC5, $ACC5 - vpsubq 32*6-128($b_ptr), $ACC6, $ACC6 - vpsubq 32*7-128($b_ptr), $ACC7, $ACC7 - vpsubq 32*8-128($b_ptr), $ACC8, $ACC8 - - ret -.size avx2_sub_x4,.-avx2_sub_x4 - -.type avx2_select_n_store,\@abi-omnipotent -.align 32 -avx2_select_n_store: - vmovdqa `8+32*9*8`(%rsp), $Y - vpor `8+32*9*8+32`(%rsp), $Y, $Y - - vpandn $ACC0, $Y, $ACC0 - vpandn $ACC1, $Y, $ACC1 - vpandn $ACC2, $Y, $ACC2 - vpandn $ACC3, $Y, $ACC3 - vpandn $ACC4, $Y, $ACC4 - vpandn $ACC5, $Y, $ACC5 - vpandn $ACC6, $Y, $ACC6 - vmovdqa `8+32*9*8+32`(%rsp), $B - vpandn $ACC7, $Y, $ACC7 - vpandn `8+32*9*8`(%rsp), $B, $B - vpandn $ACC8, $Y, $ACC8 - - vpand 32*0(%rsi), $B, $T0 - lea 160(%rsi), %rax - vpand 32*1(%rsi), $B, $Y - vpxor $T0, $ACC0, $ACC0 - vpand 32*2(%rsi), $B, $T0 - vpxor $Y, $ACC1, $ACC1 - vpand 32*3(%rsi), $B, $Y - vpxor $T0, $ACC2, $ACC2 - vpand 32*4-160(%rax), $B, $T0 - vpxor $Y, $ACC3, $ACC3 - vpand 32*5-160(%rax), $B, $Y - vpxor $T0, $ACC4, $ACC4 - vpand 32*6-160(%rax), $B, $T0 - vpxor $Y, $ACC5, $ACC5 - vpand 32*7-160(%rax), $B, $Y - vpxor $T0, $ACC6, $ACC6 - vpand 32*8-160(%rax), $B, $T0 - vmovdqa `8+32*9*8+32`(%rsp), $B - vpxor $Y, $ACC7, $ACC7 - - vpand 32*0(%rdx), $B, $Y - lea 160(%rdx), %rax - vpxor $T0, $ACC8, $ACC8 - vpand 32*1(%rdx), $B, $T0 - vpxor $Y, $ACC0, $ACC0 - vpand 32*2(%rdx), $B, $Y - vpxor $T0, $ACC1, $ACC1 - vpand 32*3(%rdx), $B, $T0 - vpxor $Y, $ACC2, $ACC2 - vpand 32*4-160(%rax), $B, $Y - vpxor $T0, $ACC3, $ACC3 - vpand 32*5-160(%rax), $B, $T0 - vpxor $Y, $ACC4, $ACC4 - vpand 32*6-160(%rax), $B, $Y - vpxor $T0, $ACC5, $ACC5 - vpand 32*7-160(%rax), $B, $T0 - vpxor $Y, $ACC6, $ACC6 - vpand 32*8-160(%rax), $B, $Y - vpxor $T0, $ACC7, $ACC7 - vpxor $Y, $ACC8, $ACC8 - `&STORE` - - ret -.size avx2_select_n_store,.-avx2_select_n_store -___ -$code.=<<___ if (0); # inlined -################################################################################ -# void avx2_mul_by2_x4(void* RESULTx4, void *Ax4); -.type avx2_mul_by2_x4,\@abi-omnipotent -.align 32 -avx2_mul_by2_x4: - vmovdqa 32*0($a_ptr), $ACC0 - lea 160($a_ptr), %rax - vmovdqa 32*1($a_ptr), $ACC1 - vmovdqa 32*2($a_ptr), $ACC2 - vmovdqa 32*3($a_ptr), $ACC3 - vmovdqa 32*4-160(%rax), $ACC4 - vmovdqa 32*5-160(%rax), $ACC5 - vmovdqa 32*6-160(%rax), $ACC6 - vmovdqa 32*7-160(%rax), $ACC7 - vmovdqa 32*8-160(%rax), $ACC8 - - vpaddq $ACC0, $ACC0, $ACC0 - vpaddq $ACC1, $ACC1, $ACC1 - vpaddq $ACC2, $ACC2, $ACC2 - vpaddq $ACC3, $ACC3, $ACC3 - vpaddq $ACC4, $ACC4, $ACC4 - vpaddq $ACC5, $ACC5, $ACC5 - vpaddq $ACC6, $ACC6, $ACC6 - vpaddq $ACC7, $ACC7, $ACC7 - vpaddq $ACC8, $ACC8, $ACC8 - - ret -.size avx2_mul_by2_x4,.-avx2_mul_by2_x4 -___ -my ($r_ptr_in,$a_ptr_in,$b_ptr_in)=("%rdi","%rsi","%rdx"); -my ($r_ptr,$a_ptr,$b_ptr)=("%r8","%r9","%r10"); - -$code.=<<___; -################################################################################ -# void ecp_nistz256_avx2_point_add_affine_x4(void* RESULTx4, void *Ax4, void *Bx4); -.globl ecp_nistz256_avx2_point_add_affine_x4 -.type ecp_nistz256_avx2_point_add_affine_x4,\@function,3 -.align 32 -ecp_nistz256_avx2_point_add_affine_x4: - mov %rsp, %rax - push %rbp - vzeroupper -___ -$code.=<<___ if ($win64); - lea -16*10(%rsp), %rsp - vmovaps %xmm6, -8-16*10(%rax) - vmovaps %xmm7, -8-16*9(%rax) - vmovaps %xmm8, -8-16*8(%rax) - vmovaps %xmm9, -8-16*7(%rax) - vmovaps %xmm10, -8-16*6(%rax) - vmovaps %xmm11, -8-16*5(%rax) - vmovaps %xmm12, -8-16*4(%rax) - vmovaps %xmm13, -8-16*3(%rax) - vmovaps %xmm14, -8-16*2(%rax) - vmovaps %xmm15, -8-16*1(%rax) -___ -$code.=<<___; - lea -8(%rax), %rbp - -# Result + 32*0 = Result.X -# Result + 32*9 = Result.Y -# Result + 32*18 = Result.Z - -# A + 32*0 = A.X -# A + 32*9 = A.Y -# A + 32*18 = A.Z - -# B + 32*0 = B.X -# B + 32*9 = B.Y - - sub \$`32*9*8+32*2+32*8`, %rsp - and \$-64, %rsp - - mov $r_ptr_in, $r_ptr - mov $a_ptr_in, $a_ptr - mov $b_ptr_in, $b_ptr - - vmovdqa 32*0($a_ptr_in), %ymm0 - vmovdqa .LAVX2_AND_MASK(%rip), $AND_MASK - vpxor %ymm1, %ymm1, %ymm1 - lea 256($a_ptr_in), %rax # size optimization - vpor 32*1($a_ptr_in), %ymm0, %ymm0 - vpor 32*2($a_ptr_in), %ymm0, %ymm0 - vpor 32*3($a_ptr_in), %ymm0, %ymm0 - vpor 32*4-256(%rax), %ymm0, %ymm0 - lea 256(%rax), %rcx # size optimization - vpor 32*5-256(%rax), %ymm0, %ymm0 - vpor 32*6-256(%rax), %ymm0, %ymm0 - vpor 32*7-256(%rax), %ymm0, %ymm0 - vpor 32*8-256(%rax), %ymm0, %ymm0 - vpor 32*9-256(%rax), %ymm0, %ymm0 - vpor 32*10-256(%rax), %ymm0, %ymm0 - vpor 32*11-256(%rax), %ymm0, %ymm0 - vpor 32*12-512(%rcx), %ymm0, %ymm0 - vpor 32*13-512(%rcx), %ymm0, %ymm0 - vpor 32*14-512(%rcx), %ymm0, %ymm0 - vpor 32*15-512(%rcx), %ymm0, %ymm0 - vpor 32*16-512(%rcx), %ymm0, %ymm0 - vpor 32*17-512(%rcx), %ymm0, %ymm0 - vpcmpeqq %ymm1, %ymm0, %ymm0 - vmovdqa %ymm0, `32*9*8`(%rsp) - - vpxor %ymm1, %ymm1, %ymm1 - vmovdqa 32*0($b_ptr), %ymm0 - lea 256($b_ptr), %rax # size optimization - vpor 32*1($b_ptr), %ymm0, %ymm0 - vpor 32*2($b_ptr), %ymm0, %ymm0 - vpor 32*3($b_ptr), %ymm0, %ymm0 - vpor 32*4-256(%rax), %ymm0, %ymm0 - lea 256(%rax), %rcx # size optimization - vpor 32*5-256(%rax), %ymm0, %ymm0 - vpor 32*6-256(%rax), %ymm0, %ymm0 - vpor 32*7-256(%rax), %ymm0, %ymm0 - vpor 32*8-256(%rax), %ymm0, %ymm0 - vpor 32*9-256(%rax), %ymm0, %ymm0 - vpor 32*10-256(%rax), %ymm0, %ymm0 - vpor 32*11-256(%rax), %ymm0, %ymm0 - vpor 32*12-512(%rcx), %ymm0, %ymm0 - vpor 32*13-512(%rcx), %ymm0, %ymm0 - vpor 32*14-512(%rcx), %ymm0, %ymm0 - vpor 32*15-512(%rcx), %ymm0, %ymm0 - vpor 32*16-512(%rcx), %ymm0, %ymm0 - vpor 32*17-512(%rcx), %ymm0, %ymm0 - vpcmpeqq %ymm1, %ymm0, %ymm0 - vmovdqa %ymm0, `32*9*8+32`(%rsp) - - # Z1^2 = Z1*Z1 - lea `32*9*2`($a_ptr), %rsi - lea `32*9*2`(%rsp), %rdi - lea `32*9*8+32*2`(%rsp), %rcx # temporary vector - call avx2_sqr_x4 - call avx2_normalize_n_store - - # U2 = X2*Z1^2 - lea `32*9*0`($b_ptr), %rsi - lea `32*9*2`(%rsp), %rdx - lea `32*9*0`(%rsp), %rdi - call avx2_mul_x4 - #call avx2_normalize - `&STORE` - - # S2 = Z1*Z1^2 = Z1^3 - lea `32*9*2`($a_ptr), %rsi - lea `32*9*2`(%rsp), %rdx - lea `32*9*1`(%rsp), %rdi - call avx2_mul_x4 - call avx2_normalize_n_store - - # S2 = S2*Y2 = Y2*Z1^3 - lea `32*9*1`($b_ptr), %rsi - lea `32*9*1`(%rsp), %rdx - lea `32*9*1`(%rsp), %rdi - call avx2_mul_x4 - call avx2_normalize_n_store - - # H = U2 - U1 = U2 - X1 - lea `32*9*0`(%rsp), %rsi - lea `32*9*0`($a_ptr), %rdx - lea `32*9*3`(%rsp), %rdi - call avx2_sub_x4 - call avx2_normalize_n_store - - # R = S2 - S1 = S2 - Y1 - lea `32*9*1`(%rsp), %rsi - lea `32*9*1`($a_ptr), %rdx - lea `32*9*4`(%rsp), %rdi - call avx2_sub_x4 - call avx2_normalize_n_store - - # Z3 = H*Z1*Z2 - lea `32*9*3`(%rsp), %rsi - lea `32*9*2`($a_ptr), %rdx - lea `32*9*2`($r_ptr), %rdi - call avx2_mul_x4 - call avx2_normalize - - lea .LONE(%rip), %rsi - lea `32*9*2`($a_ptr), %rdx - call avx2_select_n_store - - # R^2 = R^2 - lea `32*9*4`(%rsp), %rsi - lea `32*9*6`(%rsp), %rdi - lea `32*9*8+32*2`(%rsp), %rcx # temporary vector - call avx2_sqr_x4 - call avx2_normalize_n_store - - # H^2 = H^2 - lea `32*9*3`(%rsp), %rsi - lea `32*9*5`(%rsp), %rdi - call avx2_sqr_x4 - call avx2_normalize_n_store - - # H^3 = H^2*H - lea `32*9*3`(%rsp), %rsi - lea `32*9*5`(%rsp), %rdx - lea `32*9*7`(%rsp), %rdi - call avx2_mul_x4 - call avx2_normalize_n_store - - # U2 = U1*H^2 - lea `32*9*0`($a_ptr), %rsi - lea `32*9*5`(%rsp), %rdx - lea `32*9*0`(%rsp), %rdi - call avx2_mul_x4 - #call avx2_normalize - `&STORE` - - # Hsqr = U2*2 - #lea 32*9*0(%rsp), %rsi - #lea 32*9*5(%rsp), %rdi - #call avx2_mul_by2_x4 - - vpaddq $ACC0, $ACC0, $ACC0 # inlined avx2_mul_by2_x4 - lea `32*9*5`(%rsp), %rdi - vpaddq $ACC1, $ACC1, $ACC1 - vpaddq $ACC2, $ACC2, $ACC2 - vpaddq $ACC3, $ACC3, $ACC3 - vpaddq $ACC4, $ACC4, $ACC4 - vpaddq $ACC5, $ACC5, $ACC5 - vpaddq $ACC6, $ACC6, $ACC6 - vpaddq $ACC7, $ACC7, $ACC7 - vpaddq $ACC8, $ACC8, $ACC8 - call avx2_normalize_n_store - - # X3 = R^2 - H^3 - #lea 32*9*6(%rsp), %rsi - #lea 32*9*7(%rsp), %rdx - #lea 32*9*5(%rsp), %rcx - #lea 32*9*0($r_ptr), %rdi - #call avx2_sub_x4 - #NORMALIZE - #STORE - - # X3 = X3 - U2*2 - #lea 32*9*0($r_ptr), %rsi - #lea 32*9*0($r_ptr), %rdi - #call avx2_sub_x4 - #NORMALIZE - #STORE - - lea `32*9*6+128`(%rsp), %rsi - lea .LAVX2_POLY_x2+128(%rip), %rax - lea `32*9*7+128`(%rsp), %rdx - lea `32*9*5+128`(%rsp), %rcx - lea `32*9*0`($r_ptr), %rdi - - vmovdqa 32*0-128(%rsi), $ACC0 - vmovdqa 32*1-128(%rsi), $ACC1 - vmovdqa 32*2-128(%rsi), $ACC2 - vmovdqa 32*3-128(%rsi), $ACC3 - vmovdqa 32*4-128(%rsi), $ACC4 - vmovdqa 32*5-128(%rsi), $ACC5 - vmovdqa 32*6-128(%rsi), $ACC6 - vmovdqa 32*7-128(%rsi), $ACC7 - vmovdqa 32*8-128(%rsi), $ACC8 - - vpaddq 32*0-128(%rax), $ACC0, $ACC0 - vpaddq 32*1-128(%rax), $ACC1, $ACC1 - vpaddq 32*2-128(%rax), $ACC2, $ACC2 - vpaddq 32*3-128(%rax), $ACC3, $ACC3 - vpaddq 32*4-128(%rax), $ACC4, $ACC4 - vpaddq 32*5-128(%rax), $ACC5, $ACC5 - vpaddq 32*6-128(%rax), $ACC6, $ACC6 - vpaddq 32*7-128(%rax), $ACC7, $ACC7 - vpaddq 32*8-128(%rax), $ACC8, $ACC8 - - vpsubq 32*0-128(%rdx), $ACC0, $ACC0 - vpsubq 32*1-128(%rdx), $ACC1, $ACC1 - vpsubq 32*2-128(%rdx), $ACC2, $ACC2 - vpsubq 32*3-128(%rdx), $ACC3, $ACC3 - vpsubq 32*4-128(%rdx), $ACC4, $ACC4 - vpsubq 32*5-128(%rdx), $ACC5, $ACC5 - vpsubq 32*6-128(%rdx), $ACC6, $ACC6 - vpsubq 32*7-128(%rdx), $ACC7, $ACC7 - vpsubq 32*8-128(%rdx), $ACC8, $ACC8 - - vpsubq 32*0-128(%rcx), $ACC0, $ACC0 - vpsubq 32*1-128(%rcx), $ACC1, $ACC1 - vpsubq 32*2-128(%rcx), $ACC2, $ACC2 - vpsubq 32*3-128(%rcx), $ACC3, $ACC3 - vpsubq 32*4-128(%rcx), $ACC4, $ACC4 - vpsubq 32*5-128(%rcx), $ACC5, $ACC5 - vpsubq 32*6-128(%rcx), $ACC6, $ACC6 - vpsubq 32*7-128(%rcx), $ACC7, $ACC7 - vpsubq 32*8-128(%rcx), $ACC8, $ACC8 - call avx2_normalize - - lea 32*0($b_ptr), %rsi - lea 32*0($a_ptr), %rdx - call avx2_select_n_store - - # H = U2 - X3 - lea `32*9*0`(%rsp), %rsi - lea `32*9*0`($r_ptr), %rdx - lea `32*9*3`(%rsp), %rdi - call avx2_sub_x4 - call avx2_normalize_n_store - - # - lea `32*9*3`(%rsp), %rsi - lea `32*9*4`(%rsp), %rdx - lea `32*9*3`(%rsp), %rdi - call avx2_mul_x4 - call avx2_normalize_n_store - - # - lea `32*9*7`(%rsp), %rsi - lea `32*9*1`($a_ptr), %rdx - lea `32*9*1`(%rsp), %rdi - call avx2_mul_x4 - call avx2_normalize_n_store - - # - lea `32*9*3`(%rsp), %rsi - lea `32*9*1`(%rsp), %rdx - lea `32*9*1`($r_ptr), %rdi - call avx2_sub_x4 - call avx2_normalize - - lea 32*9($b_ptr), %rsi - lea 32*9($a_ptr), %rdx - call avx2_select_n_store - - #lea 32*9*0($r_ptr), %rsi - #lea 32*9*0($r_ptr), %rdi - #call avx2_mul_by1_x4 - #NORMALIZE - #STORE - - lea `32*9*1`($r_ptr), %rsi - lea `32*9*1`($r_ptr), %rdi - call avx2_mul_by1_x4 - call avx2_normalize_n_store - - vzeroupper -___ -$code.=<<___ if ($win64); - movaps %xmm6, -16*10(%rbp) - movaps %xmm7, -16*9(%rbp) - movaps %xmm8, -16*8(%rbp) - movaps %xmm9, -16*7(%rbp) - movaps %xmm10, -16*6(%rbp) - movaps %xmm11, -16*5(%rbp) - movaps %xmm12, -16*4(%rbp) - movaps %xmm13, -16*3(%rbp) - movaps %xmm14, -16*2(%rbp) - movaps %xmm15, -16*1(%rbp) -___ -$code.=<<___; - mov %rbp, %rsp - pop %rbp - ret -.size ecp_nistz256_avx2_point_add_affine_x4,.-ecp_nistz256_avx2_point_add_affine_x4 - -################################################################################ -# void ecp_nistz256_avx2_point_add_affines_x4(void* RESULTx4, void *Ax4, void *Bx4); -.globl ecp_nistz256_avx2_point_add_affines_x4 -.type ecp_nistz256_avx2_point_add_affines_x4,\@function,3 -.align 32 -ecp_nistz256_avx2_point_add_affines_x4: - mov %rsp, %rax - push %rbp - vzeroupper -___ -$code.=<<___ if ($win64); - lea -16*10(%rsp), %rsp - vmovaps %xmm6, -8-16*10(%rax) - vmovaps %xmm7, -8-16*9(%rax) - vmovaps %xmm8, -8-16*8(%rax) - vmovaps %xmm9, -8-16*7(%rax) - vmovaps %xmm10, -8-16*6(%rax) - vmovaps %xmm11, -8-16*5(%rax) - vmovaps %xmm12, -8-16*4(%rax) - vmovaps %xmm13, -8-16*3(%rax) - vmovaps %xmm14, -8-16*2(%rax) - vmovaps %xmm15, -8-16*1(%rax) -___ -$code.=<<___; - lea -8(%rax), %rbp - -# Result + 32*0 = Result.X -# Result + 32*9 = Result.Y -# Result + 32*18 = Result.Z - -# A + 32*0 = A.X -# A + 32*9 = A.Y - -# B + 32*0 = B.X -# B + 32*9 = B.Y - - sub \$`32*9*8+32*2+32*8`, %rsp - and \$-64, %rsp - - mov $r_ptr_in, $r_ptr - mov $a_ptr_in, $a_ptr - mov $b_ptr_in, $b_ptr - - vmovdqa 32*0($a_ptr_in), %ymm0 - vmovdqa .LAVX2_AND_MASK(%rip), $AND_MASK - vpxor %ymm1, %ymm1, %ymm1 - lea 256($a_ptr_in), %rax # size optimization - vpor 32*1($a_ptr_in), %ymm0, %ymm0 - vpor 32*2($a_ptr_in), %ymm0, %ymm0 - vpor 32*3($a_ptr_in), %ymm0, %ymm0 - vpor 32*4-256(%rax), %ymm0, %ymm0 - lea 256(%rax), %rcx # size optimization - vpor 32*5-256(%rax), %ymm0, %ymm0 - vpor 32*6-256(%rax), %ymm0, %ymm0 - vpor 32*7-256(%rax), %ymm0, %ymm0 - vpor 32*8-256(%rax), %ymm0, %ymm0 - vpor 32*9-256(%rax), %ymm0, %ymm0 - vpor 32*10-256(%rax), %ymm0, %ymm0 - vpor 32*11-256(%rax), %ymm0, %ymm0 - vpor 32*12-512(%rcx), %ymm0, %ymm0 - vpor 32*13-512(%rcx), %ymm0, %ymm0 - vpor 32*14-512(%rcx), %ymm0, %ymm0 - vpor 32*15-512(%rcx), %ymm0, %ymm0 - vpor 32*16-512(%rcx), %ymm0, %ymm0 - vpor 32*17-512(%rcx), %ymm0, %ymm0 - vpcmpeqq %ymm1, %ymm0, %ymm0 - vmovdqa %ymm0, `32*9*8`(%rsp) - - vpxor %ymm1, %ymm1, %ymm1 - vmovdqa 32*0($b_ptr), %ymm0 - lea 256($b_ptr), %rax # size optimization - vpor 32*1($b_ptr), %ymm0, %ymm0 - vpor 32*2($b_ptr), %ymm0, %ymm0 - vpor 32*3($b_ptr), %ymm0, %ymm0 - vpor 32*4-256(%rax), %ymm0, %ymm0 - lea 256(%rax), %rcx # size optimization - vpor 32*5-256(%rax), %ymm0, %ymm0 - vpor 32*6-256(%rax), %ymm0, %ymm0 - vpor 32*7-256(%rax), %ymm0, %ymm0 - vpor 32*8-256(%rax), %ymm0, %ymm0 - vpor 32*9-256(%rax), %ymm0, %ymm0 - vpor 32*10-256(%rax), %ymm0, %ymm0 - vpor 32*11-256(%rax), %ymm0, %ymm0 - vpor 32*12-512(%rcx), %ymm0, %ymm0 - vpor 32*13-512(%rcx), %ymm0, %ymm0 - vpor 32*14-512(%rcx), %ymm0, %ymm0 - vpor 32*15-512(%rcx), %ymm0, %ymm0 - vpor 32*16-512(%rcx), %ymm0, %ymm0 - vpor 32*17-512(%rcx), %ymm0, %ymm0 - vpcmpeqq %ymm1, %ymm0, %ymm0 - vmovdqa %ymm0, `32*9*8+32`(%rsp) - - # H = U2 - U1 = X2 - X1 - lea `32*9*0`($b_ptr), %rsi - lea `32*9*0`($a_ptr), %rdx - lea `32*9*3`(%rsp), %rdi - call avx2_sub_x4 - call avx2_normalize_n_store - - # R = S2 - S1 = Y2 - Y1 - lea `32*9*1`($b_ptr), %rsi - lea `32*9*1`($a_ptr), %rdx - lea `32*9*4`(%rsp), %rdi - call avx2_sub_x4 - call avx2_normalize_n_store - - # Z3 = H*Z1*Z2 = H - lea `32*9*3`(%rsp), %rsi - lea `32*9*2`($r_ptr), %rdi - call avx2_mul_by1_x4 - call avx2_normalize - - vmovdqa `32*9*8`(%rsp), $B - vpor `32*9*8+32`(%rsp), $B, $B - - vpandn $ACC0, $B, $ACC0 - lea .LONE+128(%rip), %rax - vpandn $ACC1, $B, $ACC1 - vpandn $ACC2, $B, $ACC2 - vpandn $ACC3, $B, $ACC3 - vpandn $ACC4, $B, $ACC4 - vpandn $ACC5, $B, $ACC5 - vpandn $ACC6, $B, $ACC6 - vpandn $ACC7, $B, $ACC7 - - vpand 32*0-128(%rax), $B, $T0 - vpandn $ACC8, $B, $ACC8 - vpand 32*1-128(%rax), $B, $Y - vpxor $T0, $ACC0, $ACC0 - vpand 32*2-128(%rax), $B, $T0 - vpxor $Y, $ACC1, $ACC1 - vpand 32*3-128(%rax), $B, $Y - vpxor $T0, $ACC2, $ACC2 - vpand 32*4-128(%rax), $B, $T0 - vpxor $Y, $ACC3, $ACC3 - vpand 32*5-128(%rax), $B, $Y - vpxor $T0, $ACC4, $ACC4 - vpand 32*6-128(%rax), $B, $T0 - vpxor $Y, $ACC5, $ACC5 - vpand 32*7-128(%rax), $B, $Y - vpxor $T0, $ACC6, $ACC6 - vpand 32*8-128(%rax), $B, $T0 - vpxor $Y, $ACC7, $ACC7 - vpxor $T0, $ACC8, $ACC8 - `&STORE` - - # R^2 = R^2 - lea `32*9*4`(%rsp), %rsi - lea `32*9*6`(%rsp), %rdi - lea `32*9*8+32*2`(%rsp), %rcx # temporary vector - call avx2_sqr_x4 - call avx2_normalize_n_store - - # H^2 = H^2 - lea `32*9*3`(%rsp), %rsi - lea `32*9*5`(%rsp), %rdi - call avx2_sqr_x4 - call avx2_normalize_n_store - - # H^3 = H^2*H - lea `32*9*3`(%rsp), %rsi - lea `32*9*5`(%rsp), %rdx - lea `32*9*7`(%rsp), %rdi - call avx2_mul_x4 - call avx2_normalize_n_store - - # U2 = U1*H^2 - lea `32*9*0`($a_ptr), %rsi - lea `32*9*5`(%rsp), %rdx - lea `32*9*0`(%rsp), %rdi - call avx2_mul_x4 - #call avx2_normalize - `&STORE` - - # Hsqr = U2*2 - #lea 32*9*0(%rsp), %rsi - #lea 32*9*5(%rsp), %rdi - #call avx2_mul_by2_x4 - - vpaddq $ACC0, $ACC0, $ACC0 # inlined avx2_mul_by2_x4 - lea `32*9*5`(%rsp), %rdi - vpaddq $ACC1, $ACC1, $ACC1 - vpaddq $ACC2, $ACC2, $ACC2 - vpaddq $ACC3, $ACC3, $ACC3 - vpaddq $ACC4, $ACC4, $ACC4 - vpaddq $ACC5, $ACC5, $ACC5 - vpaddq $ACC6, $ACC6, $ACC6 - vpaddq $ACC7, $ACC7, $ACC7 - vpaddq $ACC8, $ACC8, $ACC8 - call avx2_normalize_n_store - - # X3 = R^2 - H^3 - #lea 32*9*6(%rsp), %rsi - #lea 32*9*7(%rsp), %rdx - #lea 32*9*5(%rsp), %rcx - #lea 32*9*0($r_ptr), %rdi - #call avx2_sub_x4 - #NORMALIZE - #STORE - - # X3 = X3 - U2*2 - #lea 32*9*0($r_ptr), %rsi - #lea 32*9*0($r_ptr), %rdi - #call avx2_sub_x4 - #NORMALIZE - #STORE - - lea `32*9*6+128`(%rsp), %rsi - lea .LAVX2_POLY_x2+128(%rip), %rax - lea `32*9*7+128`(%rsp), %rdx - lea `32*9*5+128`(%rsp), %rcx - lea `32*9*0`($r_ptr), %rdi - - vmovdqa 32*0-128(%rsi), $ACC0 - vmovdqa 32*1-128(%rsi), $ACC1 - vmovdqa 32*2-128(%rsi), $ACC2 - vmovdqa 32*3-128(%rsi), $ACC3 - vmovdqa 32*4-128(%rsi), $ACC4 - vmovdqa 32*5-128(%rsi), $ACC5 - vmovdqa 32*6-128(%rsi), $ACC6 - vmovdqa 32*7-128(%rsi), $ACC7 - vmovdqa 32*8-128(%rsi), $ACC8 - - vpaddq 32*0-128(%rax), $ACC0, $ACC0 - vpaddq 32*1-128(%rax), $ACC1, $ACC1 - vpaddq 32*2-128(%rax), $ACC2, $ACC2 - vpaddq 32*3-128(%rax), $ACC3, $ACC3 - vpaddq 32*4-128(%rax), $ACC4, $ACC4 - vpaddq 32*5-128(%rax), $ACC5, $ACC5 - vpaddq 32*6-128(%rax), $ACC6, $ACC6 - vpaddq 32*7-128(%rax), $ACC7, $ACC7 - vpaddq 32*8-128(%rax), $ACC8, $ACC8 - - vpsubq 32*0-128(%rdx), $ACC0, $ACC0 - vpsubq 32*1-128(%rdx), $ACC1, $ACC1 - vpsubq 32*2-128(%rdx), $ACC2, $ACC2 - vpsubq 32*3-128(%rdx), $ACC3, $ACC3 - vpsubq 32*4-128(%rdx), $ACC4, $ACC4 - vpsubq 32*5-128(%rdx), $ACC5, $ACC5 - vpsubq 32*6-128(%rdx), $ACC6, $ACC6 - vpsubq 32*7-128(%rdx), $ACC7, $ACC7 - vpsubq 32*8-128(%rdx), $ACC8, $ACC8 - - vpsubq 32*0-128(%rcx), $ACC0, $ACC0 - vpsubq 32*1-128(%rcx), $ACC1, $ACC1 - vpsubq 32*2-128(%rcx), $ACC2, $ACC2 - vpsubq 32*3-128(%rcx), $ACC3, $ACC3 - vpsubq 32*4-128(%rcx), $ACC4, $ACC4 - vpsubq 32*5-128(%rcx), $ACC5, $ACC5 - vpsubq 32*6-128(%rcx), $ACC6, $ACC6 - vpsubq 32*7-128(%rcx), $ACC7, $ACC7 - vpsubq 32*8-128(%rcx), $ACC8, $ACC8 - call avx2_normalize - - lea 32*0($b_ptr), %rsi - lea 32*0($a_ptr), %rdx - call avx2_select_n_store - - # H = U2 - X3 - lea `32*9*0`(%rsp), %rsi - lea `32*9*0`($r_ptr), %rdx - lea `32*9*3`(%rsp), %rdi - call avx2_sub_x4 - call avx2_normalize_n_store - - # H = H*R - lea `32*9*3`(%rsp), %rsi - lea `32*9*4`(%rsp), %rdx - lea `32*9*3`(%rsp), %rdi - call avx2_mul_x4 - call avx2_normalize_n_store - - # S2 = S1 * H^3 - lea `32*9*7`(%rsp), %rsi - lea `32*9*1`($a_ptr), %rdx - lea `32*9*1`(%rsp), %rdi - call avx2_mul_x4 - call avx2_normalize_n_store - - # - lea `32*9*3`(%rsp), %rsi - lea `32*9*1`(%rsp), %rdx - lea `32*9*1`($r_ptr), %rdi - call avx2_sub_x4 - call avx2_normalize - - lea 32*9($b_ptr), %rsi - lea 32*9($a_ptr), %rdx - call avx2_select_n_store - - #lea 32*9*0($r_ptr), %rsi - #lea 32*9*0($r_ptr), %rdi - #call avx2_mul_by1_x4 - #NORMALIZE - #STORE - - lea `32*9*1`($r_ptr), %rsi - lea `32*9*1`($r_ptr), %rdi - call avx2_mul_by1_x4 - call avx2_normalize_n_store - - vzeroupper -___ -$code.=<<___ if ($win64); - movaps %xmm6, -16*10(%rbp) - movaps %xmm7, -16*9(%rbp) - movaps %xmm8, -16*8(%rbp) - movaps %xmm9, -16*7(%rbp) - movaps %xmm10, -16*6(%rbp) - movaps %xmm11, -16*5(%rbp) - movaps %xmm12, -16*4(%rbp) - movaps %xmm13, -16*3(%rbp) - movaps %xmm14, -16*2(%rbp) - movaps %xmm15, -16*1(%rbp) -___ -$code.=<<___; - mov %rbp, %rsp - pop %rbp - ret -.size ecp_nistz256_avx2_point_add_affines_x4,.-ecp_nistz256_avx2_point_add_affines_x4 - -################################################################################ -# void ecp_nistz256_avx2_to_mont(void* RESULTx4, void *Ax4); -.globl ecp_nistz256_avx2_to_mont -.type ecp_nistz256_avx2_to_mont,\@function,2 -.align 32 -ecp_nistz256_avx2_to_mont: - vzeroupper -___ -$code.=<<___ if ($win64); - lea -8-16*10(%rsp), %rsp - vmovaps %xmm6, -8-16*10(%rax) - vmovaps %xmm7, -8-16*9(%rax) - vmovaps %xmm8, -8-16*8(%rax) - vmovaps %xmm9, -8-16*7(%rax) - vmovaps %xmm10, -8-16*6(%rax) - vmovaps %xmm11, -8-16*5(%rax) - vmovaps %xmm12, -8-16*4(%rax) - vmovaps %xmm13, -8-16*3(%rax) - vmovaps %xmm14, -8-16*2(%rax) - vmovaps %xmm15, -8-16*1(%rax) -___ -$code.=<<___; - vmovdqa .LAVX2_AND_MASK(%rip), $AND_MASK - lea .LTO_MONT_AVX2(%rip), %rdx - call avx2_mul_x4 - call avx2_normalize_n_store - - vzeroupper -___ -$code.=<<___ if ($win64); - movaps 16*0(%rsp), %xmm6 - movaps 16*1(%rsp), %xmm7 - movaps 16*2(%rsp), %xmm8 - movaps 16*3(%rsp), %xmm9 - movaps 16*4(%rsp), %xmm10 - movaps 16*5(%rsp), %xmm11 - movaps 16*6(%rsp), %xmm12 - movaps 16*7(%rsp), %xmm13 - movaps 16*8(%rsp), %xmm14 - movaps 16*9(%rsp), %xmm15 - lea 8+16*10(%rsp), %rsp -___ -$code.=<<___; - ret -.size ecp_nistz256_avx2_to_mont,.-ecp_nistz256_avx2_to_mont - -################################################################################ -# void ecp_nistz256_avx2_from_mont(void* RESULTx4, void *Ax4); -.globl ecp_nistz256_avx2_from_mont -.type ecp_nistz256_avx2_from_mont,\@function,2 -.align 32 -ecp_nistz256_avx2_from_mont: - vzeroupper -___ -$code.=<<___ if ($win64); - lea -8-16*10(%rsp), %rsp - vmovaps %xmm6, -8-16*10(%rax) - vmovaps %xmm7, -8-16*9(%rax) - vmovaps %xmm8, -8-16*8(%rax) - vmovaps %xmm9, -8-16*7(%rax) - vmovaps %xmm10, -8-16*6(%rax) - vmovaps %xmm11, -8-16*5(%rax) - vmovaps %xmm12, -8-16*4(%rax) - vmovaps %xmm13, -8-16*3(%rax) - vmovaps %xmm14, -8-16*2(%rax) - vmovaps %xmm15, -8-16*1(%rax) -___ -$code.=<<___; - vmovdqa .LAVX2_AND_MASK(%rip), $AND_MASK - lea .LFROM_MONT_AVX2(%rip), %rdx - call avx2_mul_x4 - call avx2_normalize_n_store - - vzeroupper -___ -$code.=<<___ if ($win64); - movaps 16*0(%rsp), %xmm6 - movaps 16*1(%rsp), %xmm7 - movaps 16*2(%rsp), %xmm8 - movaps 16*3(%rsp), %xmm9 - movaps 16*4(%rsp), %xmm10 - movaps 16*5(%rsp), %xmm11 - movaps 16*6(%rsp), %xmm12 - movaps 16*7(%rsp), %xmm13 - movaps 16*8(%rsp), %xmm14 - movaps 16*9(%rsp), %xmm15 - lea 8+16*10(%rsp), %rsp -___ -$code.=<<___; - ret -.size ecp_nistz256_avx2_from_mont,.-ecp_nistz256_avx2_from_mont - -################################################################################ -# void ecp_nistz256_avx2_set1(void* RESULTx4); -.globl ecp_nistz256_avx2_set1 -.type ecp_nistz256_avx2_set1,\@function,1 -.align 32 -ecp_nistz256_avx2_set1: - lea .LONE+128(%rip), %rax - lea 128(%rdi), %rdi - vzeroupper - vmovdqa 32*0-128(%rax), %ymm0 - vmovdqa 32*1-128(%rax), %ymm1 - vmovdqa 32*2-128(%rax), %ymm2 - vmovdqa 32*3-128(%rax), %ymm3 - vmovdqa 32*4-128(%rax), %ymm4 - vmovdqa 32*5-128(%rax), %ymm5 - vmovdqa %ymm0, 32*0-128(%rdi) - vmovdqa 32*6-128(%rax), %ymm0 - vmovdqa %ymm1, 32*1-128(%rdi) - vmovdqa 32*7-128(%rax), %ymm1 - vmovdqa %ymm2, 32*2-128(%rdi) - vmovdqa 32*8-128(%rax), %ymm2 - vmovdqa %ymm3, 32*3-128(%rdi) - vmovdqa %ymm4, 32*4-128(%rdi) - vmovdqa %ymm5, 32*5-128(%rdi) - vmovdqa %ymm0, 32*6-128(%rdi) - vmovdqa %ymm1, 32*7-128(%rdi) - vmovdqa %ymm2, 32*8-128(%rdi) - - vzeroupper - ret -.size ecp_nistz256_avx2_set1,.-ecp_nistz256_avx2_set1 -___ -} -{ -################################################################################ -# void ecp_nistz256_avx2_multi_gather_w7(void* RESULT, void *in, -# int index0, int index1, int index2, int index3); -################################################################################ - -my ($val,$in_t,$index0,$index1,$index2,$index3)=("%rdi","%rsi","%edx","%ecx","%r8d","%r9d"); -my ($INDEX0,$INDEX1,$INDEX2,$INDEX3)=map("%ymm$_",(0..3)); -my ($R0a,$R0b,$R1a,$R1b,$R2a,$R2b,$R3a,$R3b)=map("%ymm$_",(4..11)); -my ($M0,$T0,$T1,$TMP0)=map("%ymm$_",(12..15)); - -$code.=<<___; -.globl ecp_nistz256_avx2_multi_gather_w7 -.type ecp_nistz256_avx2_multi_gather_w7,\@function,6 -.align 32 -ecp_nistz256_avx2_multi_gather_w7: - vzeroupper -___ -$code.=<<___ if ($win64); - lea -8-16*10(%rsp), %rsp - vmovaps %xmm6, -8-16*10(%rax) - vmovaps %xmm7, -8-16*9(%rax) - vmovaps %xmm8, -8-16*8(%rax) - vmovaps %xmm9, -8-16*7(%rax) - vmovaps %xmm10, -8-16*6(%rax) - vmovaps %xmm11, -8-16*5(%rax) - vmovaps %xmm12, -8-16*4(%rax) - vmovaps %xmm13, -8-16*3(%rax) - vmovaps %xmm14, -8-16*2(%rax) - vmovaps %xmm15, -8-16*1(%rax) -___ -$code.=<<___; - lea .LIntOne(%rip), %rax - - vmovd $index0, %xmm0 - vmovd $index1, %xmm1 - vmovd $index2, %xmm2 - vmovd $index3, %xmm3 - - vpxor $R0a, $R0a, $R0a - vpxor $R0b, $R0b, $R0b - vpxor $R1a, $R1a, $R1a - vpxor $R1b, $R1b, $R1b - vpxor $R2a, $R2a, $R2a - vpxor $R2b, $R2b, $R2b - vpxor $R3a, $R3a, $R3a - vpxor $R3b, $R3b, $R3b - vmovdqa (%rax), $M0 - - vpermd $INDEX0, $R0a, $INDEX0 - vpermd $INDEX1, $R0a, $INDEX1 - vpermd $INDEX2, $R0a, $INDEX2 - vpermd $INDEX3, $R0a, $INDEX3 - - mov \$64, %ecx - lea 112($val), $val # size optimization - jmp .Lmulti_select_loop_avx2 - -# INDEX=0, corresponds to the point at infty (0,0) -.align 32 -.Lmulti_select_loop_avx2: - vpcmpeqd $INDEX0, $M0, $TMP0 - - vmovdqa `32*0+32*64*2*0`($in_t), $T0 - vmovdqa `32*1+32*64*2*0`($in_t), $T1 - vpand $TMP0, $T0, $T0 - vpand $TMP0, $T1, $T1 - vpxor $T0, $R0a, $R0a - vpxor $T1, $R0b, $R0b - - vpcmpeqd $INDEX1, $M0, $TMP0 - - vmovdqa `32*0+32*64*2*1`($in_t), $T0 - vmovdqa `32*1+32*64*2*1`($in_t), $T1 - vpand $TMP0, $T0, $T0 - vpand $TMP0, $T1, $T1 - vpxor $T0, $R1a, $R1a - vpxor $T1, $R1b, $R1b - - vpcmpeqd $INDEX2, $M0, $TMP0 - - vmovdqa `32*0+32*64*2*2`($in_t), $T0 - vmovdqa `32*1+32*64*2*2`($in_t), $T1 - vpand $TMP0, $T0, $T0 - vpand $TMP0, $T1, $T1 - vpxor $T0, $R2a, $R2a - vpxor $T1, $R2b, $R2b - - vpcmpeqd $INDEX3, $M0, $TMP0 - - vmovdqa `32*0+32*64*2*3`($in_t), $T0 - vmovdqa `32*1+32*64*2*3`($in_t), $T1 - vpand $TMP0, $T0, $T0 - vpand $TMP0, $T1, $T1 - vpxor $T0, $R3a, $R3a - vpxor $T1, $R3b, $R3b - - vpaddd (%rax), $M0, $M0 # increment - lea 32*2($in_t), $in_t - - dec %ecx - jnz .Lmulti_select_loop_avx2 - - vmovdqu $R0a, 32*0-112($val) - vmovdqu $R0b, 32*1-112($val) - vmovdqu $R1a, 32*2-112($val) - vmovdqu $R1b, 32*3-112($val) - vmovdqu $R2a, 32*4-112($val) - vmovdqu $R2b, 32*5-112($val) - vmovdqu $R3a, 32*6-112($val) - vmovdqu $R3b, 32*7-112($val) - - vzeroupper -___ -$code.=<<___ if ($win64); - movaps 16*0(%rsp), %xmm6 - movaps 16*1(%rsp), %xmm7 - movaps 16*2(%rsp), %xmm8 - movaps 16*3(%rsp), %xmm9 - movaps 16*4(%rsp), %xmm10 - movaps 16*5(%rsp), %xmm11 - movaps 16*6(%rsp), %xmm12 - movaps 16*7(%rsp), %xmm13 - movaps 16*8(%rsp), %xmm14 - movaps 16*9(%rsp), %xmm15 - lea 8+16*10(%rsp), %rsp -___ -$code.=<<___; - ret -.size ecp_nistz256_avx2_multi_gather_w7,.-ecp_nistz256_avx2_multi_gather_w7 - -.extern OPENSSL_ia32cap_P -.globl ecp_nistz_avx2_eligible -.type ecp_nistz_avx2_eligible,\@abi-omnipotent -.align 32 -ecp_nistz_avx2_eligible: - mov OPENSSL_ia32cap_P+8(%rip),%eax - shr \$5,%eax - and \$1,%eax - ret -.size ecp_nistz_avx2_eligible,.-ecp_nistz_avx2_eligible -___ -} -}} else {{ # assembler is too old -$code.=<<___; -.text - -.globl ecp_nistz256_avx2_transpose_convert -.globl ecp_nistz256_avx2_convert_transpose_back -.globl ecp_nistz256_avx2_point_add_affine_x4 -.globl ecp_nistz256_avx2_point_add_affines_x4 -.globl ecp_nistz256_avx2_to_mont -.globl ecp_nistz256_avx2_from_mont -.globl ecp_nistz256_avx2_set1 -.globl ecp_nistz256_avx2_multi_gather_w7 -.type ecp_nistz256_avx2_multi_gather_w7,\@abi-omnipotent -ecp_nistz256_avx2_transpose_convert: -ecp_nistz256_avx2_convert_transpose_back: -ecp_nistz256_avx2_point_add_affine_x4: -ecp_nistz256_avx2_point_add_affines_x4: -ecp_nistz256_avx2_to_mont: -ecp_nistz256_avx2_from_mont: -ecp_nistz256_avx2_set1: -ecp_nistz256_avx2_multi_gather_w7: - .byte 0x0f,0x0b # ud2 - ret -.size ecp_nistz256_avx2_multi_gather_w7,.-ecp_nistz256_avx2_multi_gather_w7 - -.globl ecp_nistz_avx2_eligible -.type ecp_nistz_avx2_eligible,\@abi-omnipotent -ecp_nistz_avx2_eligible: - xor %eax,%eax - ret -.size ecp_nistz_avx2_eligible,.-ecp_nistz_avx2_eligible -___ -}} - -foreach (split("\n",$code)) { - s/\`([^\`]*)\`/eval($1)/geo; - - print $_,"\n"; -} - -close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c index 98d12892..95097c67 100644 --- a/crypto/ec/ec2_smpl.c +++ b/crypto/ec/ec2_smpl.c @@ -489,7 +489,8 @@ int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) /* point is its own inverse */ return 1; - if (!EC_POINT_make_affine(group, point, ctx)) + if (group->meth->make_affine == NULL + || !group->meth->make_affine(group, point, ctx)) return 0; return BN_GF2m_add(point->Y, point->X, point->Y); } diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index cac0b682..6ccaef38 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -141,7 +141,7 @@ static EC_KEY *eckey_type2param(int ptype, const void *pval) return NULL; } -static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) { const unsigned char *p = NULL; const void *pval; diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index b2c91efb..a53573cc 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -27,8 +27,7 @@ int EC_GROUP_get_basis_type(const EC_GROUP *group) { int i; - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_characteristic_two_field) + if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field) /* everything else is currently not supported */ return 0; @@ -53,8 +52,7 @@ int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) if (group == NULL) return 0; - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_characteristic_two_field + if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] == 0))) { ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, @@ -74,8 +72,7 @@ int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, if (group == NULL) return 0; - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_characteristic_two_field + if (EC_GROUP_get_field_type(group) != NID_X9_62_characteristic_two_field || !((group->poly[0] != 0) && (group->poly[1] != 0) && (group->poly[2] != 0) && (group->poly[3] != 0) && (group->poly[4] == 0))) { @@ -262,7 +259,7 @@ static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) ASN1_OBJECT_free(field->fieldType); ASN1_TYPE_free(field->p.other); - nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); + nid = EC_GROUP_get_field_type(group); /* set OID for the field */ if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) { ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c index 98dd0ecf..fb6497b0 100644 --- a/crypto/ec/ec_backend.c +++ b/crypto/ec/ec_backend.c @@ -19,15 +19,10 @@ * implementations alike. */ -int ec_set_param_ecdh_cofactor_mode(EC_KEY *ec, const OSSL_PARAM *p) +int ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode) { const EC_GROUP *ecg = EC_KEY_get0_group(ec); const BIGNUM *cofactor; - int mode; - - if (!OSSL_PARAM_get_int(p, &mode)) - return 0; - /* * mode can be only 0 for disable, or 1 for enable here. * @@ -224,8 +219,12 @@ int ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) return 0; p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH); - if (p != NULL && !ec_set_param_ecdh_cofactor_mode(ec, p)) - return 0; + if (p != NULL) { + int mode; + if (!OSSL_PARAM_get_int(p, &mode) + || !ec_set_ecdh_cofactor_mode(ec, mode)) + return 0; + } return 1; } diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c index 9f929883..3be62b36 100644 --- a/crypto/ec/ec_curve.c +++ b/crypto/ec/ec_curve.c @@ -3195,7 +3195,7 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx, /* If no curve data curve method must handle everything */ if (curve.data == NULL) - return EC_GROUP_new_ex(libctx, + return ec_group_new_ex(libctx, curve.meth != NULL ? curve.meth() : NULL); if ((ctx = BN_CTX_new_ex(libctx)) == NULL) { @@ -3218,7 +3218,7 @@ static EC_GROUP *ec_group_new_from_data(OPENSSL_CTX *libctx, if (curve.meth != 0) { meth = curve.meth(); - if (((group = EC_GROUP_new_ex(libctx, meth)) == NULL) || + if (((group = ec_group_new_ex(libctx, meth)) == NULL) || (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); goto err; @@ -3388,17 +3388,13 @@ int ec_curve_nid_from_params(const EC_GROUP *group, BN_CTX *ctx) unsigned char *param_bytes = NULL; const EC_CURVE_DATA *data; const EC_POINT *generator = NULL; - const EC_METHOD *meth; const BIGNUM *cofactor = NULL; /* An array of BIGNUMs for (p, a, b, x, y, order) */ BIGNUM *bn[NUM_BN_FIELDS] = {NULL, NULL, NULL, NULL, NULL, NULL}; - meth = EC_GROUP_method_of(group); - if (meth == NULL) - return -1; /* Use the optional named curve nid as a search field */ nid = EC_GROUP_get_curve_name(group); - field_type = EC_METHOD_get_field_type(meth); + field_type = EC_GROUP_get_field_type(group); seed_len = EC_GROUP_get_seed_len(group); seed = EC_GROUP_get0_seed(group); cofactor = EC_GROUP_get0_cofactor(group); diff --git a/crypto/ec/ec_cvt.c b/crypto/ec/ec_cvt.c index 6d58fdbe..a8ea6fe7 100644 --- a/crypto/ec/ec_cvt.c +++ b/crypto/ec/ec_cvt.c @@ -54,7 +54,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, meth = EC_GFp_mont_method(); #endif - ret = EC_GROUP_new_ex(bn_get_lib_ctx(ctx), meth); + ret = ec_group_new_ex(bn_get_lib_ctx(ctx), meth); if (ret == NULL) return NULL; @@ -75,7 +75,7 @@ EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, meth = EC_GF2m_simple_method(); - ret = EC_GROUP_new_ex(bn_get_lib_ctx(ctx), meth); + ret = ec_group_new_ex(bn_get_lib_ctx(ctx), meth); if (ret == NULL) return NULL; diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index 421e87d9..47feede5 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -117,10 +117,9 @@ EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) dest->libctx = src->libctx; /* copy the parameters */ if (src->group != NULL) { - const EC_METHOD *meth = EC_GROUP_method_of(src->group); /* clear the old group */ EC_GROUP_free(dest->group); - dest->group = EC_GROUP_new_ex(src->libctx, meth); + dest->group = ec_group_new_ex(src->libctx, src->group->meth); if (dest->group == NULL) return NULL; if (!EC_GROUP_copy(dest->group, src->group)) @@ -398,7 +397,7 @@ static int ec_key_public_range_check(BN_CTX *ctx, const EC_KEY *key) if (!EC_POINT_get_affine_coordinates(key->group, key->pub_key, x, y, ctx)) goto err; - if (EC_METHOD_get_field_type(key->group->meth) == NID_X9_62_prime_field) { + if (EC_GROUP_get_field_type(key->group) == NID_X9_62_prime_field) { if (BN_is_negative(x) || BN_cmp(x, key->group->field) >= 0 || BN_is_negative(y) @@ -781,12 +780,14 @@ void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) EC_GROUP_set_asn1_flag(key->group, flag); } +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) { if (key->group == NULL) return 0; return EC_GROUP_precompute_mult(key->group, ctx); } +#endif int EC_KEY_get_flags(const EC_KEY *key) { diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index cdeffb42..f62eff50 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -23,7 +23,7 @@ /* functions for EC_GROUP objects */ -EC_GROUP *EC_GROUP_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth) +EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth) { EC_GROUP *ret; @@ -65,11 +65,13 @@ EC_GROUP *EC_GROUP_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth) return NULL; } -#ifndef FIPS_MODULE +#ifndef OPENSSL_NO_DEPRECATED_3_0 +# ifndef FIPS_MODULE EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) { - return EC_GROUP_new_ex(NULL, meth); + return ec_group_new_ex(NULL, meth); } +# endif #endif void EC_pre_comp_free(EC_GROUP *group) @@ -255,7 +257,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) if (a == NULL) return NULL; - if ((t = EC_GROUP_new_ex(a->libctx, a->meth)) == NULL) + if ((t = ec_group_new_ex(a->libctx, a->meth)) == NULL) return NULL; if (!EC_GROUP_copy(t, a)) goto err; @@ -270,6 +272,7 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) return t; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) { return group->meth; @@ -279,6 +282,7 @@ int EC_METHOD_get_field_type(const EC_METHOD *meth) { return meth->field_type; } +#endif static int ec_precompute_mont_data(EC_GROUP *); @@ -475,6 +479,11 @@ const BIGNUM *EC_GROUP_get0_field(const EC_GROUP *group) return group->field; } +int EC_GROUP_get_field_type(const EC_GROUP *group) +{ + return group->meth->field_type; +} + void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) { group->asn1_flag = flag; @@ -602,8 +611,7 @@ int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) #endif /* compare the field types */ - if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != - EC_METHOD_get_field_type(EC_GROUP_method_of(b))) + if (EC_GROUP_get_field_type(a) != EC_GROUP_get_field_type(b)) return 1; /* compare the curve name (if present in both) */ if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && @@ -777,10 +785,12 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) return t; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 const EC_METHOD *EC_POINT_method_of(const EC_POINT *point) { return point->meth; } +#endif int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) { @@ -1004,6 +1014,7 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, return group->meth->point_cmp(group, a, b, ctx); } +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { if (group->meth->make_affine == 0) { @@ -1034,6 +1045,7 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, } return group->meth->points_make_affine(group, num, points, ctx); } +#endif /* * Functions for point multiplication. If group->meth->mul is 0, we use the @@ -1093,6 +1105,7 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) { int ret = 0; + size_t num; #ifndef FIPS_MODULE BN_CTX *new_ctx = NULL; #endif @@ -1115,13 +1128,12 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, return 0; } + num = (point != NULL && p_scalar != NULL) ? 1 : 0; if (group->meth->mul != NULL) - ret = group->meth->mul(group, r, g_scalar, point != NULL - && p_scalar != NULL, &point, &p_scalar, ctx); + ret = group->meth->mul(group, r, g_scalar, num, &point, &p_scalar, ctx); else /* use default */ - ret = ec_wNAF_mul(group, r, g_scalar, point != NULL - && p_scalar != NULL, &point, &p_scalar, ctx); + ret = ec_wNAF_mul(group, r, g_scalar, num, &point, &p_scalar, ctx); #ifndef FIPS_MODULE BN_CTX_free(new_ctx); @@ -1129,6 +1141,7 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, return ret; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) { if (group->meth->mul == 0) @@ -1153,6 +1166,7 @@ int EC_GROUP_have_precompute_mult(const EC_GROUP *group) return 0; /* cannot tell whether precomputation has * been performed */ } +#endif /* * ec_precompute_mont_data sets |group->mont_data| from |group->order| and diff --git a/crypto/ec/ec_local.h b/crypto/ec/ec_local.h index d9383f10..7f9b61bc 100644 --- a/crypto/ec/ec_local.h +++ b/crypto/ec/ec_local.h @@ -31,6 +31,10 @@ /* Curve does not support signing operations */ #define EC_FLAGS_NO_SIGN 0x4 +#ifdef OPENSSL_NO_DEPRECATED_3_0 +typedef struct ec_method_st EC_METHOD; +#endif + /* * Structure details are not part of the exported interface, so all this may * change in future versions. @@ -585,6 +589,15 @@ void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, #endif int ec_group_simple_order_bits(const EC_GROUP *group); +/** + * Creates a new EC_GROUP object + * \param libctx The associated library context or NULL for the default + * library context + * \param meth EC_METHOD to use + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *ec_group_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth); + #ifdef ECP_NISTZ256_ASM /** Returns GFp methods using montgomery multiplication, with x86-64 optimized * P256. See http://eprint.iacr.org/2013/816. diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c index 33721845..aea2afd5 100644 --- a/crypto/ec/ec_mult.c +++ b/crypto/ec/ec_mult.c @@ -267,7 +267,8 @@ int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r, } /* ensure input point is in affine coords for ladder step efficiency */ - if (!p->Z_is_one && !EC_POINT_make_affine(group, p, ctx)) { + if (!p->Z_is_one && (group->meth->make_affine == NULL + || !group->meth->make_affine(group, p, ctx))) { ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB); goto err; } @@ -711,7 +712,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, } } - if (!EC_POINTs_make_affine(group, num_val, val, ctx)) + if (group->meth->points_make_affine == NULL + || !group->meth->points_make_affine(group, num_val, val, ctx)) goto err; r_is_at_infinity = 1; @@ -949,7 +951,8 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) } } - if (!EC_POINTs_make_affine(group, num, points, ctx)) + if (group->meth->points_make_affine == NULL + || !group->meth->points_make_affine(group, num, points, ctx)) goto err; pre_comp->group = group; diff --git a/crypto/ec/ecdh_kdf.c b/crypto/ec/ecdh_kdf.c index fb501c6a..a502846d 100644 --- a/crypto/ec/ecdh_kdf.c +++ b/crypto/ec/ecdh_kdf.c @@ -32,7 +32,7 @@ int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, const char *mdname = EVP_MD_name(md); EVP_KDF *kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_X963KDF, NULL); - if ((kctx = EVP_KDF_CTX_new(kdf)) != NULL) { + if ((kctx = EVP_KDF_new_ctx(kdf)) != NULL) { *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (char *)mdname, 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, @@ -41,9 +41,9 @@ int ecdh_KDF_X9_63(unsigned char *out, size_t outlen, (void *)sinfo, sinfolen); *p = OSSL_PARAM_construct_end(); - ret = EVP_KDF_CTX_set_params(kctx, params) > 0 + ret = EVP_KDF_set_ctx_params(kctx, params) > 0 && EVP_KDF_derive(kctx, out, outlen) > 0; - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); } EVP_KDF_free(kdf); return ret; diff --git a/crypto/ec/eck_prn.c b/crypto/ec/eck_prn.c index 51ebedd7..894219fb 100644 --- a/crypto/ec/eck_prn.c +++ b/crypto/ec/eck_prn.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -115,7 +115,7 @@ int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) /* explicit parameters */ int is_char_two = 0; point_conversion_form_t form; - int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); + int tmp_nid = EC_GROUP_get_field_type(x); if (tmp_nid == NID_X9_62_characteristic_two_field) is_char_two = 1; diff --git a/crypto/ec/ecp_nistp224.c b/crypto/ec/ecp_nistp224.c index 1808c4c7..2b665842 100644 --- a/crypto/ec/ecp_nistp224.c +++ b/crypto/ec/ecp_nistp224.c @@ -75,6 +75,7 @@ typedef uint64_t u64; */ typedef uint64_t limb; +typedef uint64_t limb_aX __attribute((__aligned__(1))); typedef uint128_t widelimb; typedef limb felem[4]; @@ -311,10 +312,10 @@ const EC_METHOD *EC_GFp_nistp224_method(void) */ static void bin28_to_felem(felem out, const u8 in[28]) { - out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff; - out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff; - out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff; - out[3] = (*((const uint64_t *)(in+20))) >> 8; + out[0] = *((const limb *)(in)) & 0x00ffffffffffffff; + out[1] = (*((const limb_aX *)(in + 7))) & 0x00ffffffffffffff; + out[2] = (*((const limb_aX *)(in + 14))) & 0x00ffffffffffffff; + out[3] = (*((const limb_aX *)(in + 20))) >> 8; } static void felem_to_bin28(u8 out[28], const felem in) diff --git a/crypto/ec/ecp_nistp521.c b/crypto/ec/ecp_nistp521.c index 28e048ed..0e7f1dae 100644 --- a/crypto/ec/ecp_nistp521.c +++ b/crypto/ec/ecp_nistp521.c @@ -131,6 +131,7 @@ static const felem_bytearray nistp521_curve_params[5] = { #define NLIMBS 9 typedef uint64_t limb; +typedef limb limb_aX __attribute((__aligned__(1))); typedef limb felem[NLIMBS]; typedef uint128_t largefelem[NLIMBS]; @@ -144,14 +145,14 @@ static const limb bottom58bits = 0x3ffffffffffffff; static void bin66_to_felem(felem out, const u8 in[66]) { out[0] = (*((limb *) & in[0])) & bottom58bits; - out[1] = (*((limb *) & in[7]) >> 2) & bottom58bits; - out[2] = (*((limb *) & in[14]) >> 4) & bottom58bits; - out[3] = (*((limb *) & in[21]) >> 6) & bottom58bits; - out[4] = (*((limb *) & in[29])) & bottom58bits; - out[5] = (*((limb *) & in[36]) >> 2) & bottom58bits; - out[6] = (*((limb *) & in[43]) >> 4) & bottom58bits; - out[7] = (*((limb *) & in[50]) >> 6) & bottom58bits; - out[8] = (*((limb *) & in[58])) & bottom57bits; + out[1] = (*((limb_aX *) & in[7]) >> 2) & bottom58bits; + out[2] = (*((limb_aX *) & in[14]) >> 4) & bottom58bits; + out[3] = (*((limb_aX *) & in[21]) >> 6) & bottom58bits; + out[4] = (*((limb_aX *) & in[29])) & bottom58bits; + out[5] = (*((limb_aX *) & in[36]) >> 2) & bottom58bits; + out[6] = (*((limb_aX *) & in[43]) >> 4) & bottom58bits; + out[7] = (*((limb_aX *) & in[50]) >> 6) & bottom58bits; + out[8] = (*((limb_aX *) & in[58])) & bottom57bits; } /* @@ -162,14 +163,14 @@ static void felem_to_bin66(u8 out[66], const felem in) { memset(out, 0, 66); (*((limb *) & out[0])) = in[0]; - (*((limb *) & out[7])) |= in[1] << 2; - (*((limb *) & out[14])) |= in[2] << 4; - (*((limb *) & out[21])) |= in[3] << 6; - (*((limb *) & out[29])) = in[4]; - (*((limb *) & out[36])) |= in[5] << 2; - (*((limb *) & out[43])) |= in[6] << 4; - (*((limb *) & out[50])) |= in[7] << 6; - (*((limb *) & out[58])) = in[8]; + (*((limb_aX *) & out[7])) |= in[1] << 2; + (*((limb_aX *) & out[14])) |= in[2] << 4; + (*((limb_aX *) & out[21])) |= in[3] << 6; + (*((limb_aX *) & out[29])) = in[4]; + (*((limb_aX *) & out[36])) |= in[5] << 2; + (*((limb_aX *) & out[43])) |= in[6] << 4; + (*((limb_aX *) & out[50])) |= in[7] << 6; + (*((limb_aX *) & out[58])) = in[8]; } /* BN_to_felem converts an OpenSSL BIGNUM into an felem */ diff --git a/crypto/ec/ecp_nistz256.c b/crypto/ec/ecp_nistz256.c index 4577707e..0f1170db 100644 --- a/crypto/ec/ecp_nistz256.c +++ b/crypto/ec/ecp_nistz256.c @@ -897,7 +897,8 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) * It would be faster to use EC_POINTs_make_affine and * make multiple points affine at the same time. */ - if (!EC_POINT_make_affine(group, P, ctx)) + if (group->meth->make_affine == NULL + || !group->meth->make_affine(group, P, ctx)) goto err; if (!ecp_nistz256_bignum_to_field_elem(temp.X, P->X) || !ecp_nistz256_bignum_to_field_elem(temp.Y, P->Y)) { @@ -935,207 +936,6 @@ __owur static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) return ret; } -/* - * Note that by default ECP_NISTZ256_AVX2 is undefined. While it's great - * code processing 4 points in parallel, corresponding serial operation - * is several times slower, because it uses 29x29=58-bit multiplication - * as opposite to 64x64=128-bit in integer-only scalar case. As result - * it doesn't provide *significant* performance improvement. Note that - * just defining ECP_NISTZ256_AVX2 is not sufficient to make it work, - * you'd need to compile even asm/ecp_nistz256-avx.pl module. - */ -#if defined(ECP_NISTZ256_AVX2) -# if !(defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64)) || \ - !(defined(__GNUC__) || defined(_MSC_VER)) /* this is for ALIGN32 */ -# undef ECP_NISTZ256_AVX2 -# else -/* Constant time access, loading four values, from four consecutive tables */ -void ecp_nistz256_avx2_multi_gather_w7(void *result, const void *in, - int index0, int index1, int index2, - int index3); -void ecp_nistz256_avx2_transpose_convert(void *RESULTx4, const void *in); -void ecp_nistz256_avx2_convert_transpose_back(void *result, const void *Ax4); -void ecp_nistz256_avx2_point_add_affine_x4(void *RESULTx4, const void *Ax4, - const void *Bx4); -void ecp_nistz256_avx2_point_add_affines_x4(void *RESULTx4, const void *Ax4, - const void *Bx4); -void ecp_nistz256_avx2_to_mont(void *RESULTx4, const void *Ax4); -void ecp_nistz256_avx2_from_mont(void *RESULTx4, const void *Ax4); -void ecp_nistz256_avx2_set1(void *RESULTx4); -int ecp_nistz_avx2_eligible(void); - -static void booth_recode_w7(unsigned char *sign, - unsigned char *digit, unsigned char in) -{ - unsigned char s, d; - - s = ~((in >> 7) - 1); - d = (1 << 8) - in - 1; - d = (d & s) | (in & ~s); - d = (d >> 1) + (d & 1); - - *sign = s & 1; - *digit = d; -} - -/* - * ecp_nistz256_avx2_mul_g performs multiplication by G, using only the - * precomputed table. It does 4 affine point additions in parallel, - * significantly speeding up point multiplication for a fixed value. - */ -static void ecp_nistz256_avx2_mul_g(P256_POINT *r, - unsigned char p_str[33], - const P256_POINT_AFFINE(*preComputedTable)[64]) -{ - const unsigned int window_size = 7; - const unsigned int mask = (1 << (window_size + 1)) - 1; - unsigned int wvalue; - /* Using 4 windows at a time */ - unsigned char sign0, digit0; - unsigned char sign1, digit1; - unsigned char sign2, digit2; - unsigned char sign3, digit3; - unsigned int idx = 0; - BN_ULONG tmp[P256_LIMBS]; - int i; - - ALIGN32 BN_ULONG aX4[4 * 9 * 3] = { 0 }; - ALIGN32 BN_ULONG bX4[4 * 9 * 2] = { 0 }; - ALIGN32 P256_POINT_AFFINE point_arr[4]; - ALIGN32 P256_POINT res_point_arr[4]; - - /* Initial four windows */ - wvalue = *((u16 *) & p_str[0]); - wvalue = (wvalue << 1) & mask; - idx += window_size; - booth_recode_w7(&sign0, &digit0, wvalue); - wvalue = *((u16 *) & p_str[(idx - 1) / 8]); - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - idx += window_size; - booth_recode_w7(&sign1, &digit1, wvalue); - wvalue = *((u16 *) & p_str[(idx - 1) / 8]); - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - idx += window_size; - booth_recode_w7(&sign2, &digit2, wvalue); - wvalue = *((u16 *) & p_str[(idx - 1) / 8]); - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - idx += window_size; - booth_recode_w7(&sign3, &digit3, wvalue); - - ecp_nistz256_avx2_multi_gather_w7(point_arr, preComputedTable[0], - digit0, digit1, digit2, digit3); - - ecp_nistz256_neg(tmp, point_arr[0].Y); - copy_conditional(point_arr[0].Y, tmp, sign0); - ecp_nistz256_neg(tmp, point_arr[1].Y); - copy_conditional(point_arr[1].Y, tmp, sign1); - ecp_nistz256_neg(tmp, point_arr[2].Y); - copy_conditional(point_arr[2].Y, tmp, sign2); - ecp_nistz256_neg(tmp, point_arr[3].Y); - copy_conditional(point_arr[3].Y, tmp, sign3); - - ecp_nistz256_avx2_transpose_convert(aX4, point_arr); - ecp_nistz256_avx2_to_mont(aX4, aX4); - ecp_nistz256_avx2_to_mont(&aX4[4 * 9], &aX4[4 * 9]); - ecp_nistz256_avx2_set1(&aX4[4 * 9 * 2]); - - wvalue = *((u16 *) & p_str[(idx - 1) / 8]); - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - idx += window_size; - booth_recode_w7(&sign0, &digit0, wvalue); - wvalue = *((u16 *) & p_str[(idx - 1) / 8]); - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - idx += window_size; - booth_recode_w7(&sign1, &digit1, wvalue); - wvalue = *((u16 *) & p_str[(idx - 1) / 8]); - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - idx += window_size; - booth_recode_w7(&sign2, &digit2, wvalue); - wvalue = *((u16 *) & p_str[(idx - 1) / 8]); - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - idx += window_size; - booth_recode_w7(&sign3, &digit3, wvalue); - - ecp_nistz256_avx2_multi_gather_w7(point_arr, preComputedTable[4 * 1], - digit0, digit1, digit2, digit3); - - ecp_nistz256_neg(tmp, point_arr[0].Y); - copy_conditional(point_arr[0].Y, tmp, sign0); - ecp_nistz256_neg(tmp, point_arr[1].Y); - copy_conditional(point_arr[1].Y, tmp, sign1); - ecp_nistz256_neg(tmp, point_arr[2].Y); - copy_conditional(point_arr[2].Y, tmp, sign2); - ecp_nistz256_neg(tmp, point_arr[3].Y); - copy_conditional(point_arr[3].Y, tmp, sign3); - - ecp_nistz256_avx2_transpose_convert(bX4, point_arr); - ecp_nistz256_avx2_to_mont(bX4, bX4); - ecp_nistz256_avx2_to_mont(&bX4[4 * 9], &bX4[4 * 9]); - /* Optimized when both inputs are affine */ - ecp_nistz256_avx2_point_add_affines_x4(aX4, aX4, bX4); - - for (i = 2; i < 9; i++) { - wvalue = *((u16 *) & p_str[(idx - 1) / 8]); - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - idx += window_size; - booth_recode_w7(&sign0, &digit0, wvalue); - wvalue = *((u16 *) & p_str[(idx - 1) / 8]); - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - idx += window_size; - booth_recode_w7(&sign1, &digit1, wvalue); - wvalue = *((u16 *) & p_str[(idx - 1) / 8]); - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - idx += window_size; - booth_recode_w7(&sign2, &digit2, wvalue); - wvalue = *((u16 *) & p_str[(idx - 1) / 8]); - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - idx += window_size; - booth_recode_w7(&sign3, &digit3, wvalue); - - ecp_nistz256_avx2_multi_gather_w7(point_arr, - preComputedTable[4 * i], - digit0, digit1, digit2, digit3); - - ecp_nistz256_neg(tmp, point_arr[0].Y); - copy_conditional(point_arr[0].Y, tmp, sign0); - ecp_nistz256_neg(tmp, point_arr[1].Y); - copy_conditional(point_arr[1].Y, tmp, sign1); - ecp_nistz256_neg(tmp, point_arr[2].Y); - copy_conditional(point_arr[2].Y, tmp, sign2); - ecp_nistz256_neg(tmp, point_arr[3].Y); - copy_conditional(point_arr[3].Y, tmp, sign3); - - ecp_nistz256_avx2_transpose_convert(bX4, point_arr); - ecp_nistz256_avx2_to_mont(bX4, bX4); - ecp_nistz256_avx2_to_mont(&bX4[4 * 9], &bX4[4 * 9]); - - ecp_nistz256_avx2_point_add_affine_x4(aX4, aX4, bX4); - } - - ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 0], &aX4[4 * 9 * 0]); - ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 1], &aX4[4 * 9 * 1]); - ecp_nistz256_avx2_from_mont(&aX4[4 * 9 * 2], &aX4[4 * 9 * 2]); - - ecp_nistz256_avx2_convert_transpose_back(res_point_arr, aX4); - /* Last window is performed serially */ - wvalue = *((u16 *) & p_str[(idx - 1) / 8]); - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - booth_recode_w7(&sign0, &digit0, wvalue); - ecp_nistz256_gather_w7((P256_POINT_AFFINE *)r, - preComputedTable[36], digit0); - ecp_nistz256_neg(tmp, r->Y); - copy_conditional(r->Y, tmp, sign0); - memcpy(r->Z, ONE, sizeof(ONE)); - /* Sum the four windows */ - ecp_nistz256_point_add(r, r, &res_point_arr[0]); - ecp_nistz256_point_add(r, r, &res_point_arr[1]); - ecp_nistz256_point_add(r, r, &res_point_arr[2]); - ecp_nistz256_point_add(r, r, &res_point_arr[3]); -} -# endif -#endif - __owur static int ecp_nistz256_set_from_affine(EC_POINT *out, const EC_GROUP *group, const P256_POINT_AFFINE *in, BN_CTX *ctx) @@ -1225,6 +1025,8 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group, } if (preComputedTable) { + BN_ULONG infty; + if ((BN_num_bits(scalar) > 256) || BN_is_negative(scalar)) { if ((tmp_scalar = BN_CTX_get(ctx)) == NULL) @@ -1256,67 +1058,58 @@ __owur static int ecp_nistz256_points_mul(const EC_GROUP *group, for (; i < 33; i++) p_str[i] = 0; -#if defined(ECP_NISTZ256_AVX2) - if (ecp_nistz_avx2_eligible()) { - ecp_nistz256_avx2_mul_g(&p.p, p_str, preComputedTable); - } else -#endif - { - BN_ULONG infty; + /* First window */ + wvalue = (p_str[0] << 1) & mask; + idx += window_size; - /* First window */ - wvalue = (p_str[0] << 1) & mask; + wvalue = _booth_recode_w7(wvalue); + + ecp_nistz256_gather_w7(&p.a, preComputedTable[0], + wvalue >> 1); + + ecp_nistz256_neg(p.p.Z, p.p.Y); + copy_conditional(p.p.Y, p.p.Z, wvalue & 1); + + /* + * Since affine infinity is encoded as (0,0) and + * Jacobian is (,,0), we need to harmonize them + * by assigning "one" or zero to Z. + */ + infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] | + p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]); + if (P256_LIMBS == 8) + infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] | + p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]); + + infty = 0 - is_zero(infty); + infty = ~infty; + + p.p.Z[0] = ONE[0] & infty; + p.p.Z[1] = ONE[1] & infty; + p.p.Z[2] = ONE[2] & infty; + p.p.Z[3] = ONE[3] & infty; + if (P256_LIMBS == 8) { + p.p.Z[4] = ONE[4] & infty; + p.p.Z[5] = ONE[5] & infty; + p.p.Z[6] = ONE[6] & infty; + p.p.Z[7] = ONE[7] & infty; + } + + for (i = 1; i < 37; i++) { + unsigned int off = (idx - 1) / 8; + wvalue = p_str[off] | p_str[off + 1] << 8; + wvalue = (wvalue >> ((idx - 1) % 8)) & mask; idx += window_size; wvalue = _booth_recode_w7(wvalue); - ecp_nistz256_gather_w7(&p.a, preComputedTable[0], - wvalue >> 1); + ecp_nistz256_gather_w7(&t.a, + preComputedTable[i], wvalue >> 1); - ecp_nistz256_neg(p.p.Z, p.p.Y); - copy_conditional(p.p.Y, p.p.Z, wvalue & 1); + ecp_nistz256_neg(t.p.Z, t.a.Y); + copy_conditional(t.a.Y, t.p.Z, wvalue & 1); - /* - * Since affine infinity is encoded as (0,0) and - * Jacobian ias (,,0), we need to harmonize them - * by assigning "one" or zero to Z. - */ - infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] | - p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]); - if (P256_LIMBS == 8) - infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] | - p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]); - - infty = 0 - is_zero(infty); - infty = ~infty; - - p.p.Z[0] = ONE[0] & infty; - p.p.Z[1] = ONE[1] & infty; - p.p.Z[2] = ONE[2] & infty; - p.p.Z[3] = ONE[3] & infty; - if (P256_LIMBS == 8) { - p.p.Z[4] = ONE[4] & infty; - p.p.Z[5] = ONE[5] & infty; - p.p.Z[6] = ONE[6] & infty; - p.p.Z[7] = ONE[7] & infty; - } - - for (i = 1; i < 37; i++) { - unsigned int off = (idx - 1) / 8; - wvalue = p_str[off] | p_str[off + 1] << 8; - wvalue = (wvalue >> ((idx - 1) % 8)) & mask; - idx += window_size; - - wvalue = _booth_recode_w7(wvalue); - - ecp_nistz256_gather_w7(&t.a, - preComputedTable[i], wvalue >> 1); - - ecp_nistz256_neg(t.p.Z, t.a.Y); - copy_conditional(t.a.Y, t.p.Z, wvalue & 1); - - ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a); - } + ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a); } } else { p_is_infinity = 1; diff --git a/crypto/ec/ecp_s390x_nistp.c b/crypto/ec/ecp_s390x_nistp.c index 75c8475e..edbad15c 100644 --- a/crypto/ec/ecp_s390x_nistp.c +++ b/crypto/ec/ecp_s390x_nistp.c @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* + * EC_METHOD low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include #include diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index eedb1c92..8b63e691 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -126,7 +126,7 @@ static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) return 1; } -static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +static int ecx_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) { const unsigned char *p; int pklen; diff --git a/crypto/engine/eng_lib.c b/crypto/engine/eng_lib.c index 4ba235ca..702b61b2 100644 --- a/crypto/engine/eng_lib.c +++ b/crypto/engine/eng_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -171,6 +171,7 @@ void engine_cleanup_int(void) cleanup_stack = NULL; } CRYPTO_THREAD_lock_free(global_engine_lock); + global_engine_lock = NULL; } /* Now the "ex_data" support */ diff --git a/crypto/err/err.c b/crypto/err/err.c index 9a37c426..bd38da7e 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -76,7 +76,6 @@ static ERR_STRING_DATA ERR_str_libraries[] = { {ERR_PACK(ERR_LIB_ESS, 0, 0), "ESS routines"}, {ERR_PACK(ERR_LIB_PROV, 0, 0), "Provider routines"}, {ERR_PACK(ERR_LIB_OSSL_SERIALIZER, 0, 0), "SERIALIZER routines"}, - {ERR_PACK(ERR_LIB_HTTP, 0, 0), "HTTP routines"}, {0, NULL}, }; diff --git a/crypto/err/err_all.c b/crypto/err/err_all.c index f16cb692..3441e28d 100644 --- a/crypto/err/err_all.c +++ b/crypto/err/err_all.c @@ -30,7 +30,6 @@ #include "internal/dso.h" #include #include -#include #include #include #include @@ -86,7 +85,6 @@ int err_load_crypto_strings_int(void) # ifndef OPENSSL_NO_ENGINE ERR_load_ENGINE_strings() == 0 || # endif - ERR_load_HTTP_strings() == 0 || # ifndef OPENSSL_NO_OCSP ERR_load_OCSP_strings() == 0 || # endif diff --git a/crypto/err/err_prn.c b/crypto/err/err_prn.c index 5c4ebcbd..80cc0ecf 100644 --- a/crypto/err/err_prn.c +++ b/crypto/err/err_prn.c @@ -35,8 +35,9 @@ void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), func = "unknown function"; if ((flags & ERR_TXT_STRING) == 0) data = ""; - hex = OPENSSL_buf2hexstr((const unsigned char *)&tid, sizeof(tid)); - BIO_snprintf(buf, sizeof(buf), "%s:error:%s:%s:%s:%s:%d:%s\n", + hex = openssl_buf2hexstr_sep((const unsigned char *)&tid, sizeof(tid), + '\0'); + BIO_snprintf(buf, sizeof(buf), "%s:error::%s:%s:%s:%s:%d:%s\n", hex == NULL ? "" : hex, lib, func, reason, file, line, data); OPENSSL_free(hex); diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec index 1ec7bb11..485c0c89 100644 --- a/crypto/err/openssl.ec +++ b/crypto/err/openssl.ec @@ -41,7 +41,6 @@ L ESS include/openssl/ess.h crypto/ess/ess_err.c L PROP include/internal/property.h crypto/property/property_err.c L PROV providers/common/include/prov/providercommon.h providers/common/provider_err.c L OSSL_SERIALIZER include/openssl/serializer.h crypto/serializer/serializer_err.c -L HTTP include/openssl/http.h crypto/http/http_err.c # additional header files to be scanned for function names L NONE include/openssl/x509_vfy.h NONE diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 39779f42..361efc33 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -320,6 +320,7 @@ CMS_F_CMS_SET_DETACHED:147:CMS_set_detached CMS_F_CMS_SIGN:148:CMS_sign CMS_F_CMS_SIGNED_DATA_INIT:149:cms_signed_data_init CMS_F_CMS_SIGNERINFO_CONTENT_SIGN:150:cms_SignerInfo_content_sign +CMS_F_CMS_SIGNERINFO_GET_CHAIN:184:cms_signerinfo_get_chain CMS_F_CMS_SIGNERINFO_SIGN:151:CMS_SignerInfo_sign CMS_F_CMS_SIGNERINFO_VERIFY:152:CMS_SignerInfo_verify CMS_F_CMS_SIGNERINFO_VERIFY_CERT:153:cms_signerinfo_verify_cert @@ -329,6 +330,7 @@ CMS_F_CMS_SI_CHECK_ATTRIBUTES:183:CMS_si_check_attributes CMS_F_CMS_STREAM:155:CMS_stream CMS_F_CMS_UNCOMPRESS:156:CMS_uncompress CMS_F_CMS_VERIFY:157:CMS_verify +CMS_F_ESS_CHECK_SIGNING_CERTS:185:ess_check_signing_certs CMS_F_KEK_UNWRAP_KEY:180:kek_unwrap_key COMP_F_BIO_ZLIB_FLUSH:99:bio_zlib_flush COMP_F_BIO_ZLIB_NEW:100:bio_zlib_new @@ -843,8 +845,6 @@ EVP_F_EVP_KEYEXCH_FETCH:245:EVP_KEYEXCH_fetch EVP_F_EVP_KEYEXCH_FROM_DISPATCH:244:evp_keyexch_from_dispatch EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str -EVP_F_EVP_MAC_CTX_DUP:211:EVP_MAC_CTX_dup -EVP_F_EVP_MAC_CTX_NEW:213:EVP_MAC_CTX_new EVP_F_EVP_MAC_INIT:212:EVP_MAC_init EVP_F_EVP_MD_BLOCK_SIZE:232:EVP_MD_block_size EVP_F_EVP_MD_CTX_COPY_EX:110:EVP_MD_CTX_copy_ex @@ -946,9 +946,11 @@ OCSP_F_OCSP_CHECK_IDS:107:ocsp_check_ids OCSP_F_OCSP_CHECK_ISSUER:108:ocsp_check_issuer OCSP_F_OCSP_CHECK_VALIDITY:115:OCSP_check_validity OCSP_F_OCSP_MATCH_ISSUERID:109:ocsp_match_issuerid +OCSP_F_OCSP_PARSE_URL:112: OCSP_F_OCSP_REQUEST_SIGN:110:OCSP_request_sign OCSP_F_OCSP_REQUEST_VERIFY:116:OCSP_request_verify OCSP_F_OCSP_RESPONSE_GET1_BASIC:111:OCSP_response_get1_basic +OCSP_F_PARSE_HTTP_LINE1:113: OSSL_STORE_F_FILE_ATTACH:128: OSSL_STORE_F_FILE_CTRL:129:file_ctrl OSSL_STORE_F_FILE_FIND:138:file_find @@ -1320,6 +1322,9 @@ SSL_F_PARSE_CA_NAMES:541:parse_ca_names SSL_F_PITEM_NEW:624:pitem_new SSL_F_PQUEUE_NEW:625:pqueue_new SSL_F_PROCESS_KEY_SHARE_EXT:439:* +SSL_F_QUIC_CHANGE_CIPHER_STATE:643: +SSL_F_QUIC_GET_MESSAGE:644: +SSL_F_QUIC_SET_ENCRYPTION_SECRETS:645: SSL_F_READ_STATE_MACHINE:352:read_state_machine SSL_F_SET_CLIENT_CIPHERSUITE:540:set_client_ciphersuite SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET:595:srp_generate_client_master_secret @@ -1330,7 +1335,9 @@ SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM:130:ssl3_check_cert_and_algorithm SSL_F_SSL3_CTRL:213:ssl3_ctrl SSL_F_SSL3_CTX_CTRL:133:ssl3_ctx_ctrl SSL_F_SSL3_DIGEST_CACHED_RECORDS:293:ssl3_digest_cached_records +SSL_F_SSL3_DISPATCH_ALERT:646: SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC:292:ssl3_do_change_cipher_spec +SSL_F_SSL3_DO_WRITE:647: SSL_F_SSL3_ENC:608:ssl3_enc SSL_F_SSL3_FINAL_FINISH_MAC:285:ssl3_final_finish_mac SSL_F_SSL3_FINISH_MAC:587:ssl3_finish_mac @@ -1438,6 +1445,8 @@ SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT:311:* SSL_F_SSL_PEEK:270:SSL_peek SSL_F_SSL_PEEK_EX:432:SSL_peek_ex SSL_F_SSL_PEEK_INTERNAL:522:ssl_peek_internal +SSL_F_SSL_PROCESS_QUIC_POST_HANDSHAKE:648: +SSL_F_SSL_PROVIDE_QUIC_DATA:649: SSL_F_SSL_READ:223:SSL_read SSL_F_SSL_READ_EARLY_DATA:529:SSL_read_early_data SSL_F_SSL_READ_EX:434:SSL_read_ex @@ -1488,6 +1497,7 @@ SSL_F_SSL_WRITE_EARLY_DATA:526:SSL_write_early_data SSL_F_SSL_WRITE_EARLY_FINISH:527:* SSL_F_SSL_WRITE_EX:433:SSL_write_ex SSL_F_SSL_WRITE_INTERNAL:524:ssl_write_internal +SSL_F_STATEM_FLUSH:650: SSL_F_STATE_MACHINE:353:state_machine SSL_F_TLS12_CHECK_PEER_SIGALG:333:tls12_check_peer_sigalg SSL_F_TLS12_COPY_SIGALGS:533:tls12_copy_sigalgs @@ -1527,6 +1537,7 @@ SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC:427:tls_construct_change_cipher_spec SSL_F_TLS_CONSTRUCT_CKE_DHE:404:tls_construct_cke_dhe SSL_F_TLS_CONSTRUCT_CKE_ECDHE:405:tls_construct_cke_ecdhe SSL_F_TLS_CONSTRUCT_CKE_GOST:406:tls_construct_cke_gost +SSL_F_TLS_CONSTRUCT_CKE_GOST18:641: SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE:407:tls_construct_cke_psk_preamble SSL_F_TLS_CONSTRUCT_CKE_RSA:409:tls_construct_cke_rsa SSL_F_TLS_CONSTRUCT_CKE_SRP:410:tls_construct_cke_srp @@ -1551,6 +1562,7 @@ SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH:619:\ tls_construct_ctos_post_handshake_auth SSL_F_TLS_CONSTRUCT_CTOS_PSK:501:tls_construct_ctos_psk SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES:509:tls_construct_ctos_psk_kex_modes +SSL_F_TLS_CONSTRUCT_CTOS_QUIC_TRANSPORT_PARAMS:651: SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE:473:tls_construct_ctos_renegotiate SSL_F_TLS_CONSTRUCT_CTOS_SCT:474:tls_construct_ctos_sct SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME:475:tls_construct_ctos_server_name @@ -1592,6 +1604,7 @@ SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE:456:tls_construct_stoc_key_share SSL_F_TLS_CONSTRUCT_STOC_MAXFRAGMENTLEN:548:tls_construct_stoc_maxfragmentlen SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG:457:tls_construct_stoc_next_proto_neg SSL_F_TLS_CONSTRUCT_STOC_PSK:504:tls_construct_stoc_psk +SSL_F_TLS_CONSTRUCT_STOC_QUIC_TRANSPORT_PARAMS:652: SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE:458:tls_construct_stoc_renegotiate SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME:459:tls_construct_stoc_server_name SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET:460:tls_construct_stoc_session_ticket @@ -1620,6 +1633,7 @@ SSL_F_TLS_PARSE_CTOS_MAXFRAGMENTLEN:571:tls_parse_ctos_maxfragmentlen SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH:620:tls_parse_ctos_post_handshake_auth SSL_F_TLS_PARSE_CTOS_PSK:505:tls_parse_ctos_psk SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES:572:tls_parse_ctos_psk_kex_modes +SSL_F_TLS_PARSE_CTOS_QUIC_TRANSPORT_PARAMS:653: SSL_F_TLS_PARSE_CTOS_RENEGOTIATE:464:tls_parse_ctos_renegotiate SSL_F_TLS_PARSE_CTOS_SERVER_NAME:573:tls_parse_ctos_server_name SSL_F_TLS_PARSE_CTOS_SESSION_TICKET:574:tls_parse_ctos_session_ticket @@ -1638,6 +1652,7 @@ SSL_F_TLS_PARSE_STOC_KEY_SHARE:445:tls_parse_stoc_key_share SSL_F_TLS_PARSE_STOC_MAXFRAGMENTLEN:581:tls_parse_stoc_maxfragmentlen SSL_F_TLS_PARSE_STOC_NPN:582:tls_parse_stoc_npn SSL_F_TLS_PARSE_STOC_PSK:502:tls_parse_stoc_psk +SSL_F_TLS_PARSE_STOC_QUIC_TRANSPORT_PARAMS:654: SSL_F_TLS_PARSE_STOC_RENEGOTIATE:448:tls_parse_stoc_renegotiate SSL_F_TLS_PARSE_STOC_SCT:564:tls_parse_stoc_sct SSL_F_TLS_PARSE_STOC_SERVER_NAME:583:tls_parse_stoc_server_name @@ -1658,6 +1673,7 @@ SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC:363:tls_process_change_cipher_spec SSL_F_TLS_PROCESS_CKE_DHE:411:tls_process_cke_dhe SSL_F_TLS_PROCESS_CKE_ECDHE:412:tls_process_cke_ecdhe SSL_F_TLS_PROCESS_CKE_GOST:413:tls_process_cke_gost +SSL_F_TLS_PROCESS_CKE_GOST18:642: SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE:414:tls_process_cke_psk_preamble SSL_F_TLS_PROCESS_CKE_RSA:415:tls_process_cke_rsa SSL_F_TLS_PROCESS_CKE_SRP:416:tls_process_cke_srp @@ -1874,6 +1890,7 @@ X509_F_X509_NAME_PRINT:117:X509_NAME_print X509_F_X509_OBJECT_NEW:150:X509_OBJECT_new X509_F_X509_PRINT_EX_FP:118:X509_print_ex_fp X509_F_X509_PUBKEY_DECODE:148:x509_pubkey_decode +X509_F_X509_PUBKEY_GET:166:X509_PUBKEY_get X509_F_X509_PUBKEY_GET0:119:X509_PUBKEY_get0 X509_F_X509_PUBKEY_SET:120:X509_PUBKEY_set X509_F_X509_REQ_CHECK_PRIVATE_KEY:144:X509_REQ_check_private_key @@ -2022,7 +2039,6 @@ BIO_R_AMBIGUOUS_HOST_OR_SERVICE:129:ambiguous host or service BIO_R_BAD_FOPEN_MODE:101:bad fopen mode BIO_R_BROKEN_PIPE:124:broken pipe BIO_R_CONNECT_ERROR:103:connect error -BIO_R_CONNECT_TIMEOUT:147:connect timeout BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET:107:gethostbyname addr is not af inet BIO_R_GETSOCKNAME_ERROR:132:getsockname error BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS:133:getsockname truncated address @@ -2041,8 +2057,6 @@ BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED:144:no hostname or service specified BIO_R_NO_PORT_DEFINED:113:no port defined BIO_R_NO_SUCH_FILE:128:no such file BIO_R_NULL_PARAMETER:115:null parameter -BIO_R_TRANSFER_ERROR:104:transfer error -BIO_R_TRANSFER_TIMEOUT:105:transfer timeout BIO_R_UNABLE_TO_BIND_SOCKET:117:unable to bind socket BIO_R_UNABLE_TO_CREATE_SOCKET:118:unable to create socket BIO_R_UNABLE_TO_KEEPALIVE:137:unable to keepalive @@ -2113,6 +2127,7 @@ CMP_R_ERROR_PROTECTING_MESSAGE:127:error protecting message CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection +CMP_R_ERROR_VALIDATING_SIGNATURE:171:error validating signature CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range @@ -2185,6 +2200,8 @@ CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE:114:\ error reading messagedigest attribute CMS_R_ERROR_SETTING_KEY:115:error setting key CMS_R_ERROR_SETTING_RECIPIENTINFO:116:error setting recipientinfo +CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE:182:ess no signing certid attribute +CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR:183:ess signing certid mismatch error CMS_R_INVALID_ENCRYPTED_KEY_LENGTH:117:invalid encrypted key length CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER:176:invalid key encryption parameter CMS_R_INVALID_KEY_LENGTH:118:invalid key length @@ -2334,6 +2351,7 @@ CT_R_SCT_UNSUPPORTED_VERSION:115:sct unsupported version CT_R_UNRECOGNIZED_SIGNATURE_NID:101:unrecognized signature nid CT_R_UNSUPPORTED_ENTRY_TYPE:102:unsupported entry type CT_R_UNSUPPORTED_VERSION:103:unsupported version +DH_R_BAD_FFC_PARAMETERS:127:bad ffc parameters DH_R_BAD_GENERATOR:101:bad generator DH_R_BN_DECODE_ERROR:109:bn decode error DH_R_BN_ERROR:106:bn error @@ -2361,6 +2379,7 @@ DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error DH_R_PEER_KEY_ERROR:111:peer key error DH_R_SHARED_INFO_ERROR:113:shared info error DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator +DSA_R_BAD_FFC_PARAMETERS:114:bad ffc parameters DSA_R_BAD_Q_VALUE:102:bad q value DSA_R_BN_DECODE_ERROR:108:bn decode error DSA_R_BN_ERROR:109:bn error @@ -2594,29 +2613,6 @@ EVP_R_WRAP_MODE_NOT_ALLOWED:170:wrap mode not allowed EVP_R_WRONG_FINAL_BLOCK_LENGTH:109:wrong final block length EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE:191:xts data unit is too large EVP_R_XTS_DUPLICATED_KEYS:192:xts duplicated keys -HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN:108:asn1 len exceeds max resp len -HTTP_R_CONNECT_FAILURE:100:connect failure -HTTP_R_ERROR_PARSING_ASN1_LENGTH:109:error parsing asn1 length -HTTP_R_ERROR_PARSING_CONTENT_LENGTH:119:error parsing content length -HTTP_R_ERROR_PARSING_URL:101:error parsing url -HTTP_R_ERROR_RECEIVING:103:error receiving -HTTP_R_ERROR_SENDING:102:error sending -HTTP_R_INCONSISTENT_CONTENT_LENGTH:120:inconsistent content length -HTTP_R_MAX_RESP_LEN_EXCEEDED:117:max resp len exceeded -HTTP_R_MISSING_ASN1_ENCODING:110:missing asn1 encoding -HTTP_R_MISSING_CONTENT_TYPE:121:missing content type -HTTP_R_MISSING_REDIRECT_LOCATION:111:missing redirect location -HTTP_R_RECEIVED_ERROR:105:received error -HTTP_R_RECEIVED_WRONG_HTTP_VERSION:106:received wrong http version -HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP:112:redirection from https to http -HTTP_R_REDIRECTION_NOT_ENABLED:116:redirection not enabled -HTTP_R_RESPONSE_LINE_TOO_LONG:113:response line too long -HTTP_R_RESPONSE_PARSE_ERROR:104:response parse error -HTTP_R_SOCK_NOT_SUPPORTED:122:sock not supported -HTTP_R_STATUS_CODE_UNSUPPORTED:114:status code unsupported -HTTP_R_TLS_NOT_ENABLED:107:tls not enabled -HTTP_R_TOO_MANY_REDIRECTIONS:115:too many redirections -HTTP_R_UNEXPECTED_CONTENT_TYPE:118:unexpected content type KDF_R_BAD_ENCODING:122:bad encoding KDF_R_BAD_LENGTH:123:bad length KDF_R_BOTH_MODE_AND_MODE_INT:127:both mode and mode int @@ -2651,6 +2647,7 @@ OCSP_R_CERTIFICATE_VERIFY_ERROR:101:certificate verify error OCSP_R_DIGEST_ERR:102:digest err OCSP_R_ERROR_IN_NEXTUPDATE_FIELD:122:error in nextupdate field OCSP_R_ERROR_IN_THISUPDATE_FIELD:123:error in thisupdate field +OCSP_R_ERROR_PARSING_URL:121:error parsing url OCSP_R_MISSING_OCSPSIGNING_USAGE:103:missing ocspsigning usage OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE:124:nextupdate before thisupdate OCSP_R_NOT_BASIC_RESPONSE:104:not basic response @@ -2664,6 +2661,8 @@ OCSP_R_REQUEST_NOT_SIGNED:128:request not signed OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA:111:\ response contains no revocation data OCSP_R_ROOT_CA_NOT_TRUSTED:112:root ca not trusted +OCSP_R_SERVER_RESPONSE_ERROR:114:server response error +OCSP_R_SERVER_RESPONSE_PARSE_ERROR:115:server response parse error OCSP_R_SIGNATURE_FAILURE:117:signature failure OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND:118:signer certificate not found OCSP_R_STATUS_EXPIRED:125:status expired @@ -3139,6 +3138,7 @@ SSL_R_INCONSISTENT_EARLY_DATA_ALPN:222:inconsistent early data alpn SSL_R_INCONSISTENT_EARLY_DATA_SNI:231:inconsistent early data sni SSL_R_INCONSISTENT_EXTMS:104:inconsistent extms SSL_R_INSUFFICIENT_SECURITY:241:insufficient security +SSL_R_INTERNAL_ERROR:296:internal error SSL_R_INVALID_ALERT:205:invalid alert SSL_R_INVALID_CCS_MESSAGE:260:invalid ccs message SSL_R_INVALID_CERTIFICATE_OR_ALG:238:invalid certificate or alg @@ -3177,8 +3177,8 @@ SSL_R_MISSING_TMP_DH_KEY:171:missing tmp dh key SSL_R_MISSING_TMP_ECDH_KEY:311:missing tmp ecdh key SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA:293:\ mixed handshake and non handshake data -SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:296:mixed special operator with groups -SSL_R_NESTED_GROUP:297:nested group +SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS:297:mixed special operator with groups +SSL_R_NESTED_GROUP:299:nested group SSL_R_NOT_ON_RECORD_BOUNDARY:182:not on record boundary SSL_R_NOT_REPLACING_CERTIFICATE:289:not replacing certificate SSL_R_NOT_SERVER:284:not server @@ -3286,9 +3286,9 @@ SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES:243:unable to load ssl3 sha1 routines SSL_R_UNEXPECTED_CCS_MESSAGE:262:unexpected ccs message SSL_R_UNEXPECTED_END_OF_EARLY_DATA:178:unexpected end of early data SSL_R_UNEXPECTED_EOF_WHILE_READING:294:unexpected eof while reading -SSL_R_UNEXPECTED_GROUP_CLOSE:299:unexpected group close +SSL_R_UNEXPECTED_GROUP_CLOSE:305:unexpected group close SSL_R_UNEXPECTED_MESSAGE:244:unexpected message -SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:305:unexpected operator in group +SSL_R_UNEXPECTED_OPERATOR_IN_GROUP:310:unexpected operator in group SSL_R_UNEXPECTED_RECORD:245:unexpected record SSL_R_UNINITIALIZED:276:uninitialized SSL_R_UNKNOWN_ALERT_TYPE:246:unknown alert type @@ -3317,6 +3317,7 @@ SSL_R_VERSION_TOO_LOW:396:version too low SSL_R_WRONG_CERTIFICATE_TYPE:383:wrong certificate type SSL_R_WRONG_CIPHER_RETURNED:261:wrong cipher returned SSL_R_WRONG_CURVE:378:wrong curve +SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED:313:wrong encryption level received SSL_R_WRONG_SIGNATURE_LENGTH:264:wrong signature length SSL_R_WRONG_SIGNATURE_SIZE:265:wrong signature size SSL_R_WRONG_SIGNATURE_TYPE:370:wrong signature type diff --git a/crypto/err/openssl.txt.old b/crypto/err/openssl.txt.old index 122542f6..a695203a 100644 --- a/crypto/err/openssl.txt.old +++ b/crypto/err/openssl.txt.old @@ -320,6 +320,7 @@ CMS_F_CMS_SET_DETACHED:147:CMS_set_detached CMS_F_CMS_SIGN:148:CMS_sign CMS_F_CMS_SIGNED_DATA_INIT:149:cms_signed_data_init CMS_F_CMS_SIGNERINFO_CONTENT_SIGN:150:cms_SignerInfo_content_sign +CMS_F_CMS_SIGNERINFO_GET_CHAIN:184:cms_signerinfo_get_chain CMS_F_CMS_SIGNERINFO_SIGN:151:CMS_SignerInfo_sign CMS_F_CMS_SIGNERINFO_VERIFY:152:CMS_SignerInfo_verify CMS_F_CMS_SIGNERINFO_VERIFY_CERT:153:cms_signerinfo_verify_cert @@ -329,6 +330,7 @@ CMS_F_CMS_SI_CHECK_ATTRIBUTES:183:CMS_si_check_attributes CMS_F_CMS_STREAM:155:CMS_stream CMS_F_CMS_UNCOMPRESS:156:CMS_uncompress CMS_F_CMS_VERIFY:157:CMS_verify +CMS_F_ESS_CHECK_SIGNING_CERTS:185:ess_check_signing_certs CMS_F_KEK_UNWRAP_KEY:180:kek_unwrap_key COMP_F_BIO_ZLIB_FLUSH:99:bio_zlib_flush COMP_F_BIO_ZLIB_NEW:100:bio_zlib_new @@ -696,6 +698,7 @@ EC_F_EC_POINT_INVERT:210:EC_POINT_invert EC_F_EC_POINT_IS_AT_INFINITY:118:EC_POINT_is_at_infinity EC_F_EC_POINT_IS_ON_CURVE:119:EC_POINT_is_on_curve EC_F_EC_POINT_MAKE_AFFINE:120:EC_POINT_make_affine +EC_F_EC_POINT_MUL:309: EC_F_EC_POINT_NEW:121:EC_POINT_new EC_F_EC_POINT_OCT2POINT:122:EC_POINT_oct2point EC_F_EC_POINT_POINT2BUF:281:EC_POINT_point2buf @@ -842,8 +845,6 @@ EVP_F_EVP_KEYEXCH_FETCH:245:EVP_KEYEXCH_fetch EVP_F_EVP_KEYEXCH_FROM_DISPATCH:244:evp_keyexch_from_dispatch EVP_F_EVP_MAC_CTRL:209:EVP_MAC_ctrl EVP_F_EVP_MAC_CTRL_STR:210:EVP_MAC_ctrl_str -EVP_F_EVP_MAC_CTX_DUP:211:EVP_MAC_CTX_dup -EVP_F_EVP_MAC_CTX_NEW:213:EVP_MAC_CTX_new EVP_F_EVP_MAC_INIT:212:EVP_MAC_init EVP_F_EVP_MD_BLOCK_SIZE:232:EVP_MD_block_size EVP_F_EVP_MD_CTX_COPY_EX:110:EVP_MD_CTX_copy_ex @@ -948,6 +949,7 @@ OCSP_F_OCSP_MATCH_ISSUERID:109:ocsp_match_issuerid OCSP_F_OCSP_REQUEST_SIGN:110:OCSP_request_sign OCSP_F_OCSP_REQUEST_VERIFY:116:OCSP_request_verify OCSP_F_OCSP_RESPONSE_GET1_BASIC:111:OCSP_response_get1_basic +OSSL_STORE_F_FILE_ATTACH:128: OSSL_STORE_F_FILE_CTRL:129:file_ctrl OSSL_STORE_F_FILE_FIND:138:file_find OSSL_STORE_F_FILE_GET_PASS:118:file_get_pass @@ -955,10 +957,8 @@ OSSL_STORE_F_FILE_LOAD:119:file_load OSSL_STORE_F_FILE_LOAD_TRY_DECODE:124:file_load_try_decode OSSL_STORE_F_FILE_NAME_TO_URI:126:file_name_to_uri OSSL_STORE_F_FILE_OPEN:120:file_open -OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO:127:ossl_store_attach_pem_bio +OSSL_STORE_F_OSSL_STORE_ATTACH:127: OSSL_STORE_F_OSSL_STORE_EXPECT:130:OSSL_STORE_expect -OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT:128:\ - ossl_store_file_attach_pem_bio_int OSSL_STORE_F_OSSL_STORE_FIND:131:OSSL_STORE_find OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT:100:ossl_store_get0_loader_int OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT:101:OSSL_STORE_INFO_get1_CERT @@ -1001,17 +1001,17 @@ PEM_F_D2I_PKCS8PRIVATEKEY_BIO:120:d2i_PKCS8PrivateKey_bio PEM_F_D2I_PKCS8PRIVATEKEY_FP:121:d2i_PKCS8PrivateKey_fp PEM_F_DO_B2I:132:do_b2i PEM_F_DO_B2I_BIO:133:do_b2i_bio -PEM_F_DO_BLOB_HEADER:134:do_blob_header PEM_F_DO_I2B:146:do_i2b PEM_F_DO_PK8PKEY:126:do_pk8pkey PEM_F_DO_PK8PKEY_FP:125:do_pk8pkey_fp PEM_F_DO_PVK_BODY:135:do_PVK_body -PEM_F_DO_PVK_HEADER:136:do_PVK_header PEM_F_GET_HEADER_AND_DATA:143:get_header_and_data PEM_F_GET_NAME:144:get_name PEM_F_I2B_PVK:137:i2b_PVK PEM_F_I2B_PVK_BIO:138:i2b_PVK_bio PEM_F_LOAD_IV:101:load_iv +PEM_F_OSSL_DO_BLOB_HEADER:134:ossl_do_blob_header +PEM_F_OSSL_DO_PVK_HEADER:136:ossl_do_PVK_header PEM_F_PEM_ASN1_READ:102:PEM_ASN1_read PEM_F_PEM_ASN1_READ_BIO:103:PEM_ASN1_read_bio PEM_F_PEM_ASN1_WRITE:104:PEM_ASN1_write @@ -1527,6 +1527,7 @@ SSL_F_TLS_CONSTRUCT_CHANGE_CIPHER_SPEC:427:tls_construct_change_cipher_spec SSL_F_TLS_CONSTRUCT_CKE_DHE:404:tls_construct_cke_dhe SSL_F_TLS_CONSTRUCT_CKE_ECDHE:405:tls_construct_cke_ecdhe SSL_F_TLS_CONSTRUCT_CKE_GOST:406:tls_construct_cke_gost +SSL_F_TLS_CONSTRUCT_CKE_GOST18:641: SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE:407:tls_construct_cke_psk_preamble SSL_F_TLS_CONSTRUCT_CKE_RSA:409:tls_construct_cke_rsa SSL_F_TLS_CONSTRUCT_CKE_SRP:410:tls_construct_cke_srp @@ -1658,6 +1659,7 @@ SSL_F_TLS_PROCESS_CHANGE_CIPHER_SPEC:363:tls_process_change_cipher_spec SSL_F_TLS_PROCESS_CKE_DHE:411:tls_process_cke_dhe SSL_F_TLS_PROCESS_CKE_ECDHE:412:tls_process_cke_ecdhe SSL_F_TLS_PROCESS_CKE_GOST:413:tls_process_cke_gost +SSL_F_TLS_PROCESS_CKE_GOST18:642: SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE:414:tls_process_cke_psk_preamble SSL_F_TLS_PROCESS_CKE_RSA:415:tls_process_cke_rsa SSL_F_TLS_PROCESS_CKE_SRP:416:tls_process_cke_srp @@ -1874,6 +1876,7 @@ X509_F_X509_NAME_PRINT:117:X509_NAME_print X509_F_X509_OBJECT_NEW:150:X509_OBJECT_new X509_F_X509_PRINT_EX_FP:118:X509_print_ex_fp X509_F_X509_PUBKEY_DECODE:148:x509_pubkey_decode +X509_F_X509_PUBKEY_GET:166:X509_PUBKEY_get X509_F_X509_PUBKEY_GET0:119:X509_PUBKEY_get0 X509_F_X509_PUBKEY_SET:120:X509_PUBKEY_set X509_F_X509_REQ_CHECK_PRIVATE_KEY:144:X509_REQ_check_private_key @@ -2022,7 +2025,6 @@ BIO_R_AMBIGUOUS_HOST_OR_SERVICE:129:ambiguous host or service BIO_R_BAD_FOPEN_MODE:101:bad fopen mode BIO_R_BROKEN_PIPE:124:broken pipe BIO_R_CONNECT_ERROR:103:connect error -BIO_R_CONNECT_TIMEOUT:147:connect timeout BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET:107:gethostbyname addr is not af inet BIO_R_GETSOCKNAME_ERROR:132:getsockname error BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS:133:getsockname truncated address @@ -2041,8 +2043,6 @@ BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED:144:no hostname or service specified BIO_R_NO_PORT_DEFINED:113:no port defined BIO_R_NO_SUCH_FILE:128:no such file BIO_R_NULL_PARAMETER:115:null parameter -BIO_R_TRANSFER_ERROR:104:transfer error -BIO_R_TRANSFER_TIMEOUT:105:transfer timeout BIO_R_UNABLE_TO_BIND_SOCKET:117:unable to bind socket BIO_R_UNABLE_TO_CREATE_SOCKET:118:unable to create socket BIO_R_UNABLE_TO_KEEPALIVE:137:unable to keepalive @@ -2113,6 +2113,7 @@ CMP_R_ERROR_PROTECTING_MESSAGE:127:error protecting message CMP_R_ERROR_SETTING_CERTHASH:128:error setting certhash CMP_R_ERROR_UNEXPECTED_CERTCONF:160:error unexpected certconf CMP_R_ERROR_VALIDATING_PROTECTION:140:error validating protection +CMP_R_ERROR_VALIDATING_SIGNATURE:171:error validating signature CMP_R_FAILED_EXTRACTING_PUBKEY:141:failed extracting pubkey CMP_R_FAILURE_OBTAINING_RANDOM:110:failure obtaining random CMP_R_FAIL_INFO_OUT_OF_RANGE:129:fail info out of range @@ -2134,7 +2135,6 @@ CMP_R_NULL_ARGUMENT:103:null argument CMP_R_PKIBODY_ERROR:146:pkibody error CMP_R_PKISTATUSINFO_NOT_FOUND:132:pkistatusinfo not found CMP_R_POLLING_FAILED:172:polling failed -CMP_R_POTENTIALLY_INVALID_CERTIFICATE:147:potentially invalid certificate CMP_R_RECEIVED_ERROR:180:received error CMP_R_RECIPNONCE_UNMATCHED:148:recipnonce unmatched CMP_R_REQUEST_NOT_ACCEPTED:149:request not accepted @@ -2185,6 +2185,8 @@ CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE:114:\ error reading messagedigest attribute CMS_R_ERROR_SETTING_KEY:115:error setting key CMS_R_ERROR_SETTING_RECIPIENTINFO:116:error setting recipientinfo +CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE:182:ess no signing certid attribute +CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR:183:ess signing certid mismatch error CMS_R_INVALID_ENCRYPTED_KEY_LENGTH:117:invalid encrypted key length CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER:176:invalid key encryption parameter CMS_R_INVALID_KEY_LENGTH:118:invalid key length @@ -2334,6 +2336,7 @@ CT_R_SCT_UNSUPPORTED_VERSION:115:sct unsupported version CT_R_UNRECOGNIZED_SIGNATURE_NID:101:unrecognized signature nid CT_R_UNSUPPORTED_ENTRY_TYPE:102:unsupported entry type CT_R_UNSUPPORTED_VERSION:103:unsupported version +DH_R_BAD_FFC_PARAMETERS:127:bad ffc parameters DH_R_BAD_GENERATOR:101:bad generator DH_R_BN_DECODE_ERROR:109:bn decode error DH_R_BN_ERROR:106:bn error @@ -2361,6 +2364,7 @@ DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error DH_R_PEER_KEY_ERROR:111:peer key error DH_R_SHARED_INFO_ERROR:113:shared info error DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator +DSA_R_BAD_FFC_PARAMETERS:114:bad ffc parameters DSA_R_BAD_Q_VALUE:102:bad q value DSA_R_BN_DECODE_ERROR:108:bn decode error DSA_R_BN_ERROR:109:bn error @@ -2559,6 +2563,7 @@ EVP_R_NO_KEYMGMT_AVAILABLE:199:no keymgmt available EVP_R_NO_KEYMGMT_PRESENT:196:no keymgmt present EVP_R_NO_KEY_SET:154:no key set EVP_R_NO_OPERATION_SET:149:no operation set +EVP_R_NULL_MAC_PKEY_CTX:208:null mac pkey ctx EVP_R_ONLY_ONESHOT_SUPPORTED:177:only oneshot supported EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:150:\ operation not supported for this keytype @@ -2571,6 +2576,7 @@ EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED:179:\ EVP_R_PRIVATE_KEY_DECODE_ERROR:145:private key decode error EVP_R_PRIVATE_KEY_ENCODE_ERROR:146:private key encode error EVP_R_PUBLIC_KEY_NOT_RSA:106:public key not rsa +EVP_R_SET_DEFAULT_PROPERTY_FAILURE:209:set default property failure EVP_R_TOO_MANY_RECORDS:183:too many records EVP_R_UNKNOWN_CIPHER:160:unknown cipher EVP_R_UNKNOWN_DIGEST:161:unknown digest @@ -2592,29 +2598,6 @@ EVP_R_WRAP_MODE_NOT_ALLOWED:170:wrap mode not allowed EVP_R_WRONG_FINAL_BLOCK_LENGTH:109:wrong final block length EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE:191:xts data unit is too large EVP_R_XTS_DUPLICATED_KEYS:192:xts duplicated keys -HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN:108:asn1 len exceeds max resp len -HTTP_R_CONNECT_FAILURE:100:connect failure -HTTP_R_ERROR_PARSING_ASN1_LENGTH:109:error parsing asn1 length -HTTP_R_ERROR_PARSING_CONTENT_LENGTH:119:error parsing content length -HTTP_R_ERROR_PARSING_URL:101:error parsing url -HTTP_R_ERROR_RECEIVING:103:error receiving -HTTP_R_ERROR_SENDING:102:error sending -HTTP_R_INCONSISTENT_CONTENT_LENGTH:120:inconsistent content length -HTTP_R_MAX_RESP_LEN_EXCEEDED:117:max resp len exceeded -HTTP_R_MISSING_ASN1_ENCODING:110:missing asn1 encoding -HTTP_R_MISSING_CONTENT_TYPE:121:missing content type -HTTP_R_MISSING_REDIRECT_LOCATION:111:missing redirect location -HTTP_R_RECEIVED_ERROR:105:received error -HTTP_R_RECEIVED_WRONG_HTTP_VERSION:106:received wrong http version -HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP:112:redirection from https to http -HTTP_R_REDIRECTION_NOT_ENABLED:116:redirection not enabled -HTTP_R_RESPONSE_LINE_TOO_LONG:113:response line too long -HTTP_R_RESPONSE_PARSE_ERROR:104:response parse error -HTTP_R_SOCK_NOT_SUPPORTED:122:sock not supported -HTTP_R_STATUS_CODE_UNSUPPORTED:114:status code unsupported -HTTP_R_TLS_NOT_ENABLED:107:tls not enabled -HTTP_R_TOO_MANY_REDIRECTIONS:115:too many redirections -HTTP_R_UNEXPECTED_CONTENT_TYPE:118:unexpected content type KDF_R_BAD_ENCODING:122:bad encoding KDF_R_BAD_LENGTH:123:bad length KDF_R_BOTH_MODE_AND_MODE_INT:127:both mode and mode int @@ -2649,6 +2632,7 @@ OCSP_R_CERTIFICATE_VERIFY_ERROR:101:certificate verify error OCSP_R_DIGEST_ERR:102:digest err OCSP_R_ERROR_IN_NEXTUPDATE_FIELD:122:error in nextupdate field OCSP_R_ERROR_IN_THISUPDATE_FIELD:123:error in thisupdate field +OCSP_R_ERROR_PARSING_URL:121:error parsing url OCSP_R_MISSING_OCSPSIGNING_USAGE:103:missing ocspsigning usage OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE:124:nextupdate before thisupdate OCSP_R_NOT_BASIC_RESPONSE:104:not basic response @@ -2662,6 +2646,8 @@ OCSP_R_REQUEST_NOT_SIGNED:128:request not signed OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA:111:\ response contains no revocation data OCSP_R_ROOT_CA_NOT_TRUSTED:112:root ca not trusted +OCSP_R_SERVER_RESPONSE_ERROR:114:server response error +OCSP_R_SERVER_RESPONSE_PARSE_ERROR:115:server response parse error OCSP_R_SIGNATURE_FAILURE:117:signature failure OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND:118:signer certificate not found OCSP_R_STATUS_EXPIRED:125:status expired @@ -2841,6 +2827,7 @@ PROV_R_INVALID_PADDING_MODE:168:invalid padding mode PROV_R_INVALID_PSS_SALTLEN:169:invalid pss saltlen PROV_R_INVALID_SALT_LENGTH:112:invalid salt length PROV_R_INVALID_SEED_LENGTH:154:invalid seed length +PROV_R_INVALID_SIGNATURE_SIZE:179:invalid signature size PROV_R_INVALID_TAG:110:invalid tag PROV_R_INVALID_TAGLEN:118:invalid taglen PROV_R_INVALID_X931_DIGEST:170:invalid x931 digest @@ -2862,6 +2849,8 @@ PROV_R_NOT_SUPPORTED:136:not supported PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length PROV_R_NO_KEY_SET:114:no key set PROV_R_NO_PARAMETERS_SET:177:no parameters set +PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:178:\ + operation not supported for this keytype PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small PROV_R_PSS_SALTLEN_TOO_SMALL:172:pss saltlen too small PROV_R_READ_KEY:159:read key diff --git a/crypto/ess/build.info b/crypto/ess/build.info index 24fcecc8..fa2bc41d 100644 --- a/crypto/ess/build.info +++ b/crypto/ess/build.info @@ -1,3 +1,8 @@ LIBS=../../libcrypto -SOURCE[../../libcrypto]= \ - ess_lib.c ess_asn1.c ess_err.c + +IF[{- !$disabled{'cms'} and !$disabled{'ts'} -}] + SOURCE[../../libcrypto]= ess_lib.c +ENDIF + +SOURCE[../../libcrypto]= ess_asn1.c ess_err.c + diff --git a/crypto/ess/ess_asn1.c b/crypto/ess/ess_asn1.c index 19589d97..a8d13a3a 100644 --- a/crypto/ess/ess_asn1.c +++ b/crypto/ess/ess_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,9 +9,11 @@ #include #include +#include #include #include #include "crypto/ess.h" +#include "crypto/cms.h" /* ASN1 stuff for ESS Structure */ @@ -55,3 +57,61 @@ ASN1_SEQUENCE(ESS_SIGNING_CERT_V2) = { IMPLEMENT_ASN1_FUNCTIONS(ESS_SIGNING_CERT_V2) IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT_V2) + +/* No cms support means no CMS_SignerInfo* definitions */ +#ifndef OPENSSL_NO_CMS + +/* + * Returns < 0 if attribute is not found, 1 if found, or + * -1 on attribute parsing failure. + */ +int cms_signerinfo_get_signing_cert_v2(CMS_SignerInfo *si, + ESS_SIGNING_CERT_V2 **psc) +{ + ASN1_STRING *str; + ESS_SIGNING_CERT_V2 *sc; + ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_signingCertificateV2); + + if (psc != NULL) + *psc = NULL; + str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE); + if (str == NULL) + return 0; + + sc = ASN1_item_unpack(str, ASN1_ITEM_rptr(ESS_SIGNING_CERT_V2)); + if (sc == NULL) + return -1; + if (psc != NULL) + *psc = sc; + else + ESS_SIGNING_CERT_V2_free(sc); + return 1; +} + +/* + * Returns < 0 if attribute is not found, 1 if found, or + * -1 on attribute parsing failure. + */ +int cms_signerinfo_get_signing_cert(CMS_SignerInfo *si, + ESS_SIGNING_CERT **psc) +{ + ASN1_STRING *str; + ESS_SIGNING_CERT *sc; + ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_signingCertificate); + + if (psc != NULL) + *psc = NULL; + str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE); + if (str == NULL) + return 0; + + sc = ASN1_item_unpack(str, ASN1_ITEM_rptr(ESS_SIGNING_CERT)); + if (sc == NULL) + return -1; + if (psc != NULL) + *psc = sc; + else + ESS_SIGNING_CERT_free(sc); + return 1; +} +#endif /* !OPENSSL_NO_CMS */ diff --git a/crypto/ess/ess_err.c b/crypto/ess/ess_err.c index b494aa24..6547645f 100644 --- a/crypto/ess/ess_err.c +++ b/crypto/ess/ess_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ess/ess_lib.c b/crypto/ess/ess_lib.c index 9d9defa9..17f9db98 100644 --- a/crypto/ess/ess_lib.c +++ b/crypto/ess/ess_lib.c @@ -15,8 +15,8 @@ DEFINE_STACK_OF(ESS_CERT_ID) DEFINE_STACK_OF(ESS_CERT_ID_V2) -DEFINE_STACK_OF(X509) DEFINE_STACK_OF(GENERAL_NAME) +DEFINE_STACK_OF(X509) static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed); static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg, @@ -61,9 +61,12 @@ static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed) unsigned char cert_sha1[SHA_DIGEST_LENGTH]; /* Call for side-effect of computing hash and caching extensions */ - X509_check_purpose(cert, -1, 0); + if (!X509v3_cache_extensions(cert, NULL, NULL)) + return NULL; + if ((cid = ESS_CERT_ID_new()) == NULL) goto err; + /* TODO(3.0): fetch sha1 algorithm from providers */ if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL)) goto err; if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH)) @@ -85,8 +88,8 @@ static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed) goto err; name = NULL; /* Ownership is lost. */ ASN1_INTEGER_free(cid->issuer_serial->serial); - if (!(cid->issuer_serial->serial = - ASN1_INTEGER_dup(X509_get_serialNumber(cert)))) + if ((cid->issuer_serial->serial = + ASN1_INTEGER_dup(X509_get_serialNumber(cert))) == NULL) goto err; return cid; @@ -159,6 +162,7 @@ static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg, cid->hash_alg = NULL; } + /* TODO(3.0): fetch sha1 algorithm from providers */ if (!X509_digest(cert, hash_alg, hash, &hash_len)) goto err; @@ -196,8 +200,9 @@ ESS_SIGNING_CERT *ESS_SIGNING_CERT_get(PKCS7_SIGNER_INFO *si) { ASN1_TYPE *attr; const unsigned char *p; + attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate); - if (!attr) + if (attr == NULL) return NULL; p = attr->value.sequence->data; return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); @@ -273,3 +278,86 @@ int ESS_SIGNING_CERT_V2_add(PKCS7_SIGNER_INFO *si, OPENSSL_free(pp); return 0; } + +static int ess_issuer_serial_cmp(const ESS_ISSUER_SERIAL *is, const X509 *cert) +{ + GENERAL_NAME *issuer; + + if (is == NULL || cert == NULL || sk_GENERAL_NAME_num(is->issuer) != 1) + return -1; + + issuer = sk_GENERAL_NAME_value(is->issuer, 0); + if (issuer->type != GEN_DIRNAME + || X509_NAME_cmp(issuer->d.dirn, X509_get_issuer_name(cert)) != 0) + return -1; + + return ASN1_INTEGER_cmp(is->serial, X509_get0_serialNumber(cert)); +} + +/* Returns < 0 if certificate is not found, certificate index otherwise. */ +int ess_find_cert(const STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) +{ + int i; + unsigned char cert_sha1[SHA_DIGEST_LENGTH]; + + if (cert_ids == NULL || cert == NULL) + return -1; + + /* Recompute SHA1 hash of certificate if necessary (side effect). */ + if (!X509v3_cache_extensions(cert, NULL, NULL)) + return -1; + + /* TODO(3.0): fetch sha1 algorithm from providers */ + if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL)) + return -1; + + /* Look for cert in the cert_ids vector. */ + for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) { + const ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); + + if (cid->hash->length == SHA_DIGEST_LENGTH + && memcmp(cid->hash->data, cert_sha1, SHA_DIGEST_LENGTH) == 0) { + const ESS_ISSUER_SERIAL *is = cid->issuer_serial; + + if (is == NULL || ess_issuer_serial_cmp(is, cert) == 0) + return i; + } + } + + return -1; +} + +/* Returns < 0 if certificate is not found, certificate index otherwise. */ +int ess_find_cert_v2(const STACK_OF(ESS_CERT_ID_V2) *cert_ids, const X509 *cert) +{ + int i; + unsigned char cert_digest[EVP_MAX_MD_SIZE]; + unsigned int len; + + /* Look for cert in the cert_ids vector. */ + for (i = 0; i < sk_ESS_CERT_ID_V2_num(cert_ids); ++i) { + const ESS_CERT_ID_V2 *cid = sk_ESS_CERT_ID_V2_value(cert_ids, i); + const EVP_MD *md; + + if (cid != NULL && cid->hash_alg != NULL) + md = EVP_get_digestbyobj(cid->hash_alg->algorithm); + else + md = EVP_sha256(); + + /* TODO(3.0): fetch sha1 algorithm from providers */ + if (!X509_digest(cert, md, cert_digest, &len)) + return -1; + + if (cid->hash->length != (int)len) + return -1; + + if (memcmp(cid->hash->data, cert_digest, cid->hash->length) == 0) { + const ESS_ISSUER_SERIAL *is = cid->issuer_serial; + + if (is == NULL || ess_issuer_serial_cmp(is, cert) == 0) + return i; + } + } + + return -1; +} diff --git a/crypto/evp/encode.c b/crypto/evp/encode.c index fb657d14..01552ac0 100644 --- a/crypto/evp/encode.c +++ b/crypto/evp/encode.c @@ -423,7 +423,7 @@ static int evp_decodeblock_int(EVP_ENCODE_CTX *ctx, unsigned char *t, table = data_ascii2bin; /* trim white space from the start of the line. */ - while ((conv_ascii2bin(*f, table) == B64_WS) && (n > 0)) { + while ((n > 0) && (conv_ascii2bin(*f, table) == B64_WS)) { f++; n--; } diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c index be5ab111..596f5925 100644 --- a/crypto/evp/evp_fetch.c +++ b/crypto/evp/evp_fetch.c @@ -444,7 +444,13 @@ void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id, data.free_method = free_method; data.user_fn = user_fn; data.user_arg = user_arg; - ossl_algorithm_do_all(libctx, operation_id, NULL, do_one, &data); + + /* + * No pre- or post-condition for this call, as this only creates methods + * temporarly and then promptly destroys them. + */ + ossl_algorithm_do_all(libctx, operation_id, NULL, NULL, do_one, NULL, + &data); } const char *evp_first_name(const OSSL_PROVIDER *prov, int name_id) diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c index 26d7e1ce..514ecd40 100644 --- a/crypto/evp/exchange.c +++ b/crypto/evp/exchange.c @@ -368,13 +368,13 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) /* * For clarity. The error is if parameters in peer are - * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return + * present (!missing) but don't match. EVP_PKEY_parameters_eq may return * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 * (different key types) is impossible here because it is checked earlier. * -2 is OK for us here, as well as 1, so we can check for 0 only. */ if (!EVP_PKEY_missing_parameters(peer) && - !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { + !EVP_PKEY_parameters_eq(ctx->pkey, peer)) { EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS); return -1; } diff --git a/crypto/evp/kdf_lib.c b/crypto/evp/kdf_lib.c index d22bb39c..24614980 100644 --- a/crypto/evp/kdf_lib.c +++ b/crypto/evp/kdf_lib.c @@ -23,7 +23,7 @@ #include "internal/provider.h" #include "evp_local.h" -EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf) +EVP_KDF_CTX *EVP_KDF_new_ctx(EVP_KDF *kdf) { EVP_KDF_CTX *ctx = NULL; @@ -34,7 +34,7 @@ EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf) if (ctx == NULL || (ctx->data = kdf->newctx(ossl_provider_ctx(kdf->prov))) == NULL || !EVP_KDF_up_ref(kdf)) { - EVPerr(EVP_F_EVP_KDF_CTX_NEW, ERR_R_MALLOC_FAILURE); + EVPerr(0, ERR_R_MALLOC_FAILURE); if (ctx != NULL) kdf->freectx(ctx->data); OPENSSL_free(ctx); @@ -45,7 +45,7 @@ EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf) return ctx; } -void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx) +void EVP_KDF_free_ctx(EVP_KDF_CTX *ctx) { if (ctx != NULL) { ctx->meth->freectx(ctx->data); @@ -55,7 +55,7 @@ void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx) } } -EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src) +EVP_KDF_CTX *EVP_KDF_dup_ctx(const EVP_KDF_CTX *src) { EVP_KDF_CTX *dst; @@ -64,20 +64,20 @@ EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src) dst = OPENSSL_malloc(sizeof(*dst)); if (dst == NULL) { - EVPerr(EVP_F_EVP_KDF_CTX_DUP, ERR_R_MALLOC_FAILURE); + EVPerr(0, ERR_R_MALLOC_FAILURE); return NULL; } memcpy(dst, src, sizeof(*dst)); if (!EVP_KDF_up_ref(dst->meth)) { - EVPerr(EVP_F_EVP_KDF_CTX_DUP, ERR_R_MALLOC_FAILURE); + EVPerr(0, ERR_R_MALLOC_FAILURE); OPENSSL_free(dst); return NULL; } dst->data = src->meth->dupctx(src->data); if (dst->data == NULL) { - EVP_KDF_CTX_free(dst); + EVP_KDF_free_ctx(dst); return NULL; } return dst; @@ -98,7 +98,7 @@ const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf) return kdf->prov; } -const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx) +const EVP_KDF *EVP_KDF_get_ctx_kdf(EVP_KDF_CTX *ctx) { return ctx->meth; } @@ -151,14 +151,14 @@ int EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[]) return 1; } -int EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]) +int EVP_KDF_get_ctx_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]) { if (ctx->meth->get_ctx_params != NULL) return ctx->meth->get_ctx_params(ctx->data, params); return 1; } -int EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]) +int EVP_KDF_set_ctx_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]) { if (ctx->meth->set_ctx_params != NULL) return ctx->meth->set_ctx_params(ctx->data, params); diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c index 54805d74..68ed74b2 100644 --- a/crypto/evp/keymgmt_lib.c +++ b/crypto/evp/keymgmt_lib.c @@ -39,6 +39,13 @@ static int try_import(const OSSL_PARAM params[], void *arg) { struct import_data_st *data = arg; + /* Just in time creation of keydata */ + if (data->keydata == NULL + && (data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + /* * It's fine if there was no data to transfer, we just end up with an * empty destination key. @@ -46,13 +53,6 @@ static int try_import(const OSSL_PARAM params[], void *arg) if (params[0].key == NULL) return 1; - /* Just in time creation of keydata, if needed */ - if (data->keydata == NULL - && (data->keydata = evp_keymgmt_newdata(data->keymgmt)) == NULL) { - ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); - return 0; - } - return evp_keymgmt_import(data->keymgmt, data->keydata, data->selection, params); } @@ -236,8 +236,8 @@ int evp_keymgmt_util_has(EVP_PKEY *pk, int selection) * but also in the operation cache to see if there's any common keymgmt that * supplies OP_keymgmt_match. * - * evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_cmp() - * and EVP_PKEY_cmp_parameters() return, i.e.: + * evp_keymgmt_util_match() adheres to the return values that EVP_PKEY_eq() + * and EVP_PKEY_parameters_eq() return, i.e.: * * 1 same key * 0 not same key diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c index b7bfe892..8fe97087 100644 --- a/crypto/evp/mac_lib.c +++ b/crypto/evp/mac_lib.c @@ -19,14 +19,14 @@ #include "internal/provider.h" #include "evp_local.h" -EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac) +EVP_MAC_CTX *EVP_MAC_new_ctx(EVP_MAC *mac) { EVP_MAC_CTX *ctx = OPENSSL_zalloc(sizeof(EVP_MAC_CTX)); if (ctx == NULL || (ctx->data = mac->newctx(ossl_provider_ctx(mac->prov))) == NULL || !EVP_MAC_up_ref(mac)) { - EVPerr(EVP_F_EVP_MAC_CTX_NEW, ERR_R_MALLOC_FAILURE); + EVPerr(0, ERR_R_MALLOC_FAILURE); if (ctx != NULL) mac->freectx(ctx->data); OPENSSL_free(ctx); @@ -37,7 +37,7 @@ EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac) return ctx; } -void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx) +void EVP_MAC_free_ctx(EVP_MAC_CTX *ctx) { if (ctx != NULL) { ctx->meth->freectx(ctx->data); @@ -48,7 +48,7 @@ void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx) OPENSSL_free(ctx); } -EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src) +EVP_MAC_CTX *EVP_MAC_dup_ctx(const EVP_MAC_CTX *src) { EVP_MAC_CTX *dst; @@ -57,27 +57,27 @@ EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src) dst = OPENSSL_malloc(sizeof(*dst)); if (dst == NULL) { - EVPerr(EVP_F_EVP_MAC_CTX_DUP, ERR_R_MALLOC_FAILURE); + EVPerr(0, ERR_R_MALLOC_FAILURE); return NULL; } *dst = *src; if (!EVP_MAC_up_ref(dst->meth)) { - EVPerr(EVP_F_EVP_MAC_CTX_DUP, ERR_R_MALLOC_FAILURE); + EVPerr(0, ERR_R_MALLOC_FAILURE); OPENSSL_free(dst); return NULL; } dst->data = src->meth->dupctx(src->data); if (dst->data == NULL) { - EVP_MAC_CTX_free(dst); + EVP_MAC_free_ctx(dst); return NULL; } return dst; } -EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx) +EVP_MAC *EVP_MAC_get_ctx_mac(EVP_MAC_CTX *ctx) { return ctx->meth; } @@ -144,14 +144,14 @@ int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]) return 1; } -int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]) +int EVP_MAC_get_ctx_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]) { if (ctx->meth->get_ctx_params != NULL) return ctx->meth->get_ctx_params(ctx->data, params); return 1; } -int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]) +int EVP_MAC_set_ctx_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]) { if (ctx->meth->set_ctx_params != NULL) return ctx->meth->set_ctx_params(ctx->data, params); diff --git a/crypto/evp/p5_crpt2.c b/crypto/evp/p5_crpt2.c index 6e89ffd9..e2f7734a 100644 --- a/crypto/evp/p5_crpt2.c +++ b/crypto/evp/p5_crpt2.c @@ -41,7 +41,7 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, salt = (unsigned char *)empty; kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_PBKDF2, NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); if (kctx == NULL) return 0; @@ -54,11 +54,11 @@ int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, (char *)mdname, 0); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) != 1 + if (EVP_KDF_set_ctx_params(kctx, params) != 1 || EVP_KDF_derive(kctx, out, keylen) != 1) rv = 0; - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); OSSL_TRACE_BEGIN(PKCS5V2) { BIO_printf(trc_out, "Password:\n"); diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 9eb9f493..0b067c8a 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -119,7 +119,7 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) * If |to| is a legacy key and |from| isn't, we must downgrade |from|. * If that fails, this function fails. */ - if (to->type != EVP_PKEY_NONE && from->keymgmt != NULL) + if (evp_pkey_is_legacy(to) && evp_pkey_is_provided(from)) if (!evp_pkey_downgrade((EVP_PKEY *)from)) return 0; @@ -135,15 +135,15 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) * like evp_keymgmt_util_copy() and evp_pkey_export_to_provider() called * further down help us find out if they are the same or not. */ - if (to->type == EVP_PKEY_NONE && to->keymgmt == NULL) { - if (from->type != EVP_PKEY_NONE) { + if (evp_pkey_is_blank(to)) { + if (evp_pkey_is_legacy(from)) { if (EVP_PKEY_set_type(to, from->type) == 0) return 0; } else { if (EVP_PKEY_set_type_by_keymgmt(to, from->keymgmt) == 0) return 0; } - } else if (to->type != EVP_PKEY_NONE) { + } else if (evp_pkey_is_legacy(to)) { if (to->type != from->type) { EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES); goto err; @@ -156,7 +156,7 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) } if (!EVP_PKEY_missing_parameters(to)) { - if (EVP_PKEY_cmp_parameters(to, from) == 1) + if (EVP_PKEY_parameters_eq(to, from) == 1) return 1; EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS); return 0; @@ -272,7 +272,14 @@ static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b, return evp_keymgmt_match(keymgmt1, keydata1, keydata2, selection); } +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + return EVP_PKEY_parameters_eq(a, b); +} +#endif + +int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b) { /* * TODO: clean up legacy stuff from this function when legacy support @@ -290,7 +297,14 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) return -2; } +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + return EVP_PKEY_eq(a, b); +} +#endif + +int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b) { /* * TODO: clean up legacy stuff from this function when legacy support @@ -581,7 +595,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, prov == NULL ? NULL : ossl_provider_library_context(prov); EVP_PKEY *ret = EVP_PKEY_new(); EVP_MAC *cmac = EVP_MAC_fetch(libctx, OSSL_MAC_NAME_CMAC, NULL); - EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_CTX_new(cmac) : NULL; + EVP_MAC_CTX *cmctx = cmac != NULL ? EVP_MAC_new_ctx(cmac) : NULL; OSSL_PARAM params[4]; size_t paramsn = 0; @@ -606,7 +620,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, (char *)priv, len); params[paramsn] = OSSL_PARAM_construct_end(); - if (!EVP_MAC_CTX_set_params(cmctx, params)) { + if (!EVP_MAC_set_ctx_params(cmctx, params)) { EVPerr(EVP_F_EVP_PKEY_NEW_CMAC_KEY, EVP_R_KEY_SETUP_FAILED); goto err; } @@ -616,7 +630,7 @@ EVP_PKEY *EVP_PKEY_new_CMAC_key(ENGINE *e, const unsigned char *priv, err: EVP_PKEY_free(ret); - EVP_MAC_CTX_free(cmctx); + EVP_MAC_free_ctx(cmctx); EVP_MAC_free(cmac); return NULL; # else @@ -1201,6 +1215,18 @@ int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid) int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const unsigned char *pt, size_t ptlen) { + if (pkey->ameth == NULL) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + if (pkey->keymgmt == NULL || pkey->keydata == NULL) + return 0; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, + (unsigned char *)pt, ptlen); + return evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params); + } + if (ptlen > INT_MAX) return 0; if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, ptlen, @@ -1212,6 +1238,33 @@ int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt) { int rv; + + if (pkey->ameth == NULL) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + if (pkey->keymgmt == NULL || pkey->keydata == NULL) + return 0; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, + NULL, 0); + if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)) + return 0; + + *ppt = OPENSSL_malloc(params[0].return_size); + if (*ppt == NULL) + return 0; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, + *ppt, params[0].return_size); + if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)) + return 0; + + return params[0].return_size; + } + + rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppt); if (rv <= 0) return 0; @@ -1357,19 +1410,17 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str, pkey->engine = e; /* - * The EVP_PKEY_ASN1_METHOD |pkey_id| serves different purposes, - * depending on if we're setting this key to contain a legacy or - * a provider side "origin" key. For a legacy key, we assign it - * to the |type| field, but for a provider side key, we assign it - * to the |save_type| field, because |type| is supposed to be set - * to EVP_PKEY_NONE in that case. + * The EVP_PKEY_ASN1_METHOD |pkey_id| retains its legacy key purpose + * for any key type that has a legacy implementation, regardless of + * if the internal key is a legacy or a provider side one. When + * there is no legacy implementation for the key, the type becomes + * EVP_PKEY_KEYMGMT, which indicates that one should be cautious + * with functions that expect legacy internal keys. */ - if (ameth != NULL) { - if (keymgmt != NULL) - pkey->save_type = ameth->pkey_id; - else if (pkey->ameth != NULL) - pkey->type = ameth->pkey_id; - } + if (ameth != NULL) + pkey->type = ameth->pkey_id; + else + pkey->type = EVP_PKEY_KEYMGMT; #endif } return 1; @@ -1453,7 +1504,6 @@ void evp_pkey_free_legacy(EVP_PKEY *x) ENGINE_finish(x->pmeth_engine); x->pmeth_engine = NULL; # endif - x->type = EVP_PKEY_NONE; } #endif /* FIPS_MODULE */ @@ -1472,6 +1522,7 @@ static void evp_pkey_free_it(EVP_PKEY *x) x->keymgmt = NULL; x->keydata = NULL; } + x->type = EVP_PKEY_NONE; } void EVP_PKEY_free(EVP_PKEY *x) @@ -1661,32 +1712,33 @@ int evp_pkey_downgrade(EVP_PKEY *pk) { EVP_KEYMGMT *keymgmt = pk->keymgmt; void *keydata = pk->keydata; - int type = pk->save_type; + int type = pk->type; const char *keytype = NULL; /* If this isn't a provider side key, we're done */ if (keymgmt == NULL) return 1; - /* Get the key type name for error reporting */ - if (type != EVP_PKEY_NONE) - keytype = OBJ_nid2sn(type); - else - keytype = - evp_first_name(EVP_KEYMGMT_provider(keymgmt), keymgmt->name_id); + keytype = evp_first_name(EVP_KEYMGMT_provider(keymgmt), keymgmt->name_id); /* - * |save_type| was set when any of the EVP_PKEY_set_type functions - * was called. It was set to EVP_PKEY_NONE if the key type wasn't - * recognised to be any of the legacy key types, and the downgrade - * isn't possible. + * If the type is EVP_PKEY_NONE, then we have a problem somewhere else + * in our code. If it's not one of the well known EVP_PKEY_xxx values, + * it should at least be EVP_PKEY_KEYMGMT at this point. + * TODO(3.0) remove this check when we're confident that the rest of the + * code treats this correctly. */ - if (type == EVP_PKEY_NONE) { - ERR_raise_data(ERR_LIB_EVP, EVP_R_UNKNOWN_KEY_TYPE, - "key type = %s, can't downgrade", keytype); + if (!ossl_assert(type != EVP_PKEY_NONE)) { + ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR, + "keymgmt key type = %s but legacy type = EVP_PKEY_NONE", + keytype); return 0; } + /* Prefer the legacy key type name for error reporting */ + if (type != EVP_PKEY_KEYMGMT) + keytype = OBJ_nid2sn(type); + /* * To be able to downgrade, we steal the provider side "origin" keymgmt * and keydata. We've already grabbed the pointers, so all we need to diff --git a/crypto/evp/pbe_scrypt.c b/crypto/evp/pbe_scrypt.c index 62b96879..5081b85c 100644 --- a/crypto/evp/pbe_scrypt.c +++ b/crypto/evp/pbe_scrypt.c @@ -63,7 +63,7 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen, maxmem = SCRYPT_MAX_MEM; kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_SCRYPT, NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); if (kctx == NULL) return 0; @@ -78,11 +78,11 @@ int EVP_PBE_scrypt(const char *pass, size_t passlen, *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_P, &p); *z++ = OSSL_PARAM_construct_uint64(OSSL_KDF_PARAM_SCRYPT_MAXMEM, &maxmem); *z = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) != 1 + if (EVP_KDF_set_ctx_params(kctx, params) != 1 || EVP_KDF_derive(kctx, key, keylen) != 1) rv = 0; - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return rv; } diff --git a/crypto/evp/pkey_kdf.c b/crypto/evp/pkey_kdf.c index ac4a0fa4..dff16bfd 100644 --- a/crypto/evp/pkey_kdf.c +++ b/crypto/evp/pkey_kdf.c @@ -50,7 +50,7 @@ static int pkey_kdf_init(EVP_PKEY_CTX *ctx) return 0; kdf = EVP_KDF_fetch(NULL, kdf_name, NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); if (kctx == NULL) { OPENSSL_free(pkctx); @@ -66,7 +66,7 @@ static void pkey_kdf_cleanup(EVP_PKEY_CTX *ctx) { EVP_PKEY_KDF_CTX *pkctx = ctx->data; - EVP_KDF_CTX_free(pkctx->kctx); + EVP_KDF_free_ctx(pkctx->kctx); pkey_kdf_free_collected(pkctx); OPENSSL_free(pkctx); } @@ -202,7 +202,7 @@ static int pkey_kdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) break; } - return EVP_KDF_CTX_set_params(kctx, params); + return EVP_KDF_set_ctx_params(kctx, params); } static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, @@ -210,7 +210,7 @@ static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, { EVP_PKEY_KDF_CTX *pkctx = ctx->data; EVP_KDF_CTX *kctx = pkctx->kctx; - const EVP_KDF *kdf = EVP_KDF_CTX_kdf(kctx); + const EVP_KDF *kdf = EVP_KDF_get_ctx_kdf(kctx); BUF_MEM **collector = NULL; const OSSL_PARAM *defs = EVP_KDF_settable_ctx_params(kdf); OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; @@ -239,7 +239,7 @@ static int pkey_kdf_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, if (collector != NULL) ok = collect(collector, params[0].data, params[0].data_size); else - ok = EVP_KDF_CTX_set_params(kctx, params); + ok = EVP_KDF_set_ctx_params(kctx, params); OPENSSL_free(params[0].data); return ok; } @@ -274,7 +274,7 @@ static int pkey_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, pkctx->collected_seed->data, pkctx->collected_seed->length); - r = EVP_KDF_CTX_set_params(kctx, params); + r = EVP_KDF_set_ctx_params(kctx, params); pkey_kdf_free_collected(pkctx); if (!r) return 0; @@ -287,7 +287,7 @@ static int pkey_kdf_derive(EVP_PKEY_CTX *ctx, unsigned char *key, pkctx->collected_info->data, pkctx->collected_info->length); - r = EVP_KDF_CTX_set_params(kctx, params); + r = EVP_KDF_set_ctx_params(kctx, params); pkey_kdf_free_collected(pkctx); if (!r) return 0; diff --git a/crypto/evp/pkey_mac.c b/crypto/evp/pkey_mac.c index 3503aac6..55badea7 100644 --- a/crypto/evp/pkey_mac.c +++ b/crypto/evp/pkey_mac.c @@ -71,7 +71,7 @@ static int pkey_mac_init(EVP_PKEY_CTX *ctx) } if (mac != NULL) { - hctx->ctx = EVP_MAC_CTX_new(mac); + hctx->ctx = EVP_MAC_new_ctx(mac); if (hctx->ctx == NULL) { OPENSSL_free(hctx); return 0; @@ -116,7 +116,7 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) EVP_PKEY_CTX_set_data(dst, dctx); dst->keygen_info_count = 0; - dctx->ctx = EVP_MAC_CTX_dup(sctx->ctx); + dctx->ctx = EVP_MAC_dup_ctx(sctx->ctx); if (dctx->ctx == NULL) goto err; @@ -128,7 +128,7 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src) * fetches the MAC method anew in this case. Therefore, its reference * count must be adjusted here. */ - if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(dctx->ctx))) + if (!EVP_MAC_up_ref(EVP_MAC_get_ctx_mac(dctx->ctx))) goto err; dctx->type = sctx->type; @@ -163,7 +163,8 @@ static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx) MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx); if (hctx != NULL) { - EVP_MAC *mac = hctx->ctx != NULL ? EVP_MAC_CTX_mac(hctx->ctx) : NULL; + EVP_MAC *mac = hctx->ctx != NULL ? EVP_MAC_get_ctx_mac(hctx->ctx) + : NULL; switch (hctx->type) { case MAC_TYPE_RAW: @@ -171,7 +172,7 @@ static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx) hctx->raw_data.ktmp.length); break; } - EVP_MAC_CTX_free(hctx->ctx); + EVP_MAC_free_ctx(hctx->ctx); EVP_MAC_free(mac); OPENSSL_free(hctx); EVP_PKEY_CTX_set_data(ctx, NULL); @@ -206,10 +207,10 @@ static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) return 0; } - cmkey = EVP_MAC_CTX_dup(hctx->ctx); + cmkey = EVP_MAC_dup_ctx(hctx->ctx); if (cmkey == NULL) return 0; - if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx))) + if (!EVP_MAC_up_ref(EVP_MAC_get_ctx_mac(hctx->ctx))) return 0; EVP_PKEY_assign(pkey, nid, cmkey); } @@ -255,7 +256,7 @@ static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) } if (set_key) { - if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx), + if (!EVP_MAC_is_a(EVP_MAC_get_ctx_mac(hctx->ctx), OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx))))) return 0; key = EVP_PKEY_get0(EVP_PKEY_CTX_get0_pkey(ctx)); @@ -280,7 +281,7 @@ static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, key->data, key->length); params[params_n++] = OSSL_PARAM_construct_end(); - rv = EVP_MAC_CTX_set_params(hctx->ctx, params); + rv = EVP_MAC_set_ctx_params(hctx->ctx, params); } return rv; } @@ -330,7 +331,7 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 0; } - if (!EVP_MAC_CTX_set_params(hctx->ctx, params) + if (!EVP_MAC_set_ctx_params(hctx->ctx, params) || !EVP_MAC_init(hctx->ctx)) return 0; } @@ -351,10 +352,10 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) if (ctx->pkey == NULL) return 0; - new_mac_ctx = EVP_MAC_CTX_dup(ctx->pkey->pkey.ptr); + new_mac_ctx = EVP_MAC_dup_ctx(ctx->pkey->pkey.ptr); if (new_mac_ctx == NULL) return 0; - EVP_MAC_CTX_free(hctx->ctx); + EVP_MAC_free_ctx(hctx->ctx); hctx->ctx = new_mac_ctx; } break; @@ -389,17 +390,17 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 0; } - if (!EVP_MAC_CTX_set_params(hctx->ctx, params)) + if (!EVP_MAC_set_ctx_params(hctx->ctx, params)) return 0; params[0] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &verify); - if (!EVP_MAC_CTX_get_params(hctx->ctx, params)) + if (!EVP_MAC_get_ctx_params(hctx->ctx, params)) return 0; /* - * Since EVP_MAC_CTX_{get,set}_params() returned successfully, + * Since EVP_MAC_{get,set}_ctx_params() returned successfully, * we can only assume that the size was ignored, i.e. this * control is unsupported. */ @@ -433,7 +434,7 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) return 0; } - return EVP_MAC_CTX_set_params(hctx->ctx, params); + return EVP_MAC_set_ctx_params(hctx->ctx, params); } break; default: @@ -478,7 +479,7 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) key->data, key->length); params[params_n] = OSSL_PARAM_construct_end(); - return EVP_MAC_CTX_set_params(hctx->ctx, params); + return EVP_MAC_set_ctx_params(hctx->ctx, params); } break; case MAC_TYPE_MAC: @@ -513,7 +514,7 @@ static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx, EVPerr(0, EVP_R_FETCH_FAILED); return 0; } - mac = EVP_MAC_CTX_mac(hctx->ctx); + mac = EVP_MAC_get_ctx_mac(hctx->ctx); /* * Translation of some control names that are equivalent to a single @@ -535,7 +536,7 @@ static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx, return 0; params[1] = OSSL_PARAM_construct_end(); - ok = EVP_MAC_CTX_set_params(hctx->ctx, params); + ok = EVP_MAC_set_ctx_params(hctx->ctx, params); OPENSSL_free(params[0].data); return ok; } diff --git a/crypto/evp/pmeth_gn.c b/crypto/evp/pmeth_gn.c index fb861d24..411f270b 100644 --- a/crypto/evp/pmeth_gn.c +++ b/crypto/evp/pmeth_gn.c @@ -144,6 +144,8 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) int ret = 0; OSSL_CALLBACK cb; EVP_PKEY *allocated_pkey = NULL; + /* Legacy compatible keygen callback info, only used with provider impls */ + int gentmp[2]; if (ppkey == NULL) return -1; @@ -165,6 +167,18 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) if (ctx->op.keymgmt.genctx == NULL) goto legacy; + /* + * Asssigning gentmp to ctx->keygen_info is something our legacy + * implementations do. Because the provider implementations aren't + * allowed to reach into our EVP_PKEY_CTX, we need to provide similar + * space for backward compatibility. It's ok that we attach a local + * variable, as it should only be useful in the calls down from here. + * This is cleared as soon as it isn't useful any more, i.e. directly + * after the evp_keymgmt_util_gen() call. + */ + ctx->keygen_info = gentmp; + ctx->keygen_info_count = 2; + ret = 1; if (ctx->pkey != NULL) { EVP_KEYMGMT *tmp_keymgmt = ctx->keymgmt; @@ -191,6 +205,8 @@ int EVP_PKEY_gen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) ossl_callback_to_pkey_gencb, ctx) != NULL); + ctx->keygen_info = NULL; + #ifndef FIPS_MODULE /* In case |*ppkey| was originally a legacy key */ if (ret) diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index eca51781..dd6556c8 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -137,6 +137,40 @@ EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) } #endif /* FIPS_MODULE */ +static int is_legacy_alg(int id, const char *keytype) +{ +#ifndef FIPS_MODULE + /* Certain EVP_PKEY keytypes are only available in legacy form */ + if (id == -1) { + id = OBJ_sn2nid(keytype); + if (id == NID_undef) + id = OBJ_ln2nid(keytype); + if (id == NID_undef) + return 0; + } + switch (id) { + /* + * TODO(3.0): Remove SM2 and DHX when they are converted to have provider + * support + */ + case EVP_PKEY_SM2: + case EVP_PKEY_DHX: + case EVP_PKEY_SCRYPT: + case EVP_PKEY_TLS1_PRF: + case EVP_PKEY_HKDF: + case EVP_PKEY_CMAC: + case EVP_PKEY_HMAC: + case EVP_PKEY_SIPHASH: + case EVP_PKEY_POLY1305: + return 1; + default: + return 0; + } +#else + return 0; +#endif +} + static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, EVP_PKEY *pkey, ENGINE *e, const char *keytype, const char *propquery, @@ -155,10 +189,10 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, goto common; /* - * If the key doesn't contain anything legacy, then it must be provided, - * so we extract the necessary information and use that. + * If the internal key is provided, we extract the keytype from its + * keymgmt and skip over the legacy code. */ - if (pkey != NULL && pkey->type == EVP_PKEY_NONE) { + if (pkey != NULL && evp_pkey_is_provided(pkey)) { /* If we have an engine, something went wrong somewhere... */ if (!ossl_assert(e == NULL)) return NULL; @@ -228,10 +262,20 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx, * implementation. */ if (e == NULL && keytype != NULL) { - /* This could fail so ignore errors */ - ERR_set_mark(); + int legacy = is_legacy_alg(id, keytype); + + if (legacy) { + /* This could fail so ignore errors */ + ERR_set_mark(); + } + keymgmt = EVP_KEYMGMT_fetch(libctx, keytype, propquery); - ERR_pop_to_mark(); + if (legacy) { + ERR_pop_to_mark(); + } else if (keymgmt == NULL) { + EVPerr(EVP_F_INT_CTX_NEW, EVP_R_FETCH_FAILED); + return NULL; + } } ret = OPENSSL_zalloc(sizeof(*ret)); @@ -341,45 +385,14 @@ void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src) { + int pkey_id = dst->pkey_id; + int flags = dst->flags; - dst->init = src->init; - dst->copy = src->copy; - dst->cleanup = src->cleanup; + *dst = *src; - dst->paramgen_init = src->paramgen_init; - dst->paramgen = src->paramgen; - - dst->keygen_init = src->keygen_init; - dst->keygen = src->keygen; - - dst->sign_init = src->sign_init; - dst->sign = src->sign; - - dst->verify_init = src->verify_init; - dst->verify = src->verify; - - dst->verify_recover_init = src->verify_recover_init; - dst->verify_recover = src->verify_recover; - - dst->signctx_init = src->signctx_init; - dst->signctx = src->signctx; - - dst->verifyctx_init = src->verifyctx_init; - dst->verifyctx = src->verifyctx; - - dst->encrypt_init = src->encrypt_init; - dst->encrypt = src->encrypt; - - dst->decrypt_init = src->decrypt_init; - dst->decrypt = src->decrypt; - - dst->derive_init = src->derive_init; - dst->derive = src->derive; - - dst->ctrl = src->ctrl; - dst->ctrl_str = src->ctrl_str; - - dst->check = src->check; + /* We only copy the function pointers so restore the other values */ + dst->pkey_id = pkey_id; + dst->flags = flags; } void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) @@ -1033,7 +1046,7 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, # endif # ifndef OPENSSL_NO_DH else if (strcmp(name, "dh_paramgen_generator") == 0) - name = OSSL_PKEY_PARAM_FFC_GENERATOR; + name = OSSL_PKEY_PARAM_DH_GENERATOR; else if (strcmp(name, "dh_paramgen_prime_len") == 0) name = OSSL_PKEY_PARAM_FFC_PBITS; else if (strcmp(name, "dh_paramgen_subprime_len") == 0) @@ -1042,9 +1055,9 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, name = OSSL_PKEY_PARAM_FFC_TYPE; value = dh_gen_type_id2name(atoi(value)); } else if (strcmp(name, "dh_param") == 0) - name = OSSL_PKEY_PARAM_FFC_GROUP; + name = OSSL_PKEY_PARAM_DH_GROUP; else if (strcmp(name, "dh_rfc5114") == 0) { - name = OSSL_PKEY_PARAM_FFC_GROUP; + name = OSSL_PKEY_PARAM_DH_GROUP; value = ffc_named_group_from_uid(atoi(value)); } else if (strcmp(name, "dh_pad") == 0) name = OSSL_EXCHANGE_PARAM_PAD; diff --git a/crypto/ex_data.c b/crypto/ex_data.c index 6200d055..80a13616 100644 --- a/crypto/ex_data.c +++ b/crypto/ex_data.c @@ -96,7 +96,7 @@ static void dummy_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, } static int dummy_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, - void *from_d, int idx, + void **from_d, int idx, long argl, void *argp) { return 1; diff --git a/crypto/ffc/ffc_backend.c b/crypto/ffc/ffc_backend.c index 1cfa427d..c34e79bf 100644 --- a/crypto/ffc/ffc_backend.c +++ b/crypto/ffc/ffc_backend.c @@ -27,7 +27,7 @@ int ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[]) if (ffc == NULL) return 0; - prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GROUP); + prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_GROUP); if (prm != NULL) { if (prm->data_type != OSSL_PARAM_UTF8_STRING) goto err; diff --git a/crypto/ffc/ffc_params.c b/crypto/ffc/ffc_params.c index efd7dc89..a95a2fa1 100644 --- a/crypto/ffc/ffc_params.c +++ b/crypto/ffc/ffc_params.c @@ -220,7 +220,7 @@ int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld, if (name == NULL || !ossl_param_build_set_utf8_string(bld, params, - OSSL_PKEY_PARAM_FFC_GROUP, + OSSL_PKEY_PARAM_DH_GROUP, name)) return 0; #else diff --git a/crypto/ffc/ffc_params_generate.c b/crypto/ffc/ffc_params_generate.c index 1d8d80c9..624c24dd 100644 --- a/crypto/ffc/ffc_params_generate.c +++ b/crypto/ffc/ffc_params_generate.c @@ -27,6 +27,9 @@ #include /* memset */ #include /* SHA_DIGEST_LENGTH */ #include +#include +#include +#include #include "crypto/bn.h" #include "internal/ffc.h" @@ -40,6 +43,9 @@ static int ffc_validate_LN(size_t L, size_t N, int type) /* Valid DH L,N parameters from SP800-56Ar3 5.5.1 Table 1 */ if (L == 2048 && (N == 224 || N == 256)) return 112; +#ifndef OPENSSL_NO_DH + DHerr(0, DH_R_BAD_FFC_PARAMETERS); +#endif } else if (type == FFC_PARAM_TYPE_DSA) { /* Valid DSA L,N parameters from FIPS 186-4 Section 4.2 */ if (L == 1024 && N == 160) @@ -48,6 +54,9 @@ static int ffc_validate_LN(size_t L, size_t N, int type) return 112; if (L == 3072 && N == 256) return 128; +#ifndef OPENSSL_NO_DSA + DSAerr(0, DSA_R_BAD_FFC_PARAMETERS); +#endif } return 0; } diff --git a/crypto/http/build.info b/crypto/http/build.info deleted file mode 100644 index b4626b13..00000000 --- a/crypto/http/build.info +++ /dev/null @@ -1,2 +0,0 @@ -LIBS=../../libcrypto -SOURCE[../../libcrypto]=http_client.c http_err.c http_lib.c diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c deleted file mode 100644 index 64f877ab..00000000 --- a/crypto/http/http_client.c +++ /dev/null @@ -1,1271 +0,0 @@ -/* - * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. - * Copyright Siemens AG 2018-2020 - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include "e_os.h" -#include -#include -#include "crypto/ctype.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include "internal/sockets.h" -#include "internal/cryptlib.h" /* for ossl_assert() */ - -#include "http_local.h" - -DEFINE_STACK_OF(CONF_VALUE) - -#define HTTP_PREFIX "HTTP/" -#define HTTP_VERSION_PATT "1." /* allow 1.x */ -#define HTTP_VERSION_STR_LEN 3 -#define HTTP_LINE1_MINLEN ((int)strlen(HTTP_PREFIX HTTP_VERSION_PATT "x 200\n")) -#define HTTP_VERSION_MAX_REDIRECTIONS 50 - -#define HTTP_STATUS_CODE_OK 200 -#define HTTP_STATUS_CODE_MOVED_PERMANENTLY 301 -#define HTTP_STATUS_CODE_FOUND 302 - - -/* Stateful HTTP request code, supporting blocking and non-blocking I/O */ - -/* Opaque HTTP request status structure */ - -struct ossl_http_req_ctx_st { - int state; /* Current I/O state */ - unsigned char *iobuf; /* Line buffer */ - int iobuflen; /* Line buffer length */ - BIO *wbio; /* BIO to send request to */ - BIO *rbio; /* BIO to read response from */ - BIO *mem; /* Memory BIO response is built into */ - int method_GET; /* HTTP method "GET" or "POST" */ - const char *expected_ct; /* expected Content-Type, or NULL */ - int expect_asn1; /* response must be ASN.1-encoded */ - unsigned long resp_len; /* length of response */ - unsigned long max_resp_len; /* Maximum length of response */ - time_t max_time; /* Maximum end time of the transfer, or 0 */ - char *redirection_url; /* Location given with HTTP status 301/302 */ -}; - -#define HTTP_DEFAULT_MAX_LINE_LENGTH (4 * 1024) -#define HTTP_DEFAULT_MAX_RESP_LEN (100 * 1024) - -/* HTTP states */ - -#define OHS_NOREAD 0x1000 /* If set no reading should be performed */ -#define OHS_ERROR (0 | OHS_NOREAD) /* Error condition */ -#define OHS_FIRSTLINE 1 /* First line being read */ -#define OHS_REDIRECT 0xa /* Looking for redirection location */ -#define OHS_HEADERS 2 /* MIME headers being read */ -#define OHS_ASN1_HEADER 3 /* HTTP initial header (tag+length) being read */ -#define OHS_CONTENT 4 /* HTTP content octets being read */ -#define OHS_WRITE_INIT (5 | OHS_NOREAD) /* 1st call: ready to start I/O */ -#define OHS_WRITE (6 | OHS_NOREAD) /* Request being sent */ -#define OHS_FLUSH (7 | OHS_NOREAD) /* Request being flushed */ -#define OHS_DONE (8 | OHS_NOREAD) /* Completed */ -#define OHS_HTTP_HEADER (9 | OHS_NOREAD) /* Headers set, w/o final \r\n */ - -OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, - int method_GET, int maxline, - unsigned long max_resp_len, - int timeout, - const char *expected_content_type, - int expect_asn1) -{ - OSSL_HTTP_REQ_CTX *rctx; - - if (wbio == NULL || rbio == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - - if ((rctx = OPENSSL_zalloc(sizeof(*rctx))) == NULL) - return NULL; - rctx->state = OHS_ERROR; - rctx->iobuflen = maxline > 0 ? maxline : HTTP_DEFAULT_MAX_LINE_LENGTH; - rctx->iobuf = OPENSSL_malloc(rctx->iobuflen); - rctx->wbio = wbio; - rctx->rbio = rbio; - rctx->mem = BIO_new(BIO_s_mem()); - if (rctx->iobuf == NULL || rctx->mem == NULL) { - OSSL_HTTP_REQ_CTX_free(rctx); - return NULL; - } - rctx->method_GET = method_GET; - rctx->expected_ct = expected_content_type; - rctx->expect_asn1 = expect_asn1; - rctx->resp_len = 0; - OSSL_HTTP_REQ_CTX_set_max_response_length(rctx, max_resp_len); - rctx->max_time = timeout > 0 ? time(NULL) + timeout : 0; - return rctx; -} - -void OSSL_HTTP_REQ_CTX_free(OSSL_HTTP_REQ_CTX *rctx) -{ - if (rctx == NULL) - return; - BIO_free(rctx->mem); /* this may indirectly call ERR_clear_error() */ - OPENSSL_free(rctx->iobuf); - OPENSSL_free(rctx); -} - -BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(OSSL_HTTP_REQ_CTX *rctx) -{ - if (rctx == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - return rctx->mem; -} - -void OSSL_HTTP_REQ_CTX_set_max_response_length(OSSL_HTTP_REQ_CTX *rctx, - unsigned long len) -{ - if (rctx == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return; - } - rctx->max_resp_len = len != 0 ? len : HTTP_DEFAULT_MAX_RESP_LEN; -} - -/* - * Create HTTP header using given op and path (or "/" in case path is NULL). - * Server name (and port) must be given if and only if plain HTTP proxy is used. - */ -int OSSL_HTTP_REQ_CTX_header(OSSL_HTTP_REQ_CTX *rctx, const char *server, - const char *port, const char *path) -{ - if (rctx == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (BIO_printf(rctx->mem, "%s ", rctx->method_GET ? "GET" : "POST") <= 0) - return 0; - - if (server != NULL) { /* HTTP (but not HTTPS) proxy is used */ - /* - * Section 5.1.2 of RFC 1945 states that the absoluteURI form is only - * allowed when using a proxy - */ - if (BIO_printf(rctx->mem, OSSL_HTTP_PREFIX"%s", server) <= 0) - return 0; - if (port != NULL && BIO_printf(rctx->mem, ":%s", port) <= 0) - return 0; - } - - /* Make sure path includes a forward slash */ - if (path == NULL) - path = "/"; - if (path[0] != '/' && BIO_printf(rctx->mem, "/") <= 0) - return 0; - - if (BIO_printf(rctx->mem, "%s "HTTP_PREFIX"1.0\r\n", path) <= 0) - return 0; - rctx->state = OHS_HTTP_HEADER; - return 1; -} - -int OSSL_HTTP_REQ_CTX_add1_header(OSSL_HTTP_REQ_CTX *rctx, - const char *name, const char *value) -{ - if (rctx == NULL || name == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (BIO_puts(rctx->mem, name) <= 0) - return 0; - if (value != NULL) { - if (BIO_write(rctx->mem, ": ", 2) != 2) - return 0; - if (BIO_puts(rctx->mem, value) <= 0) - return 0; - } - if (BIO_write(rctx->mem, "\r\n", 2) != 2) - return 0; - rctx->state = OHS_HTTP_HEADER; - return 1; -} - -static int OSSL_HTTP_REQ_CTX_content(OSSL_HTTP_REQ_CTX *rctx, - const char *content_type, BIO *req_mem) -{ - const unsigned char *req; - long req_len; - - if (rctx == NULL || req_mem == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (content_type != NULL - && BIO_printf(rctx->mem, "Content-Type: %s\r\n", content_type) <= 0) - return 0; - - if ((req_len = BIO_get_mem_data(req_mem, &req)) <= 0) - return 0; - rctx->state = OHS_WRITE_INIT; - - return BIO_printf(rctx->mem, "Content-Length: %ld\r\n\r\n", req_len) > 0 - && BIO_write(rctx->mem, req, req_len) == (int)req_len; -} - -BIO *HTTP_asn1_item2bio(const ASN1_ITEM *it, const ASN1_VALUE *val) -{ - BIO *res; - - if (it == NULL || val == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - - if ((res = BIO_new(BIO_s_mem())) == NULL) - return NULL; - if (ASN1_item_i2d_bio(it, res, val) <= 0) { - BIO_free(res); - res = NULL; - } - return res; -} - -int OSSL_HTTP_REQ_CTX_i2d(OSSL_HTTP_REQ_CTX *rctx, const char *content_type, - const ASN1_ITEM *it, ASN1_VALUE *req) -{ - BIO *mem; - int res; - - if (rctx == NULL || it == NULL || req == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - res = (mem = HTTP_asn1_item2bio(it, req)) != NULL - && OSSL_HTTP_REQ_CTX_content(rctx, content_type, mem); - BIO_free(mem); - return res; -} - -static int OSSL_HTTP_REQ_CTX_add1_headers(OSSL_HTTP_REQ_CTX *rctx, - const STACK_OF(CONF_VALUE) *headers, - const char *host) -{ - int i; - int add_host = 1; - CONF_VALUE *hdr; - - for (i = 0; i < sk_CONF_VALUE_num(headers); i++) { - hdr = sk_CONF_VALUE_value(headers, i); - if (add_host && strcasecmp("host", hdr->name) == 0) - add_host = 0; - if (!OSSL_HTTP_REQ_CTX_add1_header(rctx, hdr->name, hdr->value)) - return 0; - } - - if (add_host && !OSSL_HTTP_REQ_CTX_add1_header(rctx, "Host", host)) - return 0; - return 1; -} - -/*- - * Create OSSL_HTTP_REQ_CTX structure using the values provided. - * If !use_http_proxy then the 'server' and 'port' parameters are ignored. - * If req_mem == NULL then use GET and ignore content_type, else POST. - */ -OSSL_HTTP_REQ_CTX *HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int use_http_proxy, - const char *server, const char *port, - const char *path, - const STACK_OF(CONF_VALUE) *headers, - const char *content_type, BIO *req_mem, - int maxline, unsigned long max_resp_len, - int timeout, - const char *expected_content_type, - int expect_asn1) -{ - OSSL_HTTP_REQ_CTX *rctx; - - if (use_http_proxy && (server == NULL || port == NULL)) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - /* remaining parameters are checked indirectly by the functions called */ - - if ((rctx = OSSL_HTTP_REQ_CTX_new(wbio, rbio, req_mem == NULL, maxline, - max_resp_len, timeout, - expected_content_type, expect_asn1)) - == NULL) - return NULL; - - if (OSSL_HTTP_REQ_CTX_header(rctx, use_http_proxy ? server : NULL, - port, path) - && OSSL_HTTP_REQ_CTX_add1_headers(rctx, headers, server) - && (req_mem == NULL - || OSSL_HTTP_REQ_CTX_content(rctx, content_type, req_mem))) - return rctx; - - OSSL_HTTP_REQ_CTX_free(rctx); - return NULL; -} - -/* - * Parse first HTTP response line. This should be like this: "HTTP/1.0 200 OK". - * We need to obtain the numeric code and (optional) informational message. - */ - -static int parse_http_line1(char *line) -{ - int retcode; - char *code, *reason, *end; - - /* Skip to first whitespace (past protocol info) */ - for (code = line; *code != '\0' && !ossl_isspace(*code); code++) - continue; - if (*code == '\0') { - HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR); - return 0; - } - - /* Skip past whitespace to start of response code */ - while (*code != '\0' && ossl_isspace(*code)) - code++; - - if (*code == '\0') { - HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR); - return 0; - } - - /* Find end of response code: first whitespace after start of code */ - for (reason = code; *reason != '\0' && !ossl_isspace(*reason); reason++) - continue; - - if (*reason == '\0') { - HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR); - return 0; - } - - /* Set end of response code and start of message */ - *reason++ = '\0'; - - /* Attempt to parse numeric code */ - retcode = strtoul(code, &end, 10); - - if (*end != '\0') - return 0; - - /* Skip over any leading whitespace in message */ - while (*reason != '\0' && ossl_isspace(*reason)) - reason++; - - if (*reason != '\0') { - /* - * Finally zap any trailing whitespace in message (include CRLF) - */ - - /* chop any trailing whitespace from reason */ - /* We know reason has a non-whitespace character so this is OK */ - for (end = reason + strlen(reason) - 1; ossl_isspace(*end); end--) - *end = '\0'; - } - - switch (retcode) { - case HTTP_STATUS_CODE_OK: - case HTTP_STATUS_CODE_MOVED_PERMANENTLY: - case HTTP_STATUS_CODE_FOUND: - return retcode; - default: - if (retcode < 400) - HTTPerr(0, HTTP_R_STATUS_CODE_UNSUPPORTED); - else - HTTPerr(0, HTTP_R_RECEIVED_ERROR); - if (*reason == '\0') - ERR_add_error_data(2, "Code=", code); - else - ERR_add_error_data(4, "Code=", code, ",Reason=", reason); - return 0; - } -} - -static int check_set_resp_len(OSSL_HTTP_REQ_CTX *rctx, unsigned long len) -{ - const char *tag = NULL; - unsigned long val = 0; - - if (len > rctx->max_resp_len) { - HTTPerr(0, HTTP_R_MAX_RESP_LEN_EXCEEDED); - tag = ",max="; - val = rctx->max_resp_len; - } - if (rctx->resp_len != 0 && rctx->resp_len != len) { - HTTPerr(0, HTTP_R_INCONSISTENT_CONTENT_LENGTH); - tag = ",before="; - val = rctx->resp_len; - } - if (tag != NULL) { - char len_str[32]; - char str[32]; - - BIO_snprintf(len_str, sizeof(len_str), "%lu", len); - BIO_snprintf(str, sizeof(str), "%lu", val); - ERR_add_error_data(4, "length=", len_str, tag, str); - return 0; - } - rctx->resp_len = len; - return 1; -} - -/* - * Try exchanging request and response via HTTP on (non-)blocking BIO in rctx. - * Returns 1 on success, 0 on error or redirection, -1 on BIO_should_retry. - */ -int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx) -{ - int i; - long n, n_to_send = 0; - unsigned long resp_len; - const unsigned char *p; - char *key, *value, *line_end = NULL; - - if (rctx == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - rctx->redirection_url = NULL; - next_io: - if ((rctx->state & OHS_NOREAD) == 0) { - n = BIO_read(rctx->rbio, rctx->iobuf, rctx->iobuflen); - if (n <= 0) { - if (BIO_should_retry(rctx->rbio)) - return -1; - return 0; - } - - /* Write data to memory BIO */ - if (BIO_write(rctx->mem, rctx->iobuf, n) != n) - return 0; - } - - switch (rctx->state) { - case OHS_HTTP_HEADER: - /* Last operation was adding headers: need a final \r\n */ - if (BIO_write(rctx->mem, "\r\n", 2) != 2) { - rctx->state = OHS_ERROR; - return 0; - } - rctx->state = OHS_WRITE_INIT; - - /* fall thru */ - case OHS_WRITE_INIT: - n_to_send = BIO_get_mem_data(rctx->mem, NULL); - rctx->state = OHS_WRITE; - - /* fall thru */ - case OHS_WRITE: - n = BIO_get_mem_data(rctx->mem, &p); - - i = BIO_write(rctx->wbio, p + (n - n_to_send), n_to_send); - - if (i <= 0) { - if (BIO_should_retry(rctx->wbio)) - return -1; - rctx->state = OHS_ERROR; - return 0; - } - - n_to_send -= i; - - if (n_to_send > 0) - goto next_io; - - rctx->state = OHS_FLUSH; - - (void)BIO_reset(rctx->mem); - - /* fall thru */ - case OHS_FLUSH: - - i = BIO_flush(rctx->wbio); - - if (i > 0) { - rctx->state = OHS_FIRSTLINE; - goto next_io; - } - - if (BIO_should_retry(rctx->wbio)) - return -1; - - rctx->state = OHS_ERROR; - return 0; - - case OHS_ERROR: - return 0; - - case OHS_FIRSTLINE: - case OHS_HEADERS: - case OHS_REDIRECT: - - /* Attempt to read a line in */ - next_line: - /* - * Due to strange memory BIO behavior with BIO_gets we have to check - * there's a complete line in there before calling BIO_gets or we'll - * just get a partial read. - */ - n = BIO_get_mem_data(rctx->mem, &p); - if (n <= 0 || memchr(p, '\n', n) == 0) { - if (n >= rctx->iobuflen) { - rctx->state = OHS_ERROR; - return 0; - } - goto next_io; - } - n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen); - - if (n <= 0) { - if (BIO_should_retry(rctx->mem)) - goto next_io; - rctx->state = OHS_ERROR; - return 0; - } - - /* Don't allow excessive lines */ - if (n == rctx->iobuflen) { - HTTPerr(0, HTTP_R_RESPONSE_LINE_TOO_LONG); - rctx->state = OHS_ERROR; - return 0; - } - - /* First line */ - if (rctx->state == OHS_FIRSTLINE) { - switch (parse_http_line1((char *)rctx->iobuf)) { - case HTTP_STATUS_CODE_OK: - rctx->state = OHS_HEADERS; - goto next_line; - case HTTP_STATUS_CODE_MOVED_PERMANENTLY: - case HTTP_STATUS_CODE_FOUND: /* i.e., moved temporarily */ - if (rctx->method_GET) { - rctx->state = OHS_REDIRECT; - goto next_line; - } - HTTPerr(0, HTTP_R_REDIRECTION_NOT_ENABLED); - /* redirection is not supported/recommended for POST */ - /* fall through */ - default: - rctx->state = OHS_ERROR; - return 0; - } - } - key = (char *)rctx->iobuf; - value = strchr(key, ':'); - if (value != NULL) { - *(value++) = '\0'; - while (ossl_isspace(*value)) - value++; - line_end = strchr(value, '\r'); - if (line_end == NULL) - line_end = strchr(value, '\n'); - if (line_end != NULL) - *line_end = '\0'; - } - if (value != NULL && line_end != NULL) { - if (rctx->state == OHS_REDIRECT - && strcasecmp(key, "Location") == 0) { - rctx->redirection_url = value; - return 0; - } - if (rctx->expected_ct != NULL - && strcasecmp(key, "Content-Type") == 0) { - if (strcasecmp(rctx->expected_ct, value) != 0) { - HTTPerr(0, HTTP_R_UNEXPECTED_CONTENT_TYPE); - ERR_add_error_data(4, "expected=", rctx->expected_ct, - ",actual=", value); - return 0; - } - rctx->expected_ct = NULL; /* content-type has been found */ - } - if (strcasecmp(key, "Content-Length") == 0) { - resp_len = strtoul(value, &line_end, 10); - if (line_end == value || *line_end != '\0') { - HTTPerr(0, HTTP_R_ERROR_PARSING_CONTENT_LENGTH); - ERR_add_error_data(2, "input=", value); - return 0; - } - if (!check_set_resp_len(rctx, resp_len)) - return 0; - } - } - - /* Look for blank line: end of headers */ - for (p = rctx->iobuf; *p != '\0'; p++) { - if (*p != '\r' && *p != '\n') - break; - } - if (*p != '\0') /* not end of headers */ - goto next_line; - - if (rctx->expected_ct != NULL) { - HTTPerr(0, HTTP_R_MISSING_CONTENT_TYPE); - ERR_add_error_data(2, "expected=", rctx->expected_ct); - return 0; - } - if (rctx->state == OHS_REDIRECT) { - /* http status code indicated redirect but there was no Location */ - HTTPerr(0, HTTP_R_MISSING_REDIRECT_LOCATION); - return 0; - } - - if (!rctx->expect_asn1) { - rctx->state = OHS_CONTENT; - goto content; - } - - rctx->state = OHS_ASN1_HEADER; - - /* Fall thru */ - case OHS_ASN1_HEADER: - /* - * Now reading ASN1 header: can read at least 2 bytes which is enough - * for ASN1 SEQUENCE header and either length field or at least the - * length of the length field. - */ - n = BIO_get_mem_data(rctx->mem, &p); - if (n < 2) - goto next_io; - - /* Check it is an ASN1 SEQUENCE */ - if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) { - HTTPerr(0, HTTP_R_MISSING_ASN1_ENCODING); - return 0; - } - - /* Check out length field */ - if ((*p & 0x80) != 0) { - /* - * If MSB set on initial length octet we can now always read 6 - * octets: make sure we have them. - */ - if (n < 6) - goto next_io; - n = *p & 0x7F; - /* Not NDEF or excessive length */ - if (n == 0 || (n > 4)) { - HTTPerr(0, HTTP_R_ERROR_PARSING_ASN1_LENGTH); - return 0; - } - p++; - resp_len = 0; - for (i = 0; i < n; i++) { - resp_len <<= 8; - resp_len |= *p++; - } - resp_len += n + 2; - } else { - resp_len = *p + 2; - } - if (!check_set_resp_len(rctx, resp_len)) - return 0; - - content: - rctx->state = OHS_CONTENT; - - /* Fall thru */ - case OHS_CONTENT: - default: - n = BIO_get_mem_data(rctx->mem, NULL); - if (n < (long)rctx->resp_len /* may be 0 if no Content-Type or ASN.1 */) - goto next_io; - - rctx->state = OHS_DONE; - return 1; - } -} - -#ifndef OPENSSL_NO_SOCK - -/* set up a new connection BIO, to HTTP server or to HTTP(S) proxy if given */ -static BIO *HTTP_new_bio(const char *server /* optionally includes ":port" */, - const char *server_port /* explicit server port */, - const char *proxy /* optionally includes ":port" */) -{ - const char *host = server, *host_end; - char host_name[100]; - const char *port = server_port; - BIO *cbio; - - if (!ossl_assert(server != NULL)) - return NULL; - - if (proxy != NULL) { - host = proxy; - port = NULL; - } - - host_end = strchr(host, '/'); - if (host_end != NULL && (size_t)(host_end - host) < sizeof(host_name)) { - /* chop trailing string starting with '/' */ - strncpy(host_name, host, host_end - host + 1); - host = host_name; - } - - cbio = BIO_new_connect(host /* optionally includes ":port" */); - if (cbio == NULL) - goto end; - if (port != NULL) - (void)BIO_set_conn_port(cbio, port); - - end: - return cbio; -} -#endif /* OPENSSL_NO_SOCK */ - -static ASN1_VALUE *BIO_mem_d2i(BIO *mem, const ASN1_ITEM *it) -{ - const unsigned char *p; - long len = BIO_get_mem_data(mem, &p); - ASN1_VALUE *resp = ASN1_item_d2i(NULL, &p, len, it); - - if (resp == NULL) - HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR); - return resp; -} - -static BIO *OSSL_HTTP_REQ_CTX_transfer(OSSL_HTTP_REQ_CTX *rctx) -{ - int sending = 1; - int rv; - - if (rctx == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - - for (;;) { - rv = OSSL_HTTP_REQ_CTX_nbio(rctx); - if (rv != -1) - break; - /* BIO_should_retry was true */ - sending = 0; - /* will not actually wait if rctx->max_time == 0 */ - if (BIO_wait(rctx->rbio, rctx->max_time, 100 /* milliseconds */) <= 0) - return NULL; - } - - if (rv == 0) { - if (rctx->redirection_url == NULL) { /* an error occurred */ - if (sending && (rctx->state & OHS_NOREAD) != 0) - HTTPerr(0, HTTP_R_ERROR_SENDING); - else - HTTPerr(0, HTTP_R_ERROR_RECEIVING); - } - return NULL; - } - if (!BIO_up_ref(rctx->mem)) - return NULL; - return rctx->mem; -} - -/* Exchange ASN.1-encoded request and response via HTTP on (non-)blocking BIO */ -ASN1_VALUE *OSSL_HTTP_REQ_CTX_sendreq_d2i(OSSL_HTTP_REQ_CTX *rctx, - const ASN1_ITEM *it) -{ - if (rctx == NULL || it == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - return BIO_mem_d2i(OSSL_HTTP_REQ_CTX_transfer(rctx), it); -} - -static int update_timeout(int timeout, time_t start_time) -{ - long elapsed_time; - - if (timeout == 0) - return 0; - elapsed_time = (long)(time(NULL) - start_time); /* this might overflow */ - return timeout <= elapsed_time ? -1 : timeout - elapsed_time; -} - -/*- - * Exchange HTTP request and response with the given server. - * If req_mem == NULL then use GET and ignore content_type, else POST. - * The redirection_url output (freed by caller) parameter is used only for GET. - * - * Typically the bio and rbio parameters are NULL and a network BIO is created - * internally for connecting to the given server and port, optionally via a - * proxy and its port, and is then used for exchanging the request and response. - * If bio is given and rbio is NULL then this BIO is used instead. - * If both bio and rbio are given (which may be memory BIOs for instance) - * then no explicit connection is attempted, - * bio is used for writing the request, and rbio for reading the response. - * - * bio_update_fn is an optional BIO connect/disconnect callback function, - * which has the prototype - * BIO *(*OSSL_HTTP_bio_cb_t) (BIO *bio, void *arg, int conn, int detail); - * The callback may modify the HTTP BIO provided in the bio argument, - * whereby it may make use of any custom defined argument 'arg'. - * During connection establishment, just after BIO_connect_retry(), - * the callback function is invoked with the 'conn' argument being 1 - * 'detail' indicating whether a HTTPS (i.e., TLS) connection is requested. - * On disconnect 'conn' is 0 and 'detail' indicates that no error occurred. - * For instance, on connect the funct may prepend a TLS BIO to implement HTTPS; - * after disconnect it may do some error diagnostics and/or specific cleanup. - * The function should return NULL to indicate failure. - * After disconnect the modified BIO will be deallocated using BIO_free_all(). - */ -BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path, - int use_ssl, const char *proxy, const char *no_proxy, - BIO *bio, BIO *rbio, - OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, - const STACK_OF(CONF_VALUE) *headers, - const char *content_type, BIO *req_mem, - int maxline, unsigned long max_resp_len, int timeout, - const char *expected_ct, int expect_asn1, - char **redirection_url) -{ - time_t start_time = timeout > 0 ? time(NULL) : 0; - BIO *cbio; /* = bio if present, used as connection BIO if rbio is NULL */ - OSSL_HTTP_REQ_CTX *rctx; - BIO *resp = NULL; - - if (redirection_url != NULL) - *redirection_url = NULL; /* do this beforehand to prevent dbl free */ - - if (use_ssl && bio_update_fn == NULL) { - HTTPerr(0, HTTP_R_TLS_NOT_ENABLED); - return NULL; - } - if (rbio != NULL && (bio == NULL || bio_update_fn != NULL)) { - HTTPerr(0, ERR_R_PASSED_INVALID_ARGUMENT); - return NULL; - } - - if (bio != NULL) { - cbio = bio; - } else { -#ifndef OPENSSL_NO_SOCK - if (server == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - if (*port == '\0') - port = NULL; - if (port == NULL && strchr(server, ':') == NULL) - port = use_ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT; - proxy = http_adapt_proxy(proxy, no_proxy, server, use_ssl); - if ((cbio = HTTP_new_bio(server, port, proxy)) == NULL) - return NULL; -#else - HTTPerr(0, HTTP_R_SOCK_NOT_SUPPORTED); - return NULL; -#endif - } - /* remaining parameters are checked indirectly by the functions called */ - - (void)ERR_set_mark(); /* prepare removing any spurious libssl errors */ - if (rbio == NULL && BIO_connect_retry(cbio, timeout) <= 0) - goto end; - /* now timeout is guaranteed to be >= 0 */ - - /* callback can be used to wrap or prepend TLS session */ - if (bio_update_fn != NULL) { - BIO *orig_bio = cbio; - cbio = (*bio_update_fn)(cbio, arg, 1 /* connect */, use_ssl); - if (cbio == NULL) { - cbio = orig_bio; - goto end; - } - } - - rctx = HTTP_REQ_CTX_new(cbio, rbio != NULL ? rbio : cbio, - !use_ssl && proxy != NULL, server, port, path, - headers, content_type, req_mem, maxline, - max_resp_len, update_timeout(timeout, start_time), - expected_ct, expect_asn1); - if (rctx == NULL) - goto end; - - resp = OSSL_HTTP_REQ_CTX_transfer(rctx); - if (resp == NULL) { - if (rctx->redirection_url != NULL) { - if (redirection_url == NULL) - HTTPerr(0, HTTP_R_REDIRECTION_NOT_ENABLED); - else - /* may be NULL if out of memory: */ - *redirection_url = OPENSSL_strdup(rctx->redirection_url); - } else { - char buf[200]; - unsigned long err = ERR_peek_error(); - int lib = ERR_GET_LIB(err); - int reason = ERR_GET_REASON(err); - - if (lib == ERR_LIB_SSL || lib == ERR_LIB_HTTP - || (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_TIMEOUT) - || (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_ERROR) -#ifndef OPENSSL_NO_CMP - || (lib == ERR_LIB_CMP - && reason == CMP_R_POTENTIALLY_INVALID_CERTIFICATE) -#endif - ) { - BIO_snprintf(buf, 200, "server=%s:%s", server, port); - ERR_add_error_data(1, buf); - if (proxy != NULL) - ERR_add_error_data(2, " proxy=", proxy); - if (err == 0) { - BIO_snprintf(buf, 200, " peer has disconnected%s", - use_ssl ? " violating the protocol" : - ", likely because it requires the use of TLS"); - ERR_add_error_data(1, buf); - } - } - } - } - OSSL_HTTP_REQ_CTX_free(rctx); - - /* callback can be used to clean up TLS session */ - if (bio_update_fn != NULL - && (*bio_update_fn)(cbio, arg, 0, resp != NULL) == NULL) { - BIO_free(resp); - resp = NULL; - } - - end: - /* - * Use BIO_free_all() because bio_update_fn may prepend or append to cbio. - * This also frees any (e.g., SSL/TLS) BIOs linked with bio and, - * like BIO_reset(bio), calls SSL_shutdown() to notify/alert the peer. - */ - if (bio == NULL) /* cbio was not provided by caller */ - BIO_free_all(cbio); - - if (resp != NULL) - /* remove any spurious error queue entries by ssl_add_cert_chain() */ - (void)ERR_pop_to_mark(); - else - (void)ERR_clear_last_mark(); - - return resp; -} - -static int redirection_ok(int n_redir, const char *old_url, const char *new_url) -{ - size_t https_len = strlen(OSSL_HTTPS_NAME":"); - - if (n_redir >= HTTP_VERSION_MAX_REDIRECTIONS) { - HTTPerr(0, HTTP_R_TOO_MANY_REDIRECTIONS); - return 0; - } - if (*new_url == '/') /* redirection to same server => same protocol */ - return 1; - if (strncmp(old_url, OSSL_HTTPS_NAME":", https_len) == 0 && - strncmp(new_url, OSSL_HTTPS_NAME":", https_len) != 0) { - HTTPerr(0, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP); - return 0; - } - return 1; -} - -/* Get data via HTTP from server at given URL, potentially with redirection */ -BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, - BIO *bio, BIO *rbio, - OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, - const STACK_OF(CONF_VALUE) *headers, - int maxline, unsigned long max_resp_len, int timeout, - const char *expected_content_type, int expect_asn1) -{ - time_t start_time = timeout > 0 ? time(NULL) : 0; - char *current_url, *redirection_url; - int n_redirs = 0; - char *host; - char *port; - char *path; - int use_ssl; - BIO *resp = NULL; - - if (url == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - if ((current_url = OPENSSL_strdup(url)) == NULL) - return NULL; - - for (;;) { - if (!OSSL_HTTP_parse_url(current_url, &host, &port, &path, &use_ssl)) - break; - - new_rpath: - resp = OSSL_HTTP_transfer(host, port, path, use_ssl, proxy, no_proxy, - bio, rbio, - bio_update_fn, arg, headers, NULL, NULL, - maxline, max_resp_len, - update_timeout(timeout, start_time), - expected_content_type, expect_asn1, - &redirection_url); - OPENSSL_free(path); - if (resp == NULL && redirection_url != NULL) { - if (redirection_ok(++n_redirs, current_url, redirection_url)) { - (void)BIO_reset(bio); - OPENSSL_free(current_url); - current_url = redirection_url; - if (*redirection_url == '/') { /* redirection to same server */ - path = OPENSSL_strdup(redirection_url); - goto new_rpath; - } - OPENSSL_free(host); - OPENSSL_free(port); - continue; - } - OPENSSL_free(redirection_url); - } - OPENSSL_free(host); - OPENSSL_free(port); - break; - } - OPENSSL_free(current_url); - return resp; -} - -/* Get ASN.1-encoded data via HTTP from server at given URL */ -ASN1_VALUE *OSSL_HTTP_get_asn1(const char *url, - const char *proxy, const char *no_proxy, - BIO *bio, BIO *rbio, - OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, - const STACK_OF(CONF_VALUE) *headers, - int maxline, unsigned long max_resp_len, - int timeout, const char *expected_content_type, - const ASN1_ITEM *it) -{ - BIO *mem; - ASN1_VALUE *resp = NULL; - - if (url == NULL || it == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - if ((mem = OSSL_HTTP_get(url, proxy, no_proxy, bio, rbio, bio_update_fn, - arg, headers, maxline, max_resp_len, timeout, - expected_content_type, 1 /* expect_asn1 */)) - != NULL) - resp = BIO_mem_d2i(mem, it); - BIO_free(mem); - return resp; -} - -/* Post ASN.1-encoded request via HTTP to server return ASN.1 response */ -ASN1_VALUE *OSSL_HTTP_post_asn1(const char *server, const char *port, - const char *path, int use_ssl, - const char *proxy, const char *no_proxy, - BIO *bio, BIO *rbio, - OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, - const STACK_OF(CONF_VALUE) *headers, - const char *content_type, - const ASN1_VALUE *req, const ASN1_ITEM *req_it, - int maxline, unsigned long max_resp_len, - int timeout, const char *expected_ct, - const ASN1_ITEM *rsp_it) -{ - BIO *req_mem; - BIO *res_mem; - ASN1_VALUE *resp = NULL; - - if (req == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - /* remaining parameters are checked indirectly */ - - req_mem = HTTP_asn1_item2bio(req_it, req); - res_mem = OSSL_HTTP_transfer(server, port, path, use_ssl, proxy, no_proxy, - bio, rbio, - bio_update_fn, arg, headers, content_type, - req_mem /* may be NULL */, maxline, - max_resp_len, timeout, - expected_ct, 1 /* expect_asn1 */, NULL); - BIO_free(req_mem); - if (res_mem != NULL) - resp = BIO_mem_d2i(res_mem, rsp_it); - BIO_free(res_mem); - return resp; -} - -/* BASE64 encoder used for encoding basic proxy authentication credentials */ -static char *base64encode(const void *buf, size_t len) -{ - int i; - size_t outl; - char *out; - - /* Calculate size of encoded data */ - outl = (len / 3); - if (len % 3 > 0) - outl++; - outl <<= 2; - out = OPENSSL_malloc(outl + 1); - if (out == NULL) - return 0; - - i = EVP_EncodeBlock((unsigned char *)out, buf, len); - if (!ossl_assert(0 <= i && (size_t)i <= outl)) { - OPENSSL_free(out); - return NULL; - } - return out; -} - -/* - * Promote the given connection BIO using the CONNECT method for a TLS proxy. - * This is typically called by an app, so bio_err and prog are used unless NULL - * to print additional diagnostic information in a user-oriented way. - */ -int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port, - const char *proxyuser, const char *proxypass, - int timeout, BIO *bio_err, const char *prog) -{ -#undef BUF_SIZE -#define BUF_SIZE (8 * 1024) - char *mbuf = OPENSSL_malloc(BUF_SIZE); - char *mbufp; - int read_len = 0; - int ret = 0; - BIO *fbio = BIO_new(BIO_f_buffer()); - int rv; - time_t max_time = timeout > 0 ? time(NULL) + timeout : 0; - - if (bio == NULL || server == NULL - || (bio_err != NULL && prog == NULL)) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - goto end; - } - if (port == NULL || *port == '\0') - port = OSSL_HTTPS_PORT; - - if (mbuf == NULL || fbio == NULL) { - BIO_printf(bio_err /* may be NULL */, "%s: out of memory", prog); - goto end; - } - BIO_push(fbio, bio); - - BIO_printf(fbio, "CONNECT %s:%s "HTTP_PREFIX"1.0\r\n", server, port); - - /* - * Workaround for broken proxies which would otherwise close - * the connection when entering tunnel mode (e.g., Squid 2.6) - */ - BIO_printf(fbio, "Proxy-Connection: Keep-Alive\r\n"); - - /* Support for basic (base64) proxy authentication */ - if (proxyuser != NULL) { - size_t len = strlen(proxyuser) + 1; - char *proxyauth, *proxyauthenc = NULL; - - if (proxypass != NULL) - len += strlen(proxypass); - proxyauth = OPENSSL_malloc(len + 1); - if (proxyauth == NULL) - goto end; - if (BIO_snprintf(proxyauth, len + 1, "%s:%s", proxyuser, - proxypass != NULL ? proxypass : "") != (int)len) - goto proxy_end; - proxyauthenc = base64encode(proxyauth, len); - if (proxyauthenc != NULL) { - BIO_printf(fbio, "Proxy-Authorization: Basic %s\r\n", proxyauthenc); - OPENSSL_clear_free(proxyauthenc, strlen(proxyauthenc)); - } - proxy_end: - OPENSSL_clear_free(proxyauth, len); - if (proxyauthenc == NULL) - goto end; - } - - /* Terminate the HTTP CONNECT request */ - BIO_printf(fbio, "\r\n"); - - for (;;) { - if (BIO_flush(fbio) != 0) - break; - /* potentially needs to be retried if BIO is non-blocking */ - if (!BIO_should_retry(fbio)) - break; - } - - for (;;) { - /* will not actually wait if timeout == 0 */ - rv = BIO_wait(fbio, max_time, 100 /* milliseconds */); - if (rv <= 0) { - BIO_printf(bio_err, "%s: HTTP CONNECT %s\n", prog, - rv == 0 ? "timed out" : "failed waiting for data"); - goto end; - } - - /*- - * The first line is the HTTP response. - * According to RFC 7230, it is formatted exactly like this: - * HTTP/d.d ddd Reason text\r\n - */ - read_len = BIO_gets(fbio, mbuf, BUF_SIZE); - /* the BIO may not block, so we must wait for the 1st line to come in */ - if (read_len < HTTP_LINE1_MINLEN) - continue; - - /* RFC 7231 4.3.6: any 2xx status code is valid */ - if (strncmp(mbuf, HTTP_PREFIX, strlen(HTTP_PREFIX)) != 0) { - HTTPerr(0, HTTP_R_RESPONSE_PARSE_ERROR); - BIO_printf(bio_err, "%s: HTTP CONNECT failed, non-HTTP response\n", - prog); - /* Wrong protocol, not even HTTP, so stop reading headers */ - goto end; - } - mbufp = mbuf + strlen(HTTP_PREFIX); - if (strncmp(mbufp, HTTP_VERSION_PATT, strlen(HTTP_VERSION_PATT)) != 0) { - HTTPerr(0, HTTP_R_RECEIVED_WRONG_HTTP_VERSION); - BIO_printf(bio_err, - "%s: HTTP CONNECT failed, bad HTTP version %.*s\n", - prog, HTTP_VERSION_STR_LEN, mbufp); - goto end; - } - mbufp += HTTP_VERSION_STR_LEN; - if (strncmp(mbufp, " 2", strlen(" 2")) != 0) { - mbufp += 1; - /* chop any trailing whitespace */ - while (read_len > 0 && ossl_isspace(mbuf[read_len - 1])) - read_len--; - mbuf[read_len] = '\0'; - HTTPerr(0, HTTP_R_CONNECT_FAILURE); - ERR_add_error_data(2, "Reason=", mbufp); - BIO_printf(bio_err, "%s: HTTP CONNECT failed, Reason=%s\n", - prog, mbufp); - goto end; - } - ret = 1; - break; - } - - /* Read past all following headers */ - do { - /* - * TODO: This does not necessarily catch the case when the full - * HTTP response came in in more than a single TCP message. - */ - read_len = BIO_gets(fbio, mbuf, BUF_SIZE); - } while (read_len > 2); - - end: - if (fbio != NULL) { - (void)BIO_flush(fbio); - BIO_pop(fbio); - BIO_free(fbio); - } - OPENSSL_free(mbuf); - return ret; -#undef BUF_SIZE -} diff --git a/crypto/http/http_err.c b/crypto/http/http_err.c deleted file mode 100644 index 7b6f2951..00000000 --- a/crypto/http/http_err.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA HTTP_str_reasons[] = { - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN), - "asn1 len exceeds max resp len"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_CONNECT_FAILURE), "connect failure"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_ASN1_LENGTH), - "error parsing asn1 length"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_CONTENT_LENGTH), - "error parsing content length"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_URL), "error parsing url"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_RECEIVING), "error receiving"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_SENDING), "error sending"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INCONSISTENT_CONTENT_LENGTH), - "inconsistent content length"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MAX_RESP_LEN_EXCEEDED), - "max resp len exceeded"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_ASN1_ENCODING), - "missing asn1 encoding"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_CONTENT_TYPE), - "missing content type"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_REDIRECT_LOCATION), - "missing redirect location"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RECEIVED_ERROR), "received error"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RECEIVED_WRONG_HTTP_VERSION), - "received wrong http version"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP), - "redirection from https to http"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_REDIRECTION_NOT_ENABLED), - "redirection not enabled"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_LINE_TOO_LONG), - "response line too long"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_PARSE_ERROR), - "response parse error"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SOCK_NOT_SUPPORTED), - "sock not supported"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_STATUS_CODE_UNSUPPORTED), - "status code unsupported"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_TLS_NOT_ENABLED), "tls not enabled"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_TOO_MANY_REDIRECTIONS), - "too many redirections"}, - {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_UNEXPECTED_CONTENT_TYPE), - "unexpected content type"}, - {0, NULL} -}; - -#endif - -int ERR_load_HTTP_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(HTTP_str_reasons[0].error) == NULL) - ERR_load_strings_const(HTTP_str_reasons); -#endif - return 1; -} diff --git a/crypto/http/http_lib.c b/crypto/http/http_lib.c deleted file mode 100644 index 5da5b1e7..00000000 --- a/crypto/http/http_lib.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include "internal/cryptlib.h" /* for ossl_assert() */ - -#include "http_local.h" - -/* - * Parse a URL and split it up into host, port and path components and - * whether it indicates SSL/TLS. Return 1 on success, 0 on error. - */ - -int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport, - char **ppath, int *pssl) -{ - char *p, *buf; - char *host; - const char *port = OSSL_HTTP_PORT; - size_t https_len = strlen(OSSL_HTTPS_NAME); - - if (!ossl_assert(https_len >= strlen(OSSL_HTTP_NAME))) - return 0; - if (url == NULL) { - HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (phost != NULL) - *phost = NULL; - if (pport != NULL) - *pport = NULL; - if (ppath != NULL) - *ppath = NULL; - if (pssl != NULL) - *pssl = 0; - - /* dup the buffer since we are going to mess with it */ - if ((buf = OPENSSL_strdup(url)) == NULL) - goto err; - - /* Check for initial colon */ - p = strchr(buf, ':'); - if (p == NULL || (size_t)(p - buf) > https_len) { - p = buf; - } else { - *(p++) = '\0'; - - if (strcmp(buf, OSSL_HTTPS_NAME) == 0) { - if (pssl != NULL) - *pssl = 1; - port = OSSL_HTTPS_PORT; - } else if (strcmp(buf, OSSL_HTTP_NAME) != 0) { - goto parse_err; - } - - /* Check for double slash */ - if ((p[0] != '/') || (p[1] != '/')) - goto parse_err; - p += 2; - } - host = p; - - /* Check for trailing part of path */ - p = strchr(p, '/'); - if (ppath != NULL && (*ppath = OPENSSL_strdup(p == NULL ? "/" : p)) == NULL) - goto err; - if (p != NULL) - *p = '\0'; /* Set start of path to 0 so hostname[:port] is valid */ - - p = host; - if (host[0] == '[') { - /* ipv6 literal */ - host++; - p = strchr(host, ']'); - if (p == NULL) - goto parse_err; - *p = '\0'; - p++; - } - - /* Look for optional ':' for port number */ - if ((p = strchr(p, ':'))) { - *p = '\0'; - port = p + 1; - } - if (phost != NULL && (*phost = OPENSSL_strdup(host)) == NULL) - goto err; - if (pport != NULL && (*pport = OPENSSL_strdup(port)) == NULL) - goto err; - - OPENSSL_free(buf); - return 1; - - parse_err: - HTTPerr(0, HTTP_R_ERROR_PARSING_URL); - - err: - if (ppath != NULL) { - OPENSSL_free(*ppath); - *ppath = NULL; - } - if (pport != NULL) { - OPENSSL_free(*pport); - *pport = NULL; - } - if (phost != NULL) { - OPENSSL_free(*phost); - *phost = NULL; - } - OPENSSL_free(buf); - return 0; -} - -int http_use_proxy(const char *no_proxy, const char *server) -{ - size_t sl; - const char *found = NULL; - - if (!ossl_assert(server != NULL)) - return 0; - sl = strlen(server); - - /* - * using environment variable names, both lowercase and uppercase variants, - * compatible with other HTTP client implementations like wget, curl and git - */ - if (no_proxy == NULL) - no_proxy = getenv("no_proxy"); - if (no_proxy == NULL) - no_proxy = getenv(OPENSSL_NO_PROXY); - if (no_proxy != NULL) - found = strstr(no_proxy, server); - while (found != NULL - && ((found != no_proxy && found[-1] != ' ' && found[-1] != ',') - || (found[sl] != '\0' && found[sl] != ' ' && found[sl] != ','))) - found = strstr(found + 1, server); - return found == NULL; -} - -const char *http_adapt_proxy(const char *proxy, const char *no_proxy, - const char *server, int use_ssl) -{ - const int http_len = strlen(OSSL_HTTP_PREFIX); - const int https_len = strlen(OSSL_HTTPS_PREFIX); - - /* - * using environment variable names, both lowercase and uppercase variants, - * compatible with other HTTP client implementations like wget, curl and git - */ - if (proxy == NULL) - proxy = getenv(use_ssl ? "https_proxy" : "http_proxy"); - if (proxy == NULL) - proxy = getenv(use_ssl ? OPENSSL_HTTP_PROXY : - OPENSSL_HTTPS_PROXY); - if (proxy == NULL) - return NULL; - - /* skip any leading "http://" or "https://" */ - if (strncmp(proxy, OSSL_HTTP_PREFIX, http_len) == 0) - proxy += http_len; - else if (strncmp(proxy, OSSL_HTTPS_PREFIX, https_len) == 0) - proxy += https_len; - - if (*proxy == '\0' || !http_use_proxy(no_proxy, server)) - return NULL; - return proxy; -} diff --git a/crypto/http/http_local.h b/crypto/http/http_local.h deleted file mode 100644 index 729d24e4..00000000 --- a/crypto/http/http_local.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. - * Copyright Siemens AG 2018-2020 - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_HTTP_LOCAL_H -# define OSSL_CRYPTO_HTTP_LOCAL_H - -# include - -/* name aliases for legacy names with name prefix "OCSP_" */ -typedef OCSP_REQ_CTX OSSL_HTTP_REQ_CTX; -/* functions meanwhile only used internally */ -# define OSSL_HTTP_REQ_CTX_new OCSP_REQ_CTX_new -# define OSSL_HTTP_REQ_CTX_free OCSP_REQ_CTX_free -# define OSSL_HTTP_REQ_CTX_header OCSP_REQ_CTX_http -# define OSSL_HTTP_REQ_CTX_add1_header OCSP_REQ_CTX_add1_header -# define OSSL_HTTP_REQ_CTX_i2d OCSP_REQ_CTX_i2d -# define OSSL_HTTP_REQ_CTX_nbio OCSP_REQ_CTX_nbio -# define OSSL_HTTP_REQ_CTX_sendreq_d2i OCSP_REQ_CTX_nbio_d2i -/* functions that are meanwhile unused */ -# define OSSL_HTTP_REQ_CTX_get0_mem_bio OCSP_REQ_CTX_get0_mem_bio /* undoc'd */ -# define OSSL_HTTP_REQ_CTX_set_max_response_length OCSP_set_max_response_length - -BIO *HTTP_asn1_item2bio(const ASN1_ITEM *it, const ASN1_VALUE *val); -OSSL_HTTP_REQ_CTX *HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int use_http_proxy, - const char *server, const char *port, - const char *path, - const STACK_OF(CONF_VALUE) *headers, - const char *content_type, BIO *req_mem, - int maxline, unsigned long max_resp_len, - int timeout, - const char *expected_content_type, - int expect_asn1); -ASN1_VALUE *HTTP_sendreq_bio(BIO *bio, OSSL_HTTP_bio_cb_t bio_update_fn, - void *arg, const char *server, const char *port, - const char *path, int use_ssl, int use_proxy, - const STACK_OF(CONF_VALUE) *headers, - const char *content_type, - ASN1_VALUE *req, const ASN1_ITEM *req_it, - int maxline, unsigned long max_resp_len, - int timeout, const ASN1_ITEM *rsp_it); -int http_use_proxy(const char *no_proxy, const char *server); -const char *http_adapt_proxy(const char *proxy, const char *no_proxy, - const char *server, int use_ssl); - -#endif /* !defined(OSSL_CRYPTO_HTTP_LOCAL_H) */ diff --git a/crypto/modes/cbc128.c b/crypto/modes/cbc128.c index eec44bd9..df0ab244 100644 --- a/crypto/modes/cbc128.c +++ b/crypto/modes/cbc128.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,6 +15,12 @@ # define STRICT_ALIGNMENT 0 #endif +#if defined(__GNUC__) && !STRICT_ALIGNMENT +typedef size_t size_t_aX __attribute((__aligned__(1))); +#else +typedef size_t size_t_aX; +#endif + void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, size_t len, const void *key, unsigned char ivec[16], block128_f block) @@ -40,8 +46,8 @@ void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, } else { while (len >= 16) { for (n = 0; n < 16; n += sizeof(size_t)) - *(size_t *)(out + n) = - *(size_t *)(in + n) ^ *(size_t *)(iv + n); + *(size_t_aX *)(out + n) = + *(size_t_aX *)(in + n) ^ *(size_t_aX *)(iv + n); (*block) (out, out, key); iv = out; len -= 16; @@ -96,7 +102,8 @@ void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, } } else if (16 % sizeof(size_t) == 0) { /* always true */ while (len >= 16) { - size_t *out_t = (size_t *)out, *iv_t = (size_t *)iv; + size_t_aX *out_t = (size_t_aX *)out; + size_t_aX *iv_t = (size_t_aX *)iv; (*block) (in, out, key); for (n = 0; n < 16 / sizeof(size_t); n++) @@ -125,8 +132,10 @@ void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, } } else if (16 % sizeof(size_t) == 0) { /* always true */ while (len >= 16) { - size_t c, *out_t = (size_t *)out, *ivec_t = (size_t *)ivec; - const size_t *in_t = (const size_t *)in; + size_t c; + size_t_aX *out_t = (size_t_aX *)out; + size_t_aX *ivec_t = (size_t_aX *)ivec; + const size_t_aX *in_t = (const size_t_aX *)in; (*block) (in, tmp.c, key); for (n = 0; n < 16 / sizeof(size_t); n++) { diff --git a/crypto/modes/ccm128.c b/crypto/modes/ccm128.c index 1ffd6df4..eee7a69c 100644 --- a/crypto/modes/ccm128.c +++ b/crypto/modes/ccm128.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,6 +11,14 @@ #include #include "crypto/modes.h" +#ifndef STRICT_ALIGNMENT +# ifdef __GNUC__ +typedef u64 u64_a1 __attribute((__aligned__(1))); +# else +typedef u64 u64_a1; +# endif +#endif + /* * First you setup M and L parameters and pass the key schedule. This is * called once per session setup... @@ -170,8 +178,8 @@ int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, ctx->cmac.u[0] ^= temp.u[0]; ctx->cmac.u[1] ^= temp.u[1]; #else - ctx->cmac.u[0] ^= ((u64 *)inp)[0]; - ctx->cmac.u[1] ^= ((u64 *)inp)[1]; + ctx->cmac.u[0] ^= ((u64_a1 *)inp)[0]; + ctx->cmac.u[1] ^= ((u64_a1 *)inp)[1]; #endif (*block) (ctx->cmac.c, ctx->cmac.c, key); (*block) (ctx->nonce.c, scratch.c, key); @@ -181,8 +189,8 @@ int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, temp.u[1] ^= scratch.u[1]; memcpy(out, temp.c, 16); #else - ((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]; - ((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]; + ((u64_a1 *)out)[0] = scratch.u[0] ^ ((u64_a1 *)inp)[0]; + ((u64_a1 *)out)[1] = scratch.u[1] ^ ((u64_a1 *)inp)[1]; #endif inp += 16; out += 16; @@ -254,8 +262,10 @@ int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]); memcpy(out, scratch.c, 16); #else - ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]); - ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]); + ctx->cmac.u[0] ^= (((u64_a1 *)out)[0] + = scratch.u[0] ^ ((u64_a1 *)inp)[0]); + ctx->cmac.u[1] ^= (((u64_a1 *)out)[1] + = scratch.u[1] ^ ((u64_a1 *)inp)[1]); #endif (*block) (ctx->cmac.c, ctx->cmac.c, key); diff --git a/crypto/modes/cfb128.c b/crypto/modes/cfb128.c index e9ce4df3..fa94f047 100644 --- a/crypto/modes/cfb128.c +++ b/crypto/modes/cfb128.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,6 +11,12 @@ #include #include "crypto/modes.h" +#if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) +typedef size_t size_t_aX __attribute((__aligned__(1))); +#else +typedef size_t size_t_aX; +#endif + /* * The input and output encrypted as though 128bit cfb mode is being used. * The extra state information to record how much of the 128bit block we have @@ -43,8 +49,9 @@ void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, while (len >= 16) { (*block) (ivec, ivec, key); for (; n < 16; n += sizeof(size_t)) { - *(size_t *)(out + n) = - *(size_t *)(ivec + n) ^= *(size_t *)(in + n); + *(size_t_aX *)(out + n) = + *(size_t_aX *)(ivec + n) + ^= *(size_t_aX *)(in + n); } len -= 16; out += 16; @@ -92,9 +99,10 @@ void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, while (len >= 16) { (*block) (ivec, ivec, key); for (; n < 16; n += sizeof(size_t)) { - size_t t = *(size_t *)(in + n); - *(size_t *)(out + n) = *(size_t *)(ivec + n) ^ t; - *(size_t *)(ivec + n) = t; + size_t t = *(size_t_aX *)(in + n); + *(size_t_aX *)(out + n) + = *(size_t_aX *)(ivec + n) ^ t; + *(size_t_aX *)(ivec + n) = t; } len -= 16; out += 16; diff --git a/crypto/modes/ctr128.c b/crypto/modes/ctr128.c index ff7499b3..ad25eb38 100644 --- a/crypto/modes/ctr128.c +++ b/crypto/modes/ctr128.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,6 +11,12 @@ #include #include "crypto/modes.h" +#if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) +typedef size_t size_t_aX __attribute((__aligned__(1))); +#else +typedef size_t size_t_aX; +#endif + /* * NOTE: the IV/counter CTR mode is big-endian. The code itself is * endian-neutral. @@ -97,8 +103,9 @@ void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, (*block) (ivec, ecount_buf, key); ctr128_inc_aligned(ivec); for (n = 0; n < 16; n += sizeof(size_t)) - *(size_t *)(out + n) = - *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n); + *(size_t_aX *)(out + n) = + *(size_t_aX *)(in + n) + ^ *(size_t_aX *)(ecount_buf + n); len -= 16; out += 16; in += 16; diff --git a/crypto/modes/gcm128.c b/crypto/modes/gcm128.c index d2f2da61..0cefa1c8 100644 --- a/crypto/modes/gcm128.c +++ b/crypto/modes/gcm128.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2010-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,6 +12,12 @@ #include "internal/cryptlib.h" #include "crypto/modes.h" +#if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) +typedef size_t size_t_aX __attribute((__aligned__(1))); +#else +typedef size_t size_t_aX; +#endif + #if defined(BSWAP4) && defined(STRICT_ALIGNMENT) /* redefine, because alignment is ensured */ # undef GETU32 @@ -1080,8 +1086,8 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, size_t j = GHASH_CHUNK; while (j) { - size_t *out_t = (size_t *)out; - const size_t *in_t = (const size_t *)in; + size_t_aX *out_t = (size_t_aX *)out; + const size_t_aX *in_t = (const size_t_aX *)in; (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; @@ -1107,8 +1113,8 @@ int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, size_t j = i; while (len >= 16) { - size_t *out_t = (size_t *)out; - const size_t *in_t = (const size_t *)in; + size_t_aX *out_t = (size_t_aX *)out; + const size_t_aX *in_t = (const size_t_aX *)in; (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; @@ -1318,8 +1324,8 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, GHASH(ctx, in, GHASH_CHUNK); while (j) { - size_t *out_t = (size_t *)out; - const size_t *in_t = (const size_t *)in; + size_t_aX *out_t = (size_t_aX *)out; + const size_t_aX *in_t = (const size_t_aX *)in; (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; @@ -1343,8 +1349,8 @@ int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, if ((i = (len & (size_t)-16))) { GHASH(ctx, in, i); while (len >= 16) { - size_t *out_t = (size_t *)out; - const size_t *in_t = (const size_t *)in; + size_t_aX *out_t = (size_t_aX *)out; + const size_t_aX *in_t = (const size_t_aX *)in; (*block) (ctx->Yi.c, ctx->EKi.c, key); ++ctr; diff --git a/crypto/modes/ofb128.c b/crypto/modes/ofb128.c index 2eca09bc..829d724e 100644 --- a/crypto/modes/ofb128.c +++ b/crypto/modes/ofb128.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,6 +11,12 @@ #include #include "crypto/modes.h" +#if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) +typedef size_t size_t_aX __attribute((__aligned__(1))); +#else +typedef size_t size_t_aX; +#endif + /* * The input and output encrypted as though 128bit ofb mode is being used. * The extra state information to record how much of the 128bit block we have @@ -41,8 +47,9 @@ void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, while (len >= 16) { (*block) (ivec, ivec, key); for (; n < 16; n += sizeof(size_t)) - *(size_t *)(out + n) = - *(size_t *)(in + n) ^ *(size_t *)(ivec + n); + *(size_t_aX *)(out + n) = + *(size_t_aX *)(in + n) + ^ *(size_t_aX *)(ivec + n); len -= 16; out += 16; in += 16; diff --git a/crypto/modes/siv128.c b/crypto/modes/siv128.c index f45e7e2f..72ae624c 100644 --- a/crypto/modes/siv128.c +++ b/crypto/modes/siv128.c @@ -99,7 +99,7 @@ __owur static ossl_inline int siv128_do_s2v_p(SIV128_CONTEXT *ctx, SIV_BLOCK *ou EVP_MAC_CTX *mac_ctx; int ret = 0; - mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init); + mac_ctx = EVP_MAC_dup_ctx(ctx->mac_ctx_init); if (mac_ctx == NULL) return 0; @@ -126,7 +126,7 @@ __owur static ossl_inline int siv128_do_s2v_p(SIV128_CONTEXT *ctx, SIV_BLOCK *ou ret = 1; err: - EVP_MAC_CTX_free(mac_ctx); + EVP_MAC_free_ctx(mac_ctx); return ret; } @@ -187,20 +187,20 @@ int CRYPTO_siv128_init(SIV128_CONTEXT *ctx, const unsigned char *key, int klen, /* TODO(3.0) library context */ || (ctx->mac = EVP_MAC_fetch(NULL, OSSL_MAC_NAME_CMAC, NULL)) == NULL - || (ctx->mac_ctx_init = EVP_MAC_CTX_new(ctx->mac)) == NULL - || !EVP_MAC_CTX_set_params(ctx->mac_ctx_init, params) + || (ctx->mac_ctx_init = EVP_MAC_new_ctx(ctx->mac)) == NULL + || !EVP_MAC_set_ctx_params(ctx->mac_ctx_init, params) || !EVP_EncryptInit_ex(ctx->cipher_ctx, ctr, NULL, key + klen, NULL) - || (mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init)) == NULL + || (mac_ctx = EVP_MAC_dup_ctx(ctx->mac_ctx_init)) == NULL || !EVP_MAC_update(mac_ctx, zero, sizeof(zero)) || !EVP_MAC_final(mac_ctx, ctx->d.byte, &out_len, sizeof(ctx->d.byte))) { EVP_CIPHER_CTX_free(ctx->cipher_ctx); - EVP_MAC_CTX_free(ctx->mac_ctx_init); - EVP_MAC_CTX_free(mac_ctx); + EVP_MAC_free_ctx(ctx->mac_ctx_init); + EVP_MAC_free_ctx(mac_ctx); EVP_MAC_free(ctx->mac); return 0; } - EVP_MAC_CTX_free(mac_ctx); + EVP_MAC_free_ctx(mac_ctx); ctx->final_ret = -1; ctx->crypto_ok = 1; @@ -216,8 +216,8 @@ int CRYPTO_siv128_copy_ctx(SIV128_CONTEXT *dest, SIV128_CONTEXT *src) memcpy(&dest->d, &src->d, sizeof(src->d)); if (!EVP_CIPHER_CTX_copy(dest->cipher_ctx, src->cipher_ctx)) return 0; - EVP_MAC_CTX_free(dest->mac_ctx_init); - dest->mac_ctx_init = EVP_MAC_CTX_dup(src->mac_ctx_init); + EVP_MAC_free_ctx(dest->mac_ctx_init); + dest->mac_ctx_init = EVP_MAC_dup_ctx(src->mac_ctx_init); if (dest->mac_ctx_init == NULL) return 0; return 1; @@ -237,15 +237,15 @@ int CRYPTO_siv128_aad(SIV128_CONTEXT *ctx, const unsigned char *aad, siv128_dbl(&ctx->d); - if ((mac_ctx = EVP_MAC_CTX_dup(ctx->mac_ctx_init)) == NULL + if ((mac_ctx = EVP_MAC_dup_ctx(ctx->mac_ctx_init)) == NULL || !EVP_MAC_update(mac_ctx, aad, len) || !EVP_MAC_final(mac_ctx, mac_out.byte, &out_len, sizeof(mac_out.byte)) || out_len != SIV_LEN) { - EVP_MAC_CTX_free(mac_ctx); + EVP_MAC_free_ctx(mac_ctx); return 0; } - EVP_MAC_CTX_free(mac_ctx); + EVP_MAC_free_ctx(mac_ctx); siv128_xorblock(&ctx->d, &mac_out); @@ -357,7 +357,7 @@ int CRYPTO_siv128_cleanup(SIV128_CONTEXT *ctx) if (ctx != NULL) { EVP_CIPHER_CTX_free(ctx->cipher_ctx); ctx->cipher_ctx = NULL; - EVP_MAC_CTX_free(ctx->mac_ctx_init); + EVP_MAC_free_ctx(ctx->mac_ctx_init); ctx->mac_ctx_init = NULL; EVP_MAC_free(ctx->mac); ctx->mac = NULL; diff --git a/crypto/modes/xts128.c b/crypto/modes/xts128.c index 9d9b65ca..0dec42c3 100644 --- a/crypto/modes/xts128.c +++ b/crypto/modes/xts128.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,6 +11,14 @@ #include #include "crypto/modes.h" +#ifndef STRICT_ALIGNMENT +# ifdef __GNUC__ +typedef u64 u64_a1 __attribute((__aligned__(1))); +# else +typedef u64 u64_a1; +# endif +#endif + int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, const unsigned char iv[16], const unsigned char *inp, unsigned char *out, @@ -45,8 +53,8 @@ int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, scratch.u[0] ^= tweak.u[0]; scratch.u[1] ^= tweak.u[1]; #else - scratch.u[0] = ((u64 *)inp)[0] ^ tweak.u[0]; - scratch.u[1] = ((u64 *)inp)[1] ^ tweak.u[1]; + scratch.u[0] = ((u64_a1 *)inp)[0] ^ tweak.u[0]; + scratch.u[1] = ((u64_a1 *)inp)[1] ^ tweak.u[1]; #endif (*ctx->block1) (scratch.c, scratch.c, ctx->key1); #if defined(STRICT_ALIGNMENT) @@ -54,8 +62,8 @@ int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, scratch.u[1] ^= tweak.u[1]; memcpy(out, scratch.c, 16); #else - ((u64 *)out)[0] = scratch.u[0] ^= tweak.u[0]; - ((u64 *)out)[1] = scratch.u[1] ^= tweak.u[1]; + ((u64_a1 *)out)[0] = scratch.u[0] ^= tweak.u[0]; + ((u64_a1 *)out)[1] = scratch.u[1] ^= tweak.u[1]; #endif inp += 16; out += 16; @@ -128,8 +136,8 @@ int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, scratch.u[0] ^= tweak1.u[0]; scratch.u[1] ^= tweak1.u[1]; #else - scratch.u[0] = ((u64 *)inp)[0] ^ tweak1.u[0]; - scratch.u[1] = ((u64 *)inp)[1] ^ tweak1.u[1]; + scratch.u[0] = ((u64_a1 *)inp)[0] ^ tweak1.u[0]; + scratch.u[1] = ((u64_a1 *)inp)[1] ^ tweak1.u[1]; #endif (*ctx->block1) (scratch.c, scratch.c, ctx->key1); scratch.u[0] ^= tweak1.u[0]; @@ -148,8 +156,8 @@ int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, scratch.u[1] ^= tweak.u[1]; memcpy(out, scratch.c, 16); #else - ((u64 *)out)[0] = scratch.u[0] ^ tweak.u[0]; - ((u64 *)out)[1] = scratch.u[1] ^ tweak.u[1]; + ((u64_a1 *)out)[0] = scratch.u[0] ^ tweak.u[0]; + ((u64_a1 *)out)[1] = scratch.u[1] ^ tweak.u[1]; #endif } diff --git a/crypto/o_str.c b/crypto/o_str.c index 6780188c..8aa1a2a4 100644 --- a/crypto/o_str.c +++ b/crypto/o_str.c @@ -1,5 +1,5 @@ /* - * Copyright 2003-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2003-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,6 +12,9 @@ #include #include "internal/cryptlib.h" +#define DEFAULT_SEPARATOR ':' +#define CH_ZERO '\0' + char *CRYPTO_strdup(const char *str, const char* file, int line) { char *ret; @@ -37,7 +40,7 @@ char *CRYPTO_strndup(const char *str, size_t s, const char* file, int line) ret = CRYPTO_malloc(maxlen + 1, file, line); if (ret) { memcpy(ret, str, maxlen); - ret[maxlen] = '\0'; + ret[maxlen] = CH_ZERO; } return ret; } @@ -61,7 +64,7 @@ size_t OPENSSL_strnlen(const char *str, size_t maxlen) { const char *p; - for (p = str; maxlen-- != 0 && *p != '\0'; ++p) ; + for (p = str; maxlen-- != 0 && *p != CH_ZERO; ++p) ; return p - str; } @@ -74,7 +77,7 @@ size_t OPENSSL_strlcpy(char *dst, const char *src, size_t size) l++; } if (size) - *dst = '\0'; + *dst = CH_ZERO; return l + strlen(src); } @@ -129,11 +132,8 @@ int OPENSSL_hexchar2int(unsigned char c) return -1; } -/* - * Give a string of hex digits convert to a buffer - */ -int OPENSSL_hexstr2buf_ex(unsigned char *buf, size_t buf_n, size_t *buflen, - const char *str) +static int hexstr2buf_sep(unsigned char *buf, size_t buf_n, size_t *buflen, + const char *str, const char sep) { unsigned char *q; unsigned char ch, cl; @@ -143,26 +143,24 @@ int OPENSSL_hexstr2buf_ex(unsigned char *buf, size_t buf_n, size_t *buflen, for (p = (const unsigned char *)str, q = buf, cnt = 0; *p; ) { ch = *p++; - if (ch == ':') + /* A separator of CH_ZERO means there is no separator */ + if (ch == sep && sep != CH_ZERO) continue; cl = *p++; if (!cl) { - CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF_EX, - CRYPTO_R_ODD_NUMBER_OF_DIGITS); + CRYPTOerr(0, CRYPTO_R_ODD_NUMBER_OF_DIGITS); return 0; } cli = OPENSSL_hexchar2int(cl); chi = OPENSSL_hexchar2int(ch); if (cli < 0 || chi < 0) { - CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF_EX, - CRYPTO_R_ILLEGAL_HEX_DIGIT); + CRYPTOerr(0, CRYPTO_R_ILLEGAL_HEX_DIGIT); return 0; } cnt++; if (q != NULL) { if (cnt > buf_n) { - CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF_EX, - CRYPTO_R_TOO_SMALL_BUFFER); + CRYPTOerr(0, CRYPTO_R_TOO_SMALL_BUFFER); return 0; } *q++ = (unsigned char)((chi << 4) | cli); @@ -174,21 +172,31 @@ int OPENSSL_hexstr2buf_ex(unsigned char *buf, size_t buf_n, size_t *buflen, return 1; } -unsigned char *OPENSSL_hexstr2buf(const char *str, long *buflen) +/* + * Given a string of hex digits convert to a buffer + */ +int OPENSSL_hexstr2buf_ex(unsigned char *buf, size_t buf_n, size_t *buflen, + const char *str) +{ + return hexstr2buf_sep(buf, buf_n, buflen, str, DEFAULT_SEPARATOR); +} + +unsigned char *openssl_hexstr2buf_sep(const char *str, long *buflen, + const char sep) { unsigned char *buf; size_t buf_n, tmp_buflen; buf_n = strlen(str) >> 1; if ((buf = OPENSSL_malloc(buf_n)) == NULL) { - CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, ERR_R_MALLOC_FAILURE); + CRYPTOerr(0, ERR_R_MALLOC_FAILURE); return NULL; } if (buflen != NULL) *buflen = 0; tmp_buflen = 0; - if (OPENSSL_hexstr2buf_ex(buf, buf_n, &tmp_buflen, str)) { + if (hexstr2buf_sep(buf, buf_n, &tmp_buflen, str, sep)) { if (buflen != NULL) *buflen = (long)tmp_buflen; return buf; @@ -197,21 +205,29 @@ unsigned char *OPENSSL_hexstr2buf(const char *str, long *buflen) return NULL; } -int OPENSSL_buf2hexstr_ex(char *str, size_t str_n, size_t *strlen, - const unsigned char *buf, size_t buflen) +unsigned char *OPENSSL_hexstr2buf(const char *str, long *buflen) +{ + return openssl_hexstr2buf_sep(str, buflen, DEFAULT_SEPARATOR); +} + +static int buf2hexstr_sep(char *str, size_t str_n, size_t *strlen, + const unsigned char *buf, size_t buflen, + const char sep) { static const char hexdig[] = "0123456789ABCDEF"; const unsigned char *p; char *q; size_t i; + int has_sep = (sep != CH_ZERO); + size_t len = has_sep ? buflen * 3 : 1 + buflen * 2; if (strlen != NULL) - *strlen = buflen * 3; + *strlen = len; if (str == NULL) return 1; - if (str_n < (unsigned long)buflen * 3) { - CRYPTOerr(CRYPTO_F_OPENSSL_BUF2HEXSTR_EX, CRYPTO_R_TOO_SMALL_BUFFER); + if (str_n < (unsigned long)len) { + CRYPTOerr(0, CRYPTO_R_TOO_SMALL_BUFFER); return 0; } @@ -219,15 +235,46 @@ int OPENSSL_buf2hexstr_ex(char *str, size_t str_n, size_t *strlen, for (i = 0, p = buf; i < buflen; i++, p++) { *q++ = hexdig[(*p >> 4) & 0xf]; *q++ = hexdig[*p & 0xf]; - *q++ = ':'; + if (has_sep) + *q++ = sep; } - q[-1] = 0; + if (has_sep) + --q; + *q = CH_ZERO; + #ifdef CHARSET_EBCDIC ebcdic2ascii(str, str, q - str - 1); #endif return 1; } +int OPENSSL_buf2hexstr_ex(char *str, size_t str_n, size_t *strlen, + const unsigned char *buf, size_t buflen) +{ + return buf2hexstr_sep(str, str_n, strlen, buf, buflen, DEFAULT_SEPARATOR); +} + +char *openssl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep) +{ + char *tmp; + size_t tmp_n; + + if (buflen == 0) + return OPENSSL_zalloc(1); + + tmp_n = (sep != CH_ZERO) ? buflen * 3 : 1 + buflen * 2; + if ((tmp = OPENSSL_malloc(tmp_n)) == NULL) { + CRYPTOerr(0, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (buf2hexstr_sep(tmp, tmp_n, NULL, buf, buflen, sep)) + return tmp; + OPENSSL_free(tmp); + return NULL; +} + + /* * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its * hex representation @@@ (Contents of buffer are always kept in ASCII, also @@ -235,22 +282,7 @@ int OPENSSL_buf2hexstr_ex(char *str, size_t str_n, size_t *strlen, */ char *OPENSSL_buf2hexstr(const unsigned char *buf, long buflen) { - char *tmp; - size_t tmp_n; - - if (buflen == 0) - return OPENSSL_zalloc(1); - - tmp_n = buflen * 3; - if ((tmp = OPENSSL_malloc(tmp_n)) == NULL) { - CRYPTOerr(CRYPTO_F_OPENSSL_BUF2HEXSTR, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (OPENSSL_buf2hexstr_ex(tmp, tmp_n, NULL, buf, buflen)) - return tmp; - OPENSSL_free(tmp); - return NULL; + return openssl_buf2hexstr_sep(buf, buflen, ':'); } int openssl_strerror_r(int errnum, char *buf, size_t buflen) diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index 06298cf7..b1b32d7b 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -1088,7 +1088,7 @@ static const unsigned char so[7845] = { 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x08, /* [ 7836] OBJ_NAIRealm */ }; -#define NUM_NID 1219 +#define NUM_NID 1220 static const ASN1_OBJECT nid_objs[NUM_NID] = { {"UNDEF", "undefined", NID_undef}, {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, @@ -2308,10 +2308,11 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { {"modp_4096", "modp_4096", NID_modp_4096}, {"modp_6144", "modp_6144", NID_modp_6144}, {"modp_8192", "modp_8192", NID_modp_8192}, + {"KxGOST18", "kx-gost18", NID_kx_gost18}, {"ChaCha20-Poly1305-D", "chacha20-poly1305-draft", NID_chacha20_poly1305_draft}, }; -#define NUM_SN 1210 +#define NUM_SN 1211 static const unsigned int sn_objs[NUM_SN] = { 364, /* "AD_DVCS" */ 419, /* "AES-128-CBC" */ @@ -2434,7 +2435,7 @@ static const unsigned int sn_objs[NUM_SN] = { 417, /* "CSPName" */ 1019, /* "ChaCha20" */ 1018, /* "ChaCha20-Poly1305" */ - 1218, /* "ChaCha20-Poly1305-D" */ + 1219, /* "ChaCha20-Poly1305-D" */ 367, /* "CrlID" */ 391, /* "DC" */ 31, /* "DES-CBC" */ @@ -2491,6 +2492,7 @@ static const unsigned int sn_objs[NUM_SN] = { 1038, /* "KxECDHE" */ 1040, /* "KxECDHE-PSK" */ 1045, /* "KxGOST" */ + 1218, /* "KxGOST18" */ 1043, /* "KxPSK" */ 1037, /* "KxRSA" */ 1042, /* "KxRSA_PSK" */ @@ -3525,7 +3527,7 @@ static const unsigned int sn_objs[NUM_SN] = { 1093, /* "x509ExtAdmission" */ }; -#define NUM_LN 1210 +#define NUM_LN 1211 static const unsigned int ln_objs[NUM_LN] = { 363, /* "AD Time Stamping" */ 405, /* "ANSI X9.62" */ @@ -3914,7 +3916,7 @@ static const unsigned int ln_objs[NUM_LN] = { 883, /* "certificateRevocationList" */ 1019, /* "chacha20" */ 1018, /* "chacha20-poly1305" */ - 1218, /* "chacha20-poly1305-draft" */ + 1219, /* "chacha20-poly1305-draft" */ 54, /* "challengePassword" */ 407, /* "characteristic-two-field" */ 395, /* "clearance" */ @@ -4337,6 +4339,7 @@ static const unsigned int ln_objs[NUM_LN] = { 1038, /* "kx-ecdhe" */ 1040, /* "kx-ecdhe-psk" */ 1045, /* "kx-gost" */ + 1218, /* "kx-gost18" */ 1043, /* "kx-psk" */ 1037, /* "kx-rsa" */ 1042, /* "kx-rsa-psk" */ diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index 2afe3992..c676e0a3 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1215,4 +1215,5 @@ modp_3072 1214 modp_4096 1215 modp_6144 1216 modp_8192 1217 -chacha20_poly1305_draft 1218 +kx_gost18 1218 +chacha20_poly1305_draft 1219 diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index 25aa503c..e1a68dae 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -1649,6 +1649,7 @@ id-pkinit 5 : pkInitKDC : Signing KDC Response : KxPSK : kx-psk : KxSRP : kx-srp : KxGOST : kx-gost + : KxGOST18 : kx-gost18 : KxANY : kx-any # NIDs for cipher authentication diff --git a/crypto/ocsp/build.info b/crypto/ocsp/build.info index 79a59004..0902caae 100644 --- a/crypto/ocsp/build.info +++ b/crypto/ocsp/build.info @@ -1,4 +1,4 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ - ocsp_asn.c ocsp_ext.c ocsp_http.c ocsp_lib.c ocsp_cl.c \ + ocsp_asn.c ocsp_ext.c ocsp_ht.c ocsp_lib.c ocsp_cl.c \ ocsp_srv.c ocsp_prn.c ocsp_vfy.c ocsp_err.c v3_ocsp.c diff --git a/crypto/ocsp/ocsp_err.c b/crypto/ocsp/ocsp_err.c index 7cd36723..2efcb337 100644 --- a/crypto/ocsp/ocsp_err.c +++ b/crypto/ocsp/ocsp_err.c @@ -21,6 +21,7 @@ static const ERR_STRING_DATA OCSP_str_reasons[] = { "error in nextupdate field"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_ERROR_IN_THISUPDATE_FIELD), "error in thisupdate field"}, + {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_ERROR_PARSING_URL), "error parsing url"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_MISSING_OCSPSIGNING_USAGE), "missing ocspsigning usage"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE), @@ -40,6 +41,10 @@ static const ERR_STRING_DATA OCSP_str_reasons[] = { "response contains no revocation data"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_ROOT_CA_NOT_TRUSTED), "root ca not trusted"}, + {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_SERVER_RESPONSE_ERROR), + "server response error"}, + {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_SERVER_RESPONSE_PARSE_ERROR), + "server response parse error"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_SIGNATURE_FAILURE), "signature failure"}, {ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND), "signer certificate not found"}, diff --git a/crypto/ocsp/ocsp_ht.c b/crypto/ocsp/ocsp_ht.c new file mode 100644 index 00000000..fa147f3b --- /dev/null +++ b/crypto/ocsp/ocsp_ht.c @@ -0,0 +1,502 @@ +/* + * Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "e_os.h" +#include +#include +#include "crypto/ctype.h" +#include +#include +#include +#include +#include + +/* Stateful OCSP request code, supporting non-blocking I/O */ + +/* Opaque OCSP request status structure */ + +struct ocsp_req_ctx_st { + int state; /* Current I/O state */ + unsigned char *iobuf; /* Line buffer */ + int iobuflen; /* Line buffer length */ + BIO *io; /* BIO to perform I/O with */ + BIO *mem; /* Memory BIO response is built into */ + unsigned long asn1_len; /* ASN1 length of response */ + unsigned long max_resp_len; /* Maximum length of response */ +}; + +#define OCSP_MAX_RESP_LENGTH (100 * 1024) +#define OCSP_MAX_LINE_LEN 4096; + +/* OCSP states */ + +/* If set no reading should be performed */ +#define OHS_NOREAD 0x1000 +/* Error condition */ +#define OHS_ERROR (0 | OHS_NOREAD) +/* First line being read */ +#define OHS_FIRSTLINE 1 +/* MIME headers being read */ +#define OHS_HEADERS 2 +/* OCSP initial header (tag + length) being read */ +#define OHS_ASN1_HEADER 3 +/* OCSP content octets being read */ +#define OHS_ASN1_CONTENT 4 +/* First call: ready to start I/O */ +#define OHS_ASN1_WRITE_INIT (5 | OHS_NOREAD) +/* Request being sent */ +#define OHS_ASN1_WRITE (6 | OHS_NOREAD) +/* Request being flushed */ +#define OHS_ASN1_FLUSH (7 | OHS_NOREAD) +/* Completed */ +#define OHS_DONE (8 | OHS_NOREAD) +/* Headers set, no final \r\n included */ +#define OHS_HTTP_HEADER (9 | OHS_NOREAD) + +static int parse_http_line1(char *line); + +OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline) +{ + OCSP_REQ_CTX *rctx = OPENSSL_zalloc(sizeof(*rctx)); + + if (rctx == NULL) + return NULL; + rctx->state = OHS_ERROR; + rctx->max_resp_len = OCSP_MAX_RESP_LENGTH; + rctx->mem = BIO_new(BIO_s_mem()); + rctx->io = io; + if (maxline > 0) + rctx->iobuflen = maxline; + else + rctx->iobuflen = OCSP_MAX_LINE_LEN; + rctx->iobuf = OPENSSL_malloc(rctx->iobuflen); + if (rctx->iobuf == NULL || rctx->mem == NULL) { + OCSP_REQ_CTX_free(rctx); + return NULL; + } + return rctx; +} + +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx) +{ + if (!rctx) + return; + BIO_free(rctx->mem); + OPENSSL_free(rctx->iobuf); + OPENSSL_free(rctx); +} + +BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx) +{ + return rctx->mem; +} + +void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len) +{ + if (len == 0) + rctx->max_resp_len = OCSP_MAX_RESP_LENGTH; + else + rctx->max_resp_len = len; +} + +int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, ASN1_VALUE *val) +{ + static const char req_hdr[] = + "Content-Type: application/ocsp-request\r\n" + "Content-Length: %d\r\n\r\n"; + int reqlen = ASN1_item_i2d(val, NULL, it); + if (BIO_printf(rctx->mem, req_hdr, reqlen) <= 0) + return 0; + if (ASN1_item_i2d_bio(it, rctx->mem, val) <= 0) + return 0; + rctx->state = OHS_ASN1_WRITE_INIT; + return 1; +} + +int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, + ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + int rv, len; + const unsigned char *p; + + rv = OCSP_REQ_CTX_nbio(rctx); + if (rv != 1) + return rv; + + len = BIO_get_mem_data(rctx->mem, &p); + *pval = ASN1_item_d2i(NULL, &p, len, it); + if (*pval == NULL) { + rctx->state = OHS_ERROR; + return 0; + } + return 1; +} + +int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path) +{ + static const char http_hdr[] = "%s %s HTTP/1.0\r\n"; + + if (path == NULL) + path = "/"; + + if (BIO_printf(rctx->mem, http_hdr, op, path) <= 0) + return 0; + rctx->state = OHS_HTTP_HEADER; + return 1; +} + +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req) +{ + return OCSP_REQ_CTX_i2d(rctx, ASN1_ITEM_rptr(OCSP_REQUEST), + (ASN1_VALUE *)req); +} + +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value) +{ + if (!name) + return 0; + if (BIO_puts(rctx->mem, name) <= 0) + return 0; + if (value) { + if (BIO_write(rctx->mem, ": ", 2) != 2) + return 0; + if (BIO_puts(rctx->mem, value) <= 0) + return 0; + } + if (BIO_write(rctx->mem, "\r\n", 2) != 2) + return 0; + rctx->state = OHS_HTTP_HEADER; + return 1; +} + +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline) +{ + + OCSP_REQ_CTX *rctx = NULL; + rctx = OCSP_REQ_CTX_new(io, maxline); + if (rctx == NULL) + return NULL; + + if (!OCSP_REQ_CTX_http(rctx, "POST", path)) + goto err; + + if (req && !OCSP_REQ_CTX_set1_req(rctx, req)) + goto err; + + return rctx; + + err: + OCSP_REQ_CTX_free(rctx); + return NULL; +} + +/* + * Parse the HTTP response. This will look like this: "HTTP/1.0 200 OK". We + * need to obtain the numeric code and (optional) informational message. + */ + +static int parse_http_line1(char *line) +{ + int retcode; + char *p, *q, *r; + /* Skip to first white space (passed protocol info) */ + + for (p = line; *p && !ossl_isspace(*p); p++) + continue; + if (*p == '\0') { + OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); + return 0; + } + + /* Skip past white space to start of response code */ + while (*p && ossl_isspace(*p)) + p++; + + if (*p == '\0') { + OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); + return 0; + } + + /* Find end of response code: first whitespace after start of code */ + for (q = p; *q && !ossl_isspace(*q); q++) + continue; + + if (*q == '\0') { + OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); + return 0; + } + + /* Set end of response code and start of message */ + *q++ = 0; + + /* Attempt to parse numeric code */ + retcode = strtoul(p, &r, 10); + + if (*r) + return 0; + + /* Skip over any leading white space in message */ + while (*q && ossl_isspace(*q)) + q++; + + if (*q) { + /* + * Finally zap any trailing white space in message (include CRLF) + */ + + /* We know q has a non white space character so this is OK */ + for (r = q + strlen(q) - 1; ossl_isspace(*r); r--) + *r = 0; + } + if (retcode != 200) { + OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR); + if (*q == '\0') + ERR_add_error_data(2, "Code=", p); + else + ERR_add_error_data(4, "Code=", p, ",Reason=", q); + return 0; + } + + return 1; + +} + +int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx) +{ + int i, n; + const unsigned char *p; + next_io: + if (!(rctx->state & OHS_NOREAD)) { + n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen); + + if (n <= 0) { + if (BIO_should_retry(rctx->io)) + return -1; + return 0; + } + + /* Write data to memory BIO */ + + if (BIO_write(rctx->mem, rctx->iobuf, n) != n) + return 0; + } + + switch (rctx->state) { + case OHS_HTTP_HEADER: + /* Last operation was adding headers: need a final \r\n */ + if (BIO_write(rctx->mem, "\r\n", 2) != 2) { + rctx->state = OHS_ERROR; + return 0; + } + rctx->state = OHS_ASN1_WRITE_INIT; + + /* fall thru */ + case OHS_ASN1_WRITE_INIT: + rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL); + rctx->state = OHS_ASN1_WRITE; + + /* fall thru */ + case OHS_ASN1_WRITE: + n = BIO_get_mem_data(rctx->mem, &p); + + i = BIO_write(rctx->io, p + (n - rctx->asn1_len), rctx->asn1_len); + + if (i <= 0) { + if (BIO_should_retry(rctx->io)) + return -1; + rctx->state = OHS_ERROR; + return 0; + } + + rctx->asn1_len -= i; + + if (rctx->asn1_len > 0) + goto next_io; + + rctx->state = OHS_ASN1_FLUSH; + + (void)BIO_reset(rctx->mem); + + /* fall thru */ + case OHS_ASN1_FLUSH: + + i = BIO_flush(rctx->io); + + if (i > 0) { + rctx->state = OHS_FIRSTLINE; + goto next_io; + } + + if (BIO_should_retry(rctx->io)) + return -1; + + rctx->state = OHS_ERROR; + return 0; + + case OHS_ERROR: + return 0; + + case OHS_FIRSTLINE: + case OHS_HEADERS: + + /* Attempt to read a line in */ + + next_line: + /* + * Due to &%^*$" memory BIO behaviour with BIO_gets we have to check + * there's a complete line in there before calling BIO_gets or we'll + * just get a partial read. + */ + n = BIO_get_mem_data(rctx->mem, &p); + if ((n <= 0) || !memchr(p, '\n', n)) { + if (n >= rctx->iobuflen) { + rctx->state = OHS_ERROR; + return 0; + } + goto next_io; + } + n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen); + + if (n <= 0) { + if (BIO_should_retry(rctx->mem)) + goto next_io; + rctx->state = OHS_ERROR; + return 0; + } + + /* Don't allow excessive lines */ + if (n == rctx->iobuflen) { + rctx->state = OHS_ERROR; + return 0; + } + + /* First line */ + if (rctx->state == OHS_FIRSTLINE) { + if (parse_http_line1((char *)rctx->iobuf)) { + rctx->state = OHS_HEADERS; + goto next_line; + } else { + rctx->state = OHS_ERROR; + return 0; + } + } else { + /* Look for blank line: end of headers */ + for (p = rctx->iobuf; *p; p++) { + if ((*p != '\r') && (*p != '\n')) + break; + } + if (*p) + goto next_line; + + rctx->state = OHS_ASN1_HEADER; + + } + + /* Fall thru */ + + case OHS_ASN1_HEADER: + /* + * Now reading ASN1 header: can read at least 2 bytes which is enough + * for ASN1 SEQUENCE header and either length field or at least the + * length of the length field. + */ + n = BIO_get_mem_data(rctx->mem, &p); + if (n < 2) + goto next_io; + + /* Check it is an ASN1 SEQUENCE */ + if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) { + rctx->state = OHS_ERROR; + return 0; + } + + /* Check out length field */ + if (*p & 0x80) { + /* + * If MSB set on initial length octet we can now always read 6 + * octets: make sure we have them. + */ + if (n < 6) + goto next_io; + n = *p & 0x7F; + /* Not NDEF or excessive length */ + if (!n || (n > 4)) { + rctx->state = OHS_ERROR; + return 0; + } + p++; + rctx->asn1_len = 0; + for (i = 0; i < n; i++) { + rctx->asn1_len <<= 8; + rctx->asn1_len |= *p++; + } + + if (rctx->asn1_len > rctx->max_resp_len) { + rctx->state = OHS_ERROR; + return 0; + } + + rctx->asn1_len += n + 2; + } else + rctx->asn1_len = *p + 2; + + rctx->state = OHS_ASN1_CONTENT; + + /* Fall thru */ + + case OHS_ASN1_CONTENT: + n = BIO_get_mem_data(rctx->mem, NULL); + if (n < (int)rctx->asn1_len) + goto next_io; + + rctx->state = OHS_DONE; + return 1; + + case OHS_DONE: + return 1; + + } + + return 0; + +} + +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx) +{ + return OCSP_REQ_CTX_nbio_d2i(rctx, + (ASN1_VALUE **)presp, + ASN1_ITEM_rptr(OCSP_RESPONSE)); +} + +/* Blocking OCSP request handler: now a special case of non-blocking I/O */ + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req) +{ + OCSP_RESPONSE *resp = NULL; + OCSP_REQ_CTX *ctx; + int rv; + + ctx = OCSP_sendreq_new(b, path, req, -1); + + if (ctx == NULL) + return NULL; + + do { + rv = OCSP_sendreq_nbio(&resp, ctx); + } while ((rv == -1) && BIO_should_retry(b)); + + OCSP_REQ_CTX_free(ctx); + + if (rv) + return resp; + + return NULL; +} diff --git a/crypto/ocsp/ocsp_http.c b/crypto/ocsp/ocsp_http.c deleted file mode 100644 index cf4d69d8..00000000 --- a/crypto/ocsp/ocsp_http.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "../http/http_local.h" - -#ifndef OPENSSL_NO_OCSP - -int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, const OCSP_REQUEST *req) -{ - return OCSP_REQ_CTX_i2d(rctx, "application/ocsp-request", - ASN1_ITEM_rptr(OCSP_REQUEST), (ASN1_VALUE *)req); -} - -OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, - int maxline) -{ - BIO *req_mem = HTTP_asn1_item2bio(ASN1_ITEM_rptr(OCSP_REQUEST), - (ASN1_VALUE *)req); - OCSP_REQ_CTX *res = - HTTP_REQ_CTX_new(io, io, 0 /* no HTTP proxy used */, NULL, NULL, path, - NULL /* headers */, "application/ocsp-request", - req_mem /* may be NULL */, - maxline, 0 /* default max_resp_len */, - 0 /* no timeout, blocking indefinite */, NULL, - 1 /* expect_asn1 */); - BIO_free(req_mem); - return res; -} - -int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx) -{ - *presp = (OCSP_RESPONSE *) - OCSP_REQ_CTX_nbio_d2i(rctx, ASN1_ITEM_rptr(OCSP_RESPONSE)); - return *presp != NULL; -} - -OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req) -{ - OCSP_RESPONSE *resp = NULL; - OCSP_REQ_CTX *ctx; - int rv; - - ctx = OCSP_sendreq_new(b, path, req, -1 /* default max resp line length */); - if (ctx == NULL) - return NULL; - - rv = OCSP_sendreq_nbio(&resp, ctx); - - /* this indirectly calls ERR_clear_error(): */ - OCSP_REQ_CTX_free(ctx); - - return rv == 1 ? resp : NULL; -} -#endif /* !defined(OPENSSL_NO_OCSP) */ diff --git a/crypto/ocsp/ocsp_lib.c b/crypto/ocsp/ocsp_lib.c index 2701789c..75498561 100644 --- a/crypto/ocsp/ocsp_lib.c +++ b/crypto/ocsp/ocsp_lib.c @@ -109,4 +109,111 @@ int OCSP_id_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b) return ASN1_INTEGER_cmp(&a->serialNumber, &b->serialNumber); } +/* + * Parse a URL and split it up into host, port and path components and + * whether it is SSL. + */ + +int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, + int *pssl) +{ + char *p, *buf; + + char *host, *port; + + *phost = NULL; + *pport = NULL; + *ppath = NULL; + + /* dup the buffer since we are going to mess with it */ + buf = OPENSSL_strdup(url); + if (!buf) + goto mem_err; + + /* Check for initial colon */ + p = strchr(buf, ':'); + if (p == NULL) + goto parse_err; + + *(p++) = '\0'; + + if (strcmp(buf, "http") == 0) { + *pssl = 0; + port = "80"; + } else if (strcmp(buf, "https") == 0) { + *pssl = 1; + port = "443"; + } else + goto parse_err; + + /* Check for double slash */ + if ((p[0] != '/') || (p[1] != '/')) + goto parse_err; + + p += 2; + + host = p; + + /* Check for trailing part of path */ + p = strchr(p, '/'); + if (p == NULL) + *ppath = OPENSSL_strdup("/"); + else { + *ppath = OPENSSL_strdup(p); + /* Set start of path to 0 so hostname is valid */ + *p = '\0'; + } + + if (*ppath == NULL) + goto mem_err; + + p = host; + if (host[0] == '[') { + /* ipv6 literal */ + host++; + p = strchr(host, ']'); + if (p == NULL) + goto parse_err; + *p = '\0'; + p++; + } + + /* Look for optional ':' for port number */ + if ((p = strchr(p, ':'))) { + *p = 0; + port = p + 1; + } + + *pport = OPENSSL_strdup(port); + if (*pport == NULL) + goto mem_err; + + *phost = OPENSSL_strdup(host); + + if (*phost == NULL) + goto mem_err; + + OPENSSL_free(buf); + + return 1; + + mem_err: + OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE); + goto err; + + parse_err: + OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL); + + err: + OPENSSL_free(buf); + OPENSSL_free(*ppath); + *ppath = NULL; + OPENSSL_free(*pport); + *pport = NULL; + OPENSSL_free(*phost); + *phost = NULL; + return 0; + +} + IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID) diff --git a/crypto/params.c b/crypto/params.c index 06ae1bc4..9bccc517 100644 --- a/crypto/params.c +++ b/crypto/params.c @@ -788,8 +788,6 @@ static int get_string_internal(const OSSL_PARAM *p, void **val, size_t max_len, if (used_len != NULL) *used_len = sz; - if (sz == 0) - return 1; if (p->data == NULL) return 0; @@ -797,12 +795,13 @@ static int get_string_internal(const OSSL_PARAM *p, void **val, size_t max_len, return 1; if (*val == NULL) { - char *const q = OPENSSL_malloc(sz); + char *const q = OPENSSL_malloc(sz > 0 ? sz : 1); if (q == NULL) return 0; *val = q; - memcpy(q, p->data, sz); + if (sz != 0) + memcpy(q, p->data, sz); return 1; } if (max_len < sz) diff --git a/crypto/pem/pem_pk8.c b/crypto/pem/pem_pk8.c index 6b784050..8dbcb65b 100644 --- a/crypto/pem/pem_pk8.c +++ b/crypto/pem/pem_pk8.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,6 +15,7 @@ #include #include #include +#include static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, @@ -66,49 +67,95 @@ static int do_pk8pkey(BIO *bp, const EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc, const char *kstr, int klen, pem_password_cb *cb, void *u) { - X509_SIG *p8; - PKCS8_PRIV_KEY_INFO *p8inf; - char buf[PEM_BUFSIZE]; - int ret; + int ret = 0; + const char *pq = isder + ? OSSL_SERIALIZER_PrivateKey_TO_DER_PQ + : OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ; + OSSL_SERIALIZER_CTX *ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(x, pq); - if ((p8inf = EVP_PKEY2PKCS8(x)) == NULL) { - PEMerr(PEM_F_DO_PK8PKEY, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + if (ctx == NULL) return 0; - } - if (enc || (nid != -1)) { - if (!kstr) { - if (!cb) - klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); - else - klen = cb(buf, PEM_BUFSIZE, 1, u); - if (klen <= 0) { - PEMerr(PEM_F_DO_PK8PKEY, PEM_R_READ_KEY); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return 0; - } - kstr = buf; + /* + * If no keystring or callback is set, OpenSSL traditionally uses the + * user's cb argument as a password string, or if that's NULL, it falls + * back on PEM_def_callback(). + */ + if (kstr == NULL && cb == NULL) { + if (u != NULL) { + kstr = u; + klen = strlen(u); + } else { + cb = PEM_def_callback; } - p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); - if (kstr == buf) - OPENSSL_cleanse(buf, klen); - PKCS8_PRIV_KEY_INFO_free(p8inf); - if (p8 == NULL) - return 0; - if (isder) - ret = i2d_PKCS8_bio(bp, p8); - else - ret = PEM_write_bio_PKCS8(bp, p8); - X509_SIG_free(p8); - return ret; - } else { - if (isder) - ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); - else - ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return ret; } + + if (OSSL_SERIALIZER_CTX_get_serializer(ctx) != NULL) { + ret = 1; + if (enc != NULL) { + ret = 0; + if (OSSL_SERIALIZER_CTX_set_cipher(ctx, EVP_CIPHER_name(enc), + NULL)) { + const unsigned char *ukstr = (const unsigned char *)kstr; + + /* + * Try to pass the passphrase if one was given, or the + * passphrase callback if one was given. If none of them + * are given and that's wrong, we rely on the _to_bio() + * call to generate errors. + */ + ret = 1; + if (kstr != NULL + && !OSSL_SERIALIZER_CTX_set_passphrase(ctx, ukstr, klen)) + ret = 0; + else if (cb != NULL + && !OSSL_SERIALIZER_CTX_set_passphrase_cb(ctx, 1, + cb, u)) + ret = 0; + } + } + ret = ret && OSSL_SERIALIZER_to_bio(ctx, bp); + } else { + X509_SIG *p8; + PKCS8_PRIV_KEY_INFO *p8inf; + char buf[PEM_BUFSIZE]; + + ret = 0; + if ((p8inf = EVP_PKEY2PKCS8(x)) == NULL) { + PEMerr(PEM_F_DO_PK8PKEY, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + goto legacy_end; + } + if (enc || (nid != -1)) { + if (kstr == NULL) { + klen = cb(buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + PEMerr(PEM_F_DO_PK8PKEY, PEM_R_READ_KEY); + goto legacy_end; + } + + kstr = buf; + } + p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); + if (kstr == buf) + OPENSSL_cleanse(buf, klen); + if (p8 == NULL) + goto legacy_end; + if (isder) + ret = i2d_PKCS8_bio(bp, p8); + else + ret = PEM_write_bio_PKCS8(bp, p8); + X509_SIG_free(p8); + } else { + if (isder) + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + else + ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); + } + legacy_end: + PKCS8_PRIV_KEY_INFO_free(p8inf); + } + OSSL_SERIALIZER_CTX_free(ctx); + return ret; } EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c index e2f57028..6d85a8a4 100644 --- a/crypto/pem/pvkfmt.c +++ b/crypto/pem/pvkfmt.c @@ -36,10 +36,10 @@ static unsigned int read_ledword(const unsigned char **in) { const unsigned char *p = *in; unsigned int ret; - ret = *p++; - ret |= (*p++ << 8); - ret |= (*p++ << 16); - ret |= (*p++ << 24); + ret = (unsigned int)*p++; + ret |= (unsigned int)*p++ << 8; + ret |= (unsigned int)*p++ << 16; + ret |= (unsigned int)*p++ << 24; *in = p; return ret; } diff --git a/crypto/provider.c b/crypto/provider.c index fe46d318..02002a5f 100644 --- a/crypto/provider.c +++ b/crypto/provider.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -57,6 +57,19 @@ int OSSL_PROVIDER_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]) return ossl_provider_get_params(prov, params); } + +const OSSL_ALGORITHM *OSSL_PROVIDER_query_operation(const OSSL_PROVIDER *prov, + int operation_id, + int *no_cache) +{ + return ossl_provider_query_operation(prov, operation_id, no_cache); +} + +void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov) +{ + return ossl_provider_prov_ctx(prov); +} + int OSSL_PROVIDER_add_builtin(OPENSSL_CTX *libctx, const char *name, OSSL_provider_init_fn *init_fn) { @@ -85,3 +98,11 @@ const char *OSSL_PROVIDER_name(const OSSL_PROVIDER *prov) { return ossl_provider_name(prov); } + +int OSSL_PROVIDER_do_all(OPENSSL_CTX *ctx, + int (*cb)(OSSL_PROVIDER *provider, + void *cbdata), + void *cbdata) +{ + return ossl_provider_forall_loaded(ctx, cb, cbdata); +} diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 662576cd..f7af51a2 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -42,7 +42,8 @@ struct provider_store_st; /* Forward declaration */ struct ossl_provider_st { /* Flag bits */ unsigned int flag_initialized:1; - unsigned int flag_fallback:1; + unsigned int flag_fallback:1; /* Can be used as fallback */ + unsigned int flag_activated_as_fallback:1; /* OpenSSL library side data */ CRYPTO_REF_COUNT refcnt; @@ -71,6 +72,13 @@ struct ossl_provider_st { OSSL_provider_get_params_fn *get_params; OSSL_provider_query_operation_fn *query_operation; + /* + * Cache of bit to indicate of query_operation() has been called on + * a specific operation or not. + */ + unsigned char *operation_bits; + size_t operation_bits_sz; + /* Provider side data */ void *provctx; }; @@ -97,6 +105,24 @@ struct provider_store_st { unsigned int use_fallbacks:1; }; +/* + * provider_deactivate_free() is a wrapper around ossl_provider_free() + * that also makes sure that activated fallback providers are deactivated. + * This is simply done by freeing them an extra time, to compensate for the + * refcount that provider_activate_fallbacks() gives them. + * Since this is only called when the provider store is being emptied, we + * don't need to care about any lock. + */ +static void provider_deactivate_free(OSSL_PROVIDER *prov) +{ + int extra_free = (prov->flag_initialized + && prov->flag_activated_as_fallback); + + if (extra_free) + ossl_provider_free(prov); + ossl_provider_free(prov); +} + static void provider_store_free(void *vstore) { struct provider_store_st *store = vstore; @@ -104,7 +130,7 @@ static void provider_store_free(void *vstore) if (store == NULL) return; OPENSSL_free(store->default_path); - sk_OSSL_PROVIDER_pop_free(store->providers, ossl_provider_free); + sk_OSSL_PROVIDER_pop_free(store->providers, provider_deactivate_free); CRYPTO_THREAD_lock_free(store->lock); OPENSSL_free(store); } @@ -317,6 +343,9 @@ void ossl_provider_free(OSSL_PROVIDER *prov) } # endif #endif + OPENSSL_free(prov->operation_bits); + prov->operation_bits = NULL; + prov->operation_bits_sz = 0; prov->flag_initialized = 0; } @@ -644,13 +673,22 @@ static void provider_activate_fallbacks(struct provider_store_st *store) OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(store->providers, i); /* - * Note that we don't care if the activation succeeds or not. - * If it doesn't succeed, then any attempt to use any of the - * fallback providers will fail anyway. + * Activated fallback providers get an extra refcount, to + * simulate a regular load. + * Note that we don't care if the activation succeeds or not, + * other than to maintain a correct refcount. If the activation + * doesn't succeed, then any future attempt to use the fallback + * provider will fail anyway. */ if (prov->flag_fallback) { - activated_fallback_count++; - provider_activate(prov); + if (ossl_provider_up_ref(prov)) { + if (!provider_activate(prov)) { + ossl_provider_free(prov); + } else { + prov->flag_activated_as_fallback = 1; + activated_fallback_count++; + } + } } } @@ -749,6 +787,14 @@ const char *ossl_provider_module_path(const OSSL_PROVIDER *prov) #endif } +void *ossl_provider_prov_ctx(const OSSL_PROVIDER *prov) +{ + if (prov != NULL) + return prov->provctx; + + return NULL; +} + OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov) { /* TODO(3.0) just: return prov->libctx; */ @@ -782,6 +828,42 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, return prov->query_operation(prov->provctx, operation_id, no_cache); } +int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum) +{ + size_t byte = bitnum / 8; + unsigned char bit = (1 << (bitnum % 8)) & 0xFF; + + if (provider->operation_bits_sz <= byte) { + provider->operation_bits = OPENSSL_realloc(provider->operation_bits, + byte + 1); + if (provider->operation_bits == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + memset(provider->operation_bits + provider->operation_bits_sz, + '\0', byte + 1 - provider->operation_bits_sz); + } + provider->operation_bits[byte] |= bit; + return 1; +} + +int ossl_provider_test_operation_bit(OSSL_PROVIDER *provider, size_t bitnum, + int *result) +{ + size_t byte = bitnum / 8; + unsigned char bit = (1 << (bitnum % 8)) & 0xFF; + + if (!ossl_assert(result != NULL)) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + *result = 0; + if (provider->operation_bits_sz > byte) + *result = ((provider->operation_bits[byte] & bit) != 0); + return 1; +} + /*- * Core functions for the provider * =============================== @@ -795,8 +877,13 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, * never knows. */ static const OSSL_PARAM param_types[] = { - OSSL_PARAM_DEFN("openssl-version", OSSL_PARAM_UTF8_PTR, NULL, 0), - OSSL_PARAM_DEFN("provider-name", OSSL_PARAM_UTF8_PTR, NULL, 0), + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_CORE_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0), + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_CORE_PROV_NAME, OSSL_PARAM_UTF8_PTR, + NULL, 0), +#ifndef FIPS_MODULE + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_CORE_MODULE_FILENAME, OSSL_PARAM_UTF8_PTR, + NULL, 0), +#endif OSSL_PARAM_END }; @@ -833,13 +920,14 @@ static int core_get_params(const OSSL_CORE_HANDLE *handle, OSSL_PARAM params[]) */ OSSL_PROVIDER *prov = (OSSL_PROVIDER *)handle; - if ((p = OSSL_PARAM_locate(params, "openssl-version")) != NULL) + if ((p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_CORE_VERSION)) != NULL) OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR); - if ((p = OSSL_PARAM_locate(params, "provider-name")) != NULL) + if ((p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_CORE_PROV_NAME)) != NULL) OSSL_PARAM_set_utf8_ptr(p, prov->name); #ifndef FIPS_MODULE - if ((p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_MODULE_FILENAME)) != NULL) + if ((p = OSSL_PARAM_locate(params, + OSSL_PROV_PARAM_CORE_MODULE_FILENAME)) != NULL) OSSL_PARAM_set_utf8_ptr(p, ossl_provider_module_path(prov)); #endif diff --git a/crypto/rand/drbg_ctr.c b/crypto/rand/drbg_ctr.c index 050ae496..33e1b324 100644 --- a/crypto/rand/drbg_ctr.c +++ b/crypto/rand/drbg_ctr.c @@ -366,9 +366,11 @@ __owur static int drbg_ctr_generate(RAND_DRBG *drbg, ctr32 = GETU32(ctr->V + 12) + blocks; if (ctr32 < blocks) { /* 32-bit counter overflow into V. */ - blocks -= ctr32; - buflen = blocks * 16; - ctr32 = 0; + if (ctr32 != 0) { + blocks -= ctr32; + buflen = blocks * 16; + ctr32 = 0; + } ctr96_inc(ctr->V); } PUTU32(ctr->V + 12, ctr32); diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c index 081ffca9..869c2d04 100644 --- a/crypto/rand/rand_unix.c +++ b/crypto/rand/rand_unix.c @@ -391,7 +391,8 @@ static struct random_device { } random_devices[OSSL_NELEM(random_device_paths)]; static int keep_random_devices_open = 1; -# if defined(__linux) && defined(DEVRANDOM_WAIT) +# if defined(__linux) && defined(DEVRANDOM_WAIT) \ + && defined(OPENSSL_RAND_SEED_GETRANDOM) static void *shm_addr; # if !defined(FIPS_MODULE) @@ -474,7 +475,7 @@ static int wait_random_seeded(void) } return seeded; } -# else /* defined __linux */ +# else /* defined __linux && DEVRANDOM_WAIT && OPENSSL_RAND_SEED_GETRANDOM */ static int wait_random_seeded(void) { return 1; diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 2e52c906..b38d29da 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -95,7 +95,7 @@ static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) return 0; } -static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +static int rsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) { const unsigned char *p; int pklen; @@ -1001,7 +1001,8 @@ static int rsa_cms_decrypt(CMS_RecipientInfo *ri) goto err; if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) goto err; - if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) + if (label != NULL + && EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) goto err; /* Carry on */ rv = 1; diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c index d8da0873..78200280 100644 --- a/crypto/rsa/rsa_gen.c +++ b/crypto/rsa/rsa_gen.c @@ -64,16 +64,10 @@ int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, return rsa_keygen(NULL, rsa, bits, primes, e_value, cb, 0); } -static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes, - BIGNUM *e_value, BN_GENCB *cb, int pairwise_test) +#ifndef FIPS_MODULE +static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes, + BIGNUM *e_value, BN_GENCB *cb) { - int ok = -1; -#ifdef FIPS_MODULE - if (primes != 2) - return 0; - ok = rsa_sp800_56b_generate_key(rsa, bits, e_value, cb); - pairwise_test = 1; /* FIPS MODE needs to always run the pairwise test */ -#else BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *tmp, *prime; int n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0; int i = 0, quo = 0, rmd = 0, adj = 0, retries = 0; @@ -82,6 +76,7 @@ static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes, BN_CTX *ctx = NULL; BN_ULONG bitst = 0; unsigned long error = 0; + int ok = -1; if (bits < RSA_MIN_MODULUS_BITS) { ok = 0; /* we set our own err */ @@ -89,6 +84,12 @@ static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes, goto err; } + /* A bad value for e can cause infinite loops */ + if (e_value != NULL && !rsa_check_public_exponent(e_value)) { + RSAerr(0, RSA_R_PUB_EXPONENT_OUT_OF_RANGE); + return 0; + } + if (primes < RSA_DEFAULT_PRIME_NUM || primes > rsa_multip_cap(bits)) { ok = 0; /* we set our own err */ RSAerr(0, RSA_R_KEY_PRIME_NUM_INVALID); @@ -401,8 +402,29 @@ static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes, } BN_CTX_end(ctx); BN_CTX_free(ctx); + return ok; +} #endif /* FIPS_MODULE */ +static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes, + BIGNUM *e_value, BN_GENCB *cb, int pairwise_test) +{ + int ok = 0; + + /* + * Only multi-prime keys or insecure keys with a small key length will use + * the older rsa_multiprime_keygen(). + */ + if (primes == 2 && bits >= 2048) + ok = rsa_sp800_56b_generate_key(rsa, bits, e_value, cb); +#ifndef FIPS_MODULE + else + ok = rsa_multiprime_keygen(rsa, bits, primes, e_value, cb); +#endif /* FIPS_MODULE */ + +#ifdef FIPS_MODULE + pairwise_test = 1; /* FIPS MODE needs to always run the pairwise test */ +#endif if (pairwise_test && ok > 0) { OSSL_CALLBACK *stcb = NULL; void *stcbarg = NULL; diff --git a/crypto/rsa/rsa_local.h b/crypto/rsa/rsa_local.h index f94fc79c..65fd6022 100644 --- a/crypto/rsa/rsa_local.h +++ b/crypto/rsa/rsa_local.h @@ -187,12 +187,5 @@ int rsa_padding_add_PKCS1_type_2_with_libctx(OPENSSL_CTX *libctx, unsigned char *to, int tlen, const unsigned char *from, int flen); -int rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(OPENSSL_CTX *libctx, - unsigned char *to, int tlen, - const unsigned char *from, - int flen, - const unsigned char *param, - int plen, const EVP_MD *md, - const EVP_MD *mgf1md); #endif /* OSSL_CRYPTO_RSA_LOCAL_H */ diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c index cc673367..f7dca5d1 100644 --- a/crypto/rsa/rsa_oaep.c +++ b/crypto/rsa/rsa_oaep.c @@ -61,13 +61,14 @@ int rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(OPENSSL_CTX *libctx, unsigned char seedmask[EVP_MAX_MD_SIZE]; int mdlen, dbmask_len = 0; + if (md == NULL) { #ifndef FIPS_MODULE - if (md == NULL) md = EVP_sha1(); #else RSAerr(0, ERR_R_PASSED_NULL_PARAMETER); return 0; #endif + } if (mgf1md == NULL) mgf1md = md; diff --git a/crypto/rsa/rsa_sp800_56b_check.c b/crypto/rsa/rsa_sp800_56b_check.c index 7cf6241d..df9b7bf0 100644 --- a/crypto/rsa/rsa_sp800_56b_check.c +++ b/crypto/rsa/rsa_sp800_56b_check.c @@ -189,12 +189,30 @@ int rsa_check_private_exponent(const RSA *rsa, int nbits, BN_CTX *ctx) return ret; } +#ifndef FIPS_MODULE +static int bn_is_three(const BIGNUM *bn) +{ + BIGNUM *num = BN_dup(bn); + int ret = (num != NULL && BN_sub_word(num, 3) && BN_is_zero(num)); + + BN_free(num); + return ret; +} +#endif /* FIPS_MODULE */ + /* Check exponent is odd, and has a bitlen ranging from [17..256] */ int rsa_check_public_exponent(const BIGNUM *e) { - int bitlen = BN_num_bits(e); + int bitlen; - return (BN_is_odd(e) && bitlen > 16 && bitlen < 257); + /* For legacy purposes RSA_3 is allowed in non fips mode */ +#ifndef FIPS_MODULE + if (bn_is_three(e)) + return 1; +#endif /* FIPS_MODULE */ + + bitlen = BN_num_bits(e); + return (BN_is_odd(e) && bitlen > 16 && bitlen < 257); } /* diff --git a/crypto/rsa/rsa_sp800_56b_gen.c b/crypto/rsa/rsa_sp800_56b_gen.c index c4c7c08e..d1673d5c 100644 --- a/crypto/rsa/rsa_sp800_56b_gen.c +++ b/crypto/rsa/rsa_sp800_56b_gen.c @@ -65,7 +65,7 @@ int rsa_fips186_4_gen_prob_primes(RSA *rsa, BIGNUM *p1, BIGNUM *p2, * Signature Generation and Key Agree/Transport. */ if (nbits < RSA_FIPS1864_MIN_KEYGEN_KEYSIZE) { - RSAerr(RSA_F_RSA_FIPS186_4_GEN_PROB_PRIMES, RSA_R_INVALID_KEY_LENGTH); + RSAerr(RSA_F_RSA_FIPS186_4_GEN_PROB_PRIMES, RSA_R_KEY_SIZE_TOO_SMALL); return 0; } @@ -146,12 +146,13 @@ err: int rsa_sp800_56b_validate_strength(int nbits, int strength) { int s = (int)ifc_ffc_compute_security_bits(nbits); - +#ifdef FIPS_MODULE if (s < RSA_FIPS1864_MIN_KEYGEN_STRENGTH || s > RSA_FIPS1864_MAX_KEYGEN_STRENGTH) { RSAerr(RSA_F_RSA_SP800_56B_VALIDATE_STRENGTH, RSA_R_INVALID_MODULUS); return 0; } +#endif if (strength != -1 && s != strength) { RSAerr(RSA_F_RSA_SP800_56B_VALIDATE_STRENGTH, RSA_R_INVALID_STRENGTH); return 0; diff --git a/crypto/serializer/serializer_meth.c b/crypto/serializer/serializer_meth.c index a098ffb0..e3e77c54 100644 --- a/crypto/serializer/serializer_meth.c +++ b/crypto/serializer/serializer_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -417,8 +417,13 @@ void OSSL_SERIALIZER_do_all_provided(OPENSSL_CTX *libctx, data.user_fn = (void (*)(void *, void *))fn; data.user_arg = arg; - ossl_algorithm_do_all(libctx, OSSL_OP_SERIALIZER, NULL, - serializer_do_one, &data); + + /* + * No pre- or post-condition for this call, as this only creates methods + * temporarly and then promptly destroys them. + */ + ossl_algorithm_do_all(libctx, OSSL_OP_SERIALIZER, NULL, NULL, + serializer_do_one, NULL, &data); } void OSSL_SERIALIZER_names_do_all(const OSSL_SERIALIZER *ser, diff --git a/crypto/store/loader_file.c b/crypto/store/loader_file.c index 320c527a..ed74e558 100644 --- a/crypto/store/loader_file.c +++ b/crypto/store/loader_file.c @@ -36,7 +36,7 @@ DEFINE_STACK_OF(X509) #ifdef _WIN32 -# define stat _stat +# define stat _stat #endif #ifndef S_ISDIR @@ -219,7 +219,6 @@ static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name, if (ctx == NULL) { /* Initial parsing */ PKCS12 *p12; - int ok = 0; if (pem_name != NULL) /* No match, there is no PEM PKCS12 tag */ @@ -256,37 +255,46 @@ static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name, OSSL_STORE_INFO *osi_pkey = NULL; OSSL_STORE_INFO *osi_cert = NULL; OSSL_STORE_INFO *osi_ca = NULL; + int ok = 1; - if ((ctx = sk_OSSL_STORE_INFO_new_null()) != NULL - && (osi_pkey = OSSL_STORE_INFO_new_PKEY(pkey)) != NULL - && sk_OSSL_STORE_INFO_push(ctx, osi_pkey) != 0 - && (osi_cert = OSSL_STORE_INFO_new_CERT(cert)) != NULL - && sk_OSSL_STORE_INFO_push(ctx, osi_cert) != 0) { - ok = 1; - osi_pkey = NULL; - osi_cert = NULL; - - while(sk_X509_num(chain) > 0) { + if ((ctx = sk_OSSL_STORE_INFO_new_null()) != NULL) { + if (pkey != NULL) { + if ((osi_pkey = OSSL_STORE_INFO_new_PKEY(pkey)) != NULL + /* clearing pkey here avoids case distinctions */ + && (pkey = NULL) == NULL + && sk_OSSL_STORE_INFO_push(ctx, osi_pkey) != 0) + osi_pkey = NULL; + else + ok = 0; + } + if (ok && cert != NULL) { + if ((osi_cert = OSSL_STORE_INFO_new_CERT(cert)) != NULL + /* clearing cert here avoids case distinctions */ + && (cert = NULL) == NULL + && sk_OSSL_STORE_INFO_push(ctx, osi_cert) != 0) + osi_cert = NULL; + else + ok = 0; + } + while (ok && sk_X509_num(chain) > 0) { X509 *ca = sk_X509_value(chain, 0); - if ((osi_ca = OSSL_STORE_INFO_new_CERT(ca)) == NULL - || sk_OSSL_STORE_INFO_push(ctx, osi_ca) == 0) { + if ((osi_ca = OSSL_STORE_INFO_new_CERT(ca)) != NULL + && sk_X509_shift(chain) != NULL + && sk_OSSL_STORE_INFO_push(ctx, osi_ca) != 0) + osi_ca = NULL; + else ok = 0; - break; - } - osi_ca = NULL; - (void)sk_X509_shift(chain); } } - sk_X509_free(chain); + EVP_PKEY_free(pkey); + X509_free(cert); + sk_X509_pop_free(chain, X509_free); + OSSL_STORE_INFO_free(osi_pkey); + OSSL_STORE_INFO_free(osi_cert); + OSSL_STORE_INFO_free(osi_ca); if (!ok) { - OSSL_STORE_INFO_free(osi_ca); - OSSL_STORE_INFO_free(osi_cert); - OSSL_STORE_INFO_free(osi_pkey); sk_OSSL_STORE_INFO_pop_free(ctx, OSSL_STORE_INFO_free); - EVP_PKEY_free(pkey); - X509_free(cert); - sk_X509_pop_free(chain, X509_free); ctx = NULL; } *pctx = ctx; @@ -294,15 +302,12 @@ static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name, } p12_end: PKCS12_free(p12); - if (!ok) + if (ctx == NULL) return NULL; } - if (ctx != NULL) { - *matchcount = 1; - store_info = sk_OSSL_STORE_INFO_shift(ctx); - } - + *matchcount = 1; + store_info = sk_OSSL_STORE_INFO_shift(ctx); return store_info; } @@ -326,7 +331,7 @@ static FILE_HANDLER PKCS12_handler = { try_decode_PKCS12, eof_PKCS12, destroy_ctx_PKCS12, - 1 /* repeatable */ + 1 /* repeatable */ }; /* @@ -450,6 +455,43 @@ static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name, } } else { int i; +#ifndef OPENSSL_NO_ENGINE + ENGINE *curengine = ENGINE_get_first(); + + while (curengine != NULL) { + ENGINE_PKEY_ASN1_METHS_PTR asn1meths = + ENGINE_get_pkey_asn1_meths(curengine); + + if (asn1meths != NULL) { + const int *nids = NULL; + int nids_n = asn1meths(curengine, NULL, &nids, 0); + + for (i = 0; i < nids_n; i++) { + EVP_PKEY_ASN1_METHOD *ameth2 = NULL; + EVP_PKEY *tmp_pkey = NULL; + const unsigned char *tmp_blob = blob; + + if (!asn1meths(curengine, &ameth2, NULL, nids[i])) + continue; + if (ameth2 == NULL + || ameth2->pkey_flags & ASN1_PKEY_ALIAS) + continue; + + tmp_pkey = + d2i_PrivateKey_ex(ameth2->pkey_id, NULL, + &tmp_blob, len, libctx, propq); + if (tmp_pkey != NULL) { + if (pkey != NULL) + EVP_PKEY_free(tmp_pkey); + else + pkey = tmp_pkey; + (*matchcount)++; + } + } + } + curengine = ENGINE_get_next(curengine); + } +#endif for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { EVP_PKEY *tmp_pkey = NULL; @@ -735,7 +777,7 @@ struct ossl_store_loader_ctx_st { #define FILE_FLAG_ATTACHED (1<<1) unsigned int flags; union { - struct { /* Used with is_raw and is_pem */ + struct { /* Used with is_raw and is_pem */ BIO *file; /* @@ -745,7 +787,7 @@ struct ossl_store_loader_ctx_st { const FILE_HANDLER *last_handler; void *last_handler_ctx; } file; - struct { /* Used with is_dir */ + struct { /* Used with is_dir */ OPENSSL_DIR_CTX *ctx; int end_reached; @@ -1279,10 +1321,10 @@ static int ends_with_dirsep(const char *uri) { if (*uri != '\0') uri += strlen(uri) - 1; -#if defined __VMS +#if defined(__VMS) if (*uri == ']' || *uri == '>' || *uri == ':') return 1; -#elif defined _WIN32 +#elif defined(_WIN32) if (*uri == '\\') return 1; #endif @@ -1357,7 +1399,7 @@ static int file_name_check(OSSL_STORE_LOADER_CTX *ctx, const char *name) while (ossl_isdigit(*p)) p++; -# ifdef __VMS +#ifdef __VMS /* * One extra step here, check for a possible generation number. */ @@ -1365,7 +1407,7 @@ static int file_name_check(OSSL_STORE_LOADER_CTX *ctx, const char *name) for (p++; *p != '\0'; p++) if (!ossl_isdigit(*p)) break; -# endif +#endif /* * If we've reached the end of the string at this point, we've successfully diff --git a/crypto/ts/ts_rsp_verify.c b/crypto/ts/ts_rsp_verify.c index b872f75b..c909b211 100644 --- a/crypto/ts/ts_rsp_verify.c +++ b/crypto/ts/ts_rsp_verify.c @@ -26,8 +26,7 @@ static int ts_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, X509 *signer, STACK_OF(X509) **chain); static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si, STACK_OF(X509) *chain); -static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); -static int ts_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert); + static int int_ts_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token, TS_TST_INFO *tst_info); static int ts_check_status_info(TS_RESP *response); @@ -44,7 +43,6 @@ static int ts_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info); static int ts_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer); static int ts_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name); -static int ts_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert); /* * This must be large enough to hold all values in ts_status_text (with @@ -218,7 +216,7 @@ static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si, if (ss != NULL) { cert_ids = ss->cert_ids; cert = sk_X509_value(chain, 0); - if (ts_find_cert(cert_ids, cert) != 0) + if (ess_find_cert(cert_ids, cert) != 0) goto err; /* @@ -228,14 +226,14 @@ static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si, if (sk_ESS_CERT_ID_num(cert_ids) > 1) { for (i = 1; i < sk_X509_num(chain); ++i) { cert = sk_X509_value(chain, i); - if (ts_find_cert(cert_ids, cert) < 0) + if (ess_find_cert(cert_ids, cert) < 0) goto err; } } } else if (ssv2 != NULL) { cert_ids_v2 = ssv2->cert_ids; cert = sk_X509_value(chain, 0); - if (ts_find_cert_v2(cert_ids_v2, cert) != 0) + if (ess_find_cert_v2(cert_ids_v2, cert) != 0) goto err; /* @@ -245,7 +243,7 @@ static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si, if (sk_ESS_CERT_ID_V2_num(cert_ids_v2) > 1) { for (i = 1; i < sk_X509_num(chain); ++i) { cert = sk_X509_value(chain, i); - if (ts_find_cert_v2(cert_ids_v2, cert) < 0) + if (ess_find_cert_v2(cert_ids_v2, cert) < 0) goto err; } } @@ -263,87 +261,6 @@ static int ts_check_signing_certs(PKCS7_SIGNER_INFO *si, return ret; } -/* Returns < 0 if certificate is not found, certificate index otherwise. */ -static int ts_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) -{ - int i; - unsigned char cert_sha1[SHA_DIGEST_LENGTH]; - - if (!cert_ids || !cert) - return -1; - - /* Recompute SHA1 hash of certificate if necessary (side effect). */ - X509_check_purpose(cert, -1, 0); - - if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL)) - return -1; - - /* Look for cert in the cert_ids vector. */ - for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) { - ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); - - if (cid->hash->length == SHA_DIGEST_LENGTH - && memcmp(cid->hash->data, cert_sha1, SHA_DIGEST_LENGTH) == 0) { - ESS_ISSUER_SERIAL *is = cid->issuer_serial; - if (!is || !ts_issuer_serial_cmp(is, cert)) - return i; - } - } - - return -1; -} - -/* Returns < 0 if certificate is not found, certificate index otherwise. */ -static int ts_find_cert_v2(STACK_OF(ESS_CERT_ID_V2) *cert_ids, X509 *cert) -{ - int i; - unsigned char cert_digest[EVP_MAX_MD_SIZE]; - unsigned int len; - - /* Look for cert in the cert_ids vector. */ - for (i = 0; i < sk_ESS_CERT_ID_V2_num(cert_ids); ++i) { - ESS_CERT_ID_V2 *cid = sk_ESS_CERT_ID_V2_value(cert_ids, i); - const EVP_MD *md; - - if (cid->hash_alg != NULL) - md = EVP_get_digestbyobj(cid->hash_alg->algorithm); - else - md = EVP_sha256(); - - if (!X509_digest(cert, md, cert_digest, &len)) - return -1; - if (cid->hash->length != (int)len) - return -1; - - if (memcmp(cid->hash->data, cert_digest, cid->hash->length) == 0) { - ESS_ISSUER_SERIAL *is = cid->issuer_serial; - - if (is == NULL || !ts_issuer_serial_cmp(is, cert)) - return i; - } - } - - return -1; -} - -static int ts_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509 *cert) -{ - GENERAL_NAME *issuer; - - if (!is || !cert || sk_GENERAL_NAME_num(is->issuer) != 1) - return -1; - - issuer = sk_GENERAL_NAME_value(is->issuer, 0); - if (issuer->type != GEN_DIRNAME - || X509_NAME_cmp(issuer->d.dirn, X509_get_issuer_name(cert))) - return -1; - - if (ASN1_INTEGER_cmp(is->serial, X509_get_serialNumber(cert))) - return -1; - - return 0; -} - /*- * Verifies whether 'response' contains a valid response with regards * to the settings of the context: diff --git a/crypto/ui/ui_openssl.c b/crypto/ui/ui_openssl.c index cf873431..78b88c07 100644 --- a/crypto/ui/ui_openssl.c +++ b/crypto/ui/ui_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -435,6 +435,16 @@ static int open_console(UI *ui) is_a_tty = 0; else # endif +# ifdef EPERM + /* + * Linux can return EPERM (Operation not permitted), + * e.g. if a daemon executes openssl via fork()+execve() + * This should be ok + */ + if (errno == EPERM) + is_a_tty = 0; + else +# endif # ifdef ENODEV /* * MacOS X returns ENODEV (Operation not supported by device), diff --git a/crypto/ui/ui_util.c b/crypto/ui/ui_util.c index f64780a6..58769d68 100644 --- a/crypto/ui/ui_util.c +++ b/crypto/ui/ui_util.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -71,9 +71,8 @@ static void ui_new_method_data(void *parent, void *ptr, CRYPTO_EX_DATA *ad, } static int ui_dup_method_data(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, - void *from_d, int idx, long argl, void *argp) + void **pptr, int idx, long argl, void *argp) { - void **pptr = (void **)from_d; if (*pptr != NULL) *pptr = OPENSSL_memdup(*pptr, sizeof(struct pem_password_cb_data)); return 1; diff --git a/crypto/whrlpool/wp_block.c b/crypto/whrlpool/wp_block.c index eb6a69ce..e5aa1a03 100644 --- a/crypto/whrlpool/wp_block.c +++ b/crypto/whrlpool/wp_block.c @@ -70,6 +70,20 @@ typedef unsigned long long u64; # undef STRICT_ALIGNMENT #endif +#ifndef STRICT_ALIGNMENT +# ifdef __GNUC__ +typedef u64 u64_a1 __attribute((__aligned__(1))); +# else +typedef u64 u64_a1; +# endif +#endif + +#if defined(__GNUC__) && !defined(STRICT_ALIGNMENT) +typedef u64 u64_aX __attribute((__aligned__(1))); +#else +typedef u64 u64_aX; +#endif + #undef SMALL_REGISTER_BANK #if defined(__i386) || defined(__i386__) || defined(_M_IX86) # define SMALL_REGISTER_BANK @@ -197,13 +211,13 @@ typedef unsigned long long u64; # define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ c0,c1,c2,c3,c4,c5,c6,c7 # define C0(K,i) (((u64*)(Cx.c+0))[2*K.c[(i)*8+0]]) -# define C1(K,i) (((u64*)(Cx.c+7))[2*K.c[(i)*8+1]]) -# define C2(K,i) (((u64*)(Cx.c+6))[2*K.c[(i)*8+2]]) -# define C3(K,i) (((u64*)(Cx.c+5))[2*K.c[(i)*8+3]]) -# define C4(K,i) (((u64*)(Cx.c+4))[2*K.c[(i)*8+4]]) -# define C5(K,i) (((u64*)(Cx.c+3))[2*K.c[(i)*8+5]]) -# define C6(K,i) (((u64*)(Cx.c+2))[2*K.c[(i)*8+6]]) -# define C7(K,i) (((u64*)(Cx.c+1))[2*K.c[(i)*8+7]]) +# define C1(K,i) (((u64_a1*)(Cx.c+7))[2*K.c[(i)*8+1]]) +# define C2(K,i) (((u64_a1*)(Cx.c+6))[2*K.c[(i)*8+2]]) +# define C3(K,i) (((u64_a1*)(Cx.c+5))[2*K.c[(i)*8+3]]) +# define C4(K,i) (((u64_a1*)(Cx.c+4))[2*K.c[(i)*8+4]]) +# define C5(K,i) (((u64_a1*)(Cx.c+3))[2*K.c[(i)*8+5]]) +# define C6(K,i) (((u64_a1*)(Cx.c+2))[2*K.c[(i)*8+6]]) +# define C7(K,i) (((u64_a1*)(Cx.c+1))[2*K.c[(i)*8+7]]) #endif static const @@ -537,7 +551,7 @@ void whirlpool_block(WHIRLPOOL_CTX *ctx, const void *inp, size_t n) } else # endif { - const u64 *pa = (const u64 *)p; + const u64_aX *pa = (const u64_aX *)p; S.q[0] = (K.q[0] = H->q[0]) ^ pa[0]; S.q[1] = (K.q[1] = H->q[1]) ^ pa[1]; S.q[2] = (K.q[2] = H->q[2]) ^ pa[2]; @@ -775,7 +789,7 @@ void whirlpool_block(WHIRLPOOL_CTX *ctx, const void *inp, size_t n) } else # endif { - const u64 *pa = (const u64 *)p; + const u64_aX *pa = (const u64_aX *)p; H->q[0] ^= S.q[0] ^ pa[0]; H->q[1] ^= S.q[1] ^ pa[1]; H->q[2] ^= S.q[2] ^ pa[2]; diff --git a/crypto/x509/v3_alt.c b/crypto/x509/v3_alt.c index 5fece4f9..dd45546f 100644 --- a/crypto/x509/v3_alt.c +++ b/crypto/x509/v3_alt.c @@ -128,7 +128,7 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, BIO_snprintf(othername, sizeof(othername), "othername: %s:", oline); else - strncpy(othername, "othername:", sizeof(othername)); + OPENSSL_strlcpy(othername, "othername:", sizeof(othername)); /* check if the value is something printable */ if (gen->d.otherName->value->type == V_ASN1_IA5STRING) { diff --git a/crypto/x509/v3_ncons.c b/crypto/x509/v3_ncons.c index d7b82b77..4543ec2e 100644 --- a/crypto/x509/v3_ncons.c +++ b/crypto/x509/v3_ncons.c @@ -197,7 +197,7 @@ static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) int len2 = ip->length - len1; char *ip1 = ipaddr_to_asc(ip->data, len1); char *ip2 = ipaddr_to_asc(ip->data + len1, len2); - int ret = ret = ip1 != NULL && ip2 != NULL + int ret = ip1 != NULL && ip2 != NULL && BIO_printf(bp, "IP:%s/%s", ip1, ip2) > 0; OPENSSL_free(ip1); diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c index 05615c1e..25f72e05 100644 --- a/crypto/x509/x509_cmp.c +++ b/crypto/x509/x509_cmp.c @@ -300,7 +300,7 @@ int X509_check_private_key(const X509 *x, const EVP_PKEY *k) xk = X509_get0_pubkey(x); if (xk) - ret = EVP_PKEY_cmp(xk, k); + ret = EVP_PKEY_eq(xk, k); else ret = -2; diff --git a/crypto/x509/x509_d2.c b/crypto/x509/x509_d2.c index cb0f84a7..c0543adf 100644 --- a/crypto/x509/x509_d2.c +++ b/crypto/x509/x509_d2.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -73,8 +73,6 @@ int X509_STORE_load_store(X509_STORE *ctx, const char *uri) return 1; } -/* Deprecated */ -#ifndef OPENSSL_NO_DEPRECATED_3_0 int X509_STORE_load_locations(X509_STORE *ctx, const char *file, const char *path) { @@ -86,4 +84,3 @@ int X509_STORE_load_locations(X509_STORE *ctx, const char *file, return 0; return 1; } -#endif diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c index e37024b5..450f2a79 100644 --- a/crypto/x509/x509_err.c +++ b/crypto/x509/x509_err.c @@ -20,10 +20,10 @@ static const ERR_STRING_DATA X509_str_reasons[] = { {ERR_PACK(ERR_LIB_X509, 0, X509_R_BASE64_DECODE_ERROR), "base64 decode error"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_CANT_CHECK_DH_KEY), "cant check dh key"}, - {ERR_PACK(ERR_LIB_X509, 0, X509_R_CERT_ALREADY_IN_HASH_TABLE), - "cert already in hash table"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_CERTIFICATE_VERIFICATION_FAILED), "certificate verification failed"}, + {ERR_PACK(ERR_LIB_X509, 0, X509_R_CERT_ALREADY_IN_HASH_TABLE), + "cert already in hash table"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_ALREADY_DELTA), "crl already delta"}, {ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_VERIFY_FAILURE), "crl verify failure"}, diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c index 639e8e47..fcc07b17 100644 --- a/crypto/x509/x509_req.c +++ b/crypto/x509/x509_req.c @@ -85,7 +85,7 @@ int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) int ok = 0; xk = X509_REQ_get_pubkey(x); - switch (EVP_PKEY_cmp(xk, k)) { + switch (EVP_PKEY_eq(xk, k)) { case 1: ok = 1; break; diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index fb046918..1e881ccf 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -139,10 +139,9 @@ static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) xtmp = sk_X509_value(certs, i); if (!X509_cmp(xtmp, x)) break; + xtmp = NULL; } - if (i < sk_X509_num(certs)) - X509_up_ref(xtmp); - else + if (xtmp != NULL && !X509_up_ref(xtmp)) xtmp = NULL; sk_X509_pop_free(certs, X509_free); return xtmp; @@ -275,17 +274,24 @@ int X509_verify_cert(X509_STORE_CTX *ctx) return -1; } + if (!X509_up_ref(ctx->cert)) { + X509err(X509_F_X509_VERIFY_CERT, ERR_R_INTERNAL_ERROR); + ctx->error = X509_V_ERR_UNSPECIFIED; + return -1; + } + /* * first we make sure the chain we are going to build is present and that * the first entry is in place */ - if (((ctx->chain = sk_X509_new_null()) == NULL) || - (!sk_X509_push(ctx->chain, ctx->cert))) { + if ((ctx->chain = sk_X509_new_null()) == NULL + || !sk_X509_push(ctx->chain, ctx->cert)) { + X509_free(ctx->cert); X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); ctx->error = X509_V_ERR_OUT_OF_MEM; return -1; } - X509_up_ref(ctx->cert); + ctx->num_untrusted = 1; /* If the peer's public key is too weak, we can stop early. */ @@ -370,11 +376,15 @@ static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { *issuer = find_issuer(ctx, ctx->other_ctx, x); - if (*issuer) { - X509_up_ref(*issuer); - return 1; - } else - return 0; + + if (*issuer == NULL || !X509_up_ref(*issuer)) + goto err; + + return 1; + + err: + *issuer = NULL; + return 0; } static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, @@ -387,15 +397,21 @@ static STACK_OF(X509) *lookup_certs_sk(X509_STORE_CTX *ctx, for (i = 0; i < sk_X509_num(ctx->other_ctx); i++) { x = sk_X509_value(ctx->other_ctx, i); if (X509_NAME_cmp(nm, X509_get_subject_name(x)) == 0) { + if (!X509_up_ref(x)) { + sk_X509_pop_free(sk, X509_free); + X509err(X509_F_LOOKUP_CERTS_SK, ERR_R_INTERNAL_ERROR); + ctx->error = X509_V_ERR_UNSPECIFIED; + return NULL; + } if (sk == NULL) sk = sk_X509_new_null(); - if (sk == NULL || sk_X509_push(sk, x) == 0) { + if (sk == NULL || !sk_X509_push(sk, x)) { + X509_free(x); sk_X509_pop_free(sk, X509_free); X509err(X509_F_LOOKUP_CERTS_SK, ERR_R_MALLOC_FAILURE); ctx->error = X509_V_ERR_OUT_OF_MEM; return NULL; } - X509_up_ref(x); } } return sk; @@ -3244,7 +3260,16 @@ static int build_chain(X509_STORE_CTX *ctx) /* Drop this issuer from future consideration */ (void) sk_X509_delete_ptr(sktmp, xtmp); + if (!X509_up_ref(xtmp)) { + X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR); + trust = X509_TRUST_REJECTED; + ctx->error = X509_V_ERR_UNSPECIFIED; + search = 0; + continue; + } + if (!sk_X509_push(ctx->chain, xtmp)) { + X509_free(xtmp); X509err(X509_F_BUILD_CHAIN, ERR_R_MALLOC_FAILURE); trust = X509_TRUST_REJECTED; ctx->error = X509_V_ERR_OUT_OF_MEM; @@ -3252,7 +3277,7 @@ static int build_chain(X509_STORE_CTX *ctx) continue; } - X509_up_ref(x = xtmp); + x = xtmp; ++ctx->num_untrusted; ss = cert_self_signed(ctx, xtmp); if (ss < 0) { diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index 6d7f341c..31c99c45 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -20,7 +20,7 @@ #include #include #include "crypto/x509.h" -#include +#include #include #include #include @@ -130,21 +130,11 @@ int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) &x->sig_alg, &x->signature, &x->cert_info, ctx); } -#if !defined(OPENSSL_NO_SOCK) -static ASN1_VALUE *simple_get_asn1(const char *url, BIO *bio, BIO *rbio, - int timeout, const ASN1_ITEM *it) +#ifndef OPENSSL_NO_OCSP +int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert) { - return OSSL_HTTP_get_asn1(url, NULL, NULL /* no proxy used */, bio, - rbio, NULL /* no callback for SSL/TLS */, NULL, - NULL /* headers */, 1024 /* maxline */, - 0 /* max_resp_len */, timeout, - NULL /* expected_content_type */, it); -} - -X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout) -{ - return (X509 *)simple_get_asn1(url, bio, rbio, timeout, - ASN1_ITEM_rptr(X509)); + return OCSP_REQ_CTX_nbio_d2i(rctx, + (ASN1_VALUE **)pcert, ASN1_ITEM_rptr(X509)); } #endif @@ -176,11 +166,12 @@ int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) &x->crl, ctx); } -#if !defined(OPENSSL_NO_SOCK) -X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout) +#ifndef OPENSSL_NO_OCSP +int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl) { - return (X509_CRL *)simple_get_asn1(url, bio, rbio, timeout, - ASN1_ITEM_rptr(X509_CRL)); + return OCSP_REQ_CTX_nbio_d2i(rctx, + (ASN1_VALUE **)pcrl, + ASN1_ITEM_rptr(X509_CRL)); } #endif diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c index 23e92f2b..c73ea7a4 100644 --- a/crypto/x509/x_pubkey.c +++ b/crypto/x509/x_pubkey.c @@ -30,7 +30,7 @@ struct X509_pubkey_st { EVP_PKEY *pkey; }; -static int x509_pubkey_decode(EVP_PKEY **pk, X509_PUBKEY *key); +static int x509_pubkey_decode(EVP_PKEY **pk, const X509_PUBKEY *key); /* Minor tweak to operation: free up EVP_PKEY */ static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, @@ -151,7 +151,7 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) */ -static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key) +static int x509_pubkey_decode(EVP_PKEY **ppkey, const X509_PUBKEY *key) { EVP_PKEY *pkey = EVP_PKEY_new(); @@ -188,7 +188,7 @@ static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key) return 0; } -EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key) +EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key) { EVP_PKEY *ret = NULL; @@ -216,11 +216,14 @@ EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key) return NULL; } -EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) +EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key) { EVP_PKEY *ret = X509_PUBKEY_get0(key); - if (ret != NULL) - EVP_PKEY_up_ref(ret); + + if (ret != NULL && !EVP_PKEY_up_ref(ret)) { + X509err(X509_F_X509_PUBKEY_GET, ERR_R_INTERNAL_ERROR); + ret = NULL; + } return ret; } @@ -450,7 +453,7 @@ int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen, - X509_ALGOR **pa, X509_PUBKEY *pub) + X509_ALGOR **pa, const X509_PUBKEY *pub) { if (ppkalg) *ppkalg = pub->algor->algorithm; @@ -469,3 +472,24 @@ ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) return NULL; return x->cert_info.key->public_key; } + +/* Returns 1 for equal, 0, for non-equal, < 0 on error */ +int X509_PUBKEY_eq(const X509_PUBKEY *a, const X509_PUBKEY *b) +{ + X509_ALGOR *algA, *algB; + EVP_PKEY *pA, *pB; + + if (a == b) + return 1; + if (a == NULL || b == NULL) + return 0; + if (!X509_PUBKEY_get0_param(NULL, NULL, NULL, &algA, a) || algA == NULL + || !X509_PUBKEY_get0_param(NULL, NULL, NULL, &algB, b) || algB == NULL) + return -2; + if (X509_ALGOR_cmp(algA, algB) != 0) + return 0; + if ((pA = X509_PUBKEY_get0(a)) == NULL + || (pB = X509_PUBKEY_get0(b)) == NULL) + return -2; + return EVP_PKEY_eq(pA, pB); +} diff --git a/demos/certs/apps/apps.cnf b/demos/certs/apps/apps.cnf index bd762b7d..07a3d10b 100644 --- a/demos/certs/apps/apps.cnf +++ b/demos/certs/apps/apps.cnf @@ -35,9 +35,6 @@ commonName = $ENV::CN basicConstraints=critical, CA:FALSE keyUsage=critical, nonRepudiation, digitalSignature, keyEncipherment -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - [ ec_cert ] # These extensions are added when 'ca' signs a request for an end entity @@ -46,9 +43,6 @@ nsComment = "OpenSSL Generated Certificate" basicConstraints=critical, CA:FALSE keyUsage=critical, nonRepudiation, digitalSignature, keyAgreement -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid diff --git a/demos/certs/ca.cnf b/demos/certs/ca.cnf index c75a71a6..2fbf2049 100644 --- a/demos/certs/ca.cnf +++ b/demos/certs/ca.cnf @@ -35,9 +35,6 @@ commonName = $ENV::CN basicConstraints=critical, CA:FALSE keyUsage=critical, nonRepudiation, digitalSignature, keyEncipherment -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid @@ -47,9 +44,6 @@ authorityKeyIdentifier=keyid basicConstraints=critical, CA:FALSE keyUsage=critical, nonRepudiation, digitalSignature, keyEncipherment -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid diff --git a/doc/internal/man3/ossl_cmp_hdr_init.pod b/doc/internal/man3/ossl_cmp_hdr_init.pod index cf7f5965..0c640505 100644 --- a/doc/internal/man3/ossl_cmp_hdr_init.pod +++ b/doc/internal/man3/ossl_cmp_hdr_init.pod @@ -4,6 +4,7 @@ ossl_cmp_hdr_set_pvno, ossl_cmp_hdr_get_pvno, +ossl_cmp_hdr_get_protection_nid, ossl_cmp_hdr_get0_sendernonce, ossl_cmp_general_name_is_NULL_DN, ossl_cmp_hdr_set1_sender, @@ -25,6 +26,7 @@ ossl_cmp_hdr_init int ossl_cmp_hdr_set_pvno(OSSL_CMP_PKIHEADER *hdr, int pvno); int ossl_cmp_hdr_get_pvno(const OSSL_CMP_PKIHEADER *hdr); + int ossl_cmp_hdr_get_protection_nid(const OSSL_CMP_PKIHEADER *hdr); ASN1_OCTET_STRING *ossl_cmp_hdr_get0_sendernonce(const OSSL_CMP_PKIHEADER *hdr); int ossl_cmp_general_name_is_NULL_DN(GENERAL_NAME *name); @@ -52,6 +54,9 @@ ossl_cmp_hdr_set_pvno() sets hdr->pvno to the given B. ossl_cmp_hdr_get_pvno() returns the pvno of the given B or -1 on error. +ossl_cmp_hdr_get_protection_nid returns the NID of the protection algorithm +in B or NID_undef on error. + ossl_cmp_hdr_get0_sendernonce() returns the sender nonce of the given PKIHeader. ossl_cmp_general_name_is_NULL_DN() determines if the given GENERAL_NAME @@ -110,7 +115,9 @@ CMP is defined in RFC 4210 (and CRMF in RFC 4211). ossl_cmp_hdr_get_pvno() returns the pvno of the given B or -1 on error. -ossl_cmp_hdr_get0_sendernonce() returns the respective nonce. +ossl_cmp_hdr_get_protection_nid returns the respective NID, NID_undef on error. + +ossl_cmp_hdr_get0_sendernonce() returns the respective nonce, or NULL. ossl_cmp_general_name_is_NULL_DN() returns 1 given a NULL-DN, else 0. diff --git a/doc/internal/man3/ossl_cmp_msg_check_received.pod b/doc/internal/man3/ossl_cmp_msg_check_received.pod deleted file mode 100644 index 0fd41403..00000000 --- a/doc/internal/man3/ossl_cmp_msg_check_received.pod +++ /dev/null @@ -1,86 +0,0 @@ -=pod - -=head1 NAME - -ossl_cmp_allow_unprotected_cb_t, -ossl_cmp_msg_check_received -- does all checks on a received CMP message that can be done generically - -=head1 SYNOPSIS - - #include "cmp_local.h" - - typedef int (*ossl_cmp_allow_unprotected_cb_t)(const OSSL_CMP_CTX *ctx, - const OSSL_CMP_MSG *msg, - int invalid_protection, int arg); - - int ossl_cmp_msg_check_received(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, - ossl_cmp_allow_unprotected_cb_t cb, int cb_arg); - -=head1 DESCRIPTION - -ossl_cmp_msg_check_received() checks the given message B, -which may be a server response or a request by some client. - -It is ensured for the B that - -=over 4 - -=item it has a valid body type, - -=item its protection is present and valid (or a callback function B -is present and indicates that a missing or invalid protection is acceptable), - -=item its recipNonce matches any previous senderNonce stored in B, and - -=item its transaction ID matches any previous transaction ID stored in B. - -=back - -In case no protection is present and B is not NULL then this callback -function is called with its B parameter being 0, while in -case an invalid protection is present the B parameter is 1. -The callback is passed also the arguments B, B, and -(which typically contains the expected message type). -The callback should return 1 on acceptance, 0 on rejection, or -1 on error. -It should not put and error on the error stack since this could be misleading. - -If all checks pass then ossl_cmp_msg_check_received() - -=over 4 - -=item learns the senderNonce from the received message, - -=item learns the transaction ID if it is not yet in B, and - -=item adds any extraCerts contained in the to the list of untrusted -certificates in B for future use, such that -they are available already to the certificate confirmation callback and the -peer does not need to send them again (at least not in the same transaction). -For efficiency, the extraCerts are prepended to the list so they get used first. - -=back - -=head1 RETURN VALUES - -ossl_cmp_msg_check_received() returns the message body type (which is >= 0) -on success, -1 on error. - -=head1 SEE ALSO - -L - -=head1 HISTORY - -The OpenSSL CMP support was added in OpenSSL 3.0. - -=head1 COPYRIGHT - -Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the Apache License 2.0 (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/doc/internal/man3/ossl_cmp_msg_check_update.pod b/doc/internal/man3/ossl_cmp_msg_check_update.pod new file mode 100644 index 00000000..4e7a9224 --- /dev/null +++ b/doc/internal/man3/ossl_cmp_msg_check_update.pod @@ -0,0 +1,95 @@ +=pod + +=head1 NAME + +ossl_cmp_allow_unprotected_cb_t, +ossl_cmp_msg_check_update +- generic checks on a received CMP message, updating the context + +=head1 SYNOPSIS + + #include "cmp_local.h" + + typedef int (*ossl_cmp_allow_unprotected_cb_t)(const OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *msg, + int invalid_protection, int arg); + + int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, + ossl_cmp_allow_unprotected_cb_t cb, int cb_arg); + +=head1 DESCRIPTION + +ossl_cmp_msg_check_update() does all generic checks on the given message B, +which may be a server response or a request by some client, +and updates the B accordingly. + +The B is checked for the following: + +=over 4 + +=item its sender is of appropriate type (currently only B) + and matches any expected sender or srvCert subject given in B, + +=item its protection is present and valid (or a callback function B +is present and indicates that a missing or invalid protection is acceptable), + +=item its CMP protocol version is acceptable, namely B, + +=item its body type is valid, + +=item its transaction ID matches any transaction ID given in B, and + +=item its recipNonce matches any senderNonce given in B. + +=back + +In case no protection is present and B is not NULL then this callback +function is called with its B parameter being 0, while in +case an invalid protection is present the B parameter is 1. +The callback is passed also the arguments B, B, and +(which typically contains the expected message type). +The callback should return 1 on acceptance, 0 on rejection, or -1 on error. +It should not put an error on the error stack since this could be misleading. + +ossl_cmp_msg_check_update() adds all extraCerts contained in the to +the list of untrusted certificates in B such that they are already usable +for OSSL_CMP_validate_msg(), which is called internally, and for future use. +Thus they are available also to the certificate confirmation callback, and the +peer does not need to send them again (at least not in the same transaction). +Note that it does not help validating the message before storing the extraCerts +because they are not part of the protected portion of the message anyway. +For efficiency, the extraCerts are prepended to the list so they get used first. + +If all checks pass then ossl_cmp_msg_check_update() +records in B the senderNonce of the received message as the new recipNonce +and learns the transaction ID if none is currently present in B. + +Moreover, according to RFC 4210 section 5.3.2, if the message protection is +PBM-based then any certificates in the caPubs field are added to the list of +trusted certificates (if set via L). +This way these certs are available for validating subsequent messages in the +same context and could apply to any Polling Response (pollRep), error, or PKI +Confirmation (PKIConf) messages following in the same or future transactions. + +=head1 RETURN VALUES + +ossl_cmp_msg_check_update() returns 1 on success, -1 on error. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The OpenSSL CMP support was added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/internal/man3/ossl_provider_new.pod b/doc/internal/man3/ossl_provider_new.pod index 36fe6301..7bc5a386 100644 --- a/doc/internal/man3/ossl_provider_new.pod +++ b/doc/internal/man3/ossl_provider_new.pod @@ -13,7 +13,8 @@ ossl_provider_name, ossl_provider_dso, ossl_provider_module_name, ossl_provider_module_path, ossl_provider_library_context, ossl_provider_teardown, ossl_provider_gettable_params, -ossl_provider_get_params, ossl_provider_query_operation +ossl_provider_get_params, ossl_provider_query_operation, +ossl_provider_set_operation_bit, ossl_provider_test_operation_bit - internal provider routines =head1 SYNOPSIS @@ -63,6 +64,10 @@ ossl_provider_get_params, ossl_provider_query_operation int operation_id, int *no_cache); + int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum); + int ossl_provider_test_operation_bit(OSSL_PROVIDER *provider, size_t bitnum, + int *result); + =head1 DESCRIPTION I is a type that holds all the necessary information @@ -208,6 +213,13 @@ I function, if the provider has one. It should return an array of I for the given I. +ossl_provider_set_operation_bit() registers a 1 for operation I +in a bitstring that's internal to I. + +ossl_provider_tests_operation_bit() checks if the bit operation I +is set (1) or not (0) in the internal I bitstring, and sets +I<*result> to 1 or 0 accorddingly. + =head1 NOTES Locating a provider module happens as follows: @@ -270,6 +282,9 @@ otherwise NULL. ossl_provider_get_params() returns 1 on success, or 0 on error. If this function isn't available in the provider, 0 is returned. +ossl_provider_set_operation_bit() and ossl_provider_test_operation_bit() +return 1 on success, or 0 on error. + =head1 SEE ALSO L, L, L @@ -280,7 +295,7 @@ The functions described here were all added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/CA.pl.pod b/doc/man1/CA.pl.pod index 85e02b9e..aa2e0058 100644 --- a/doc/man1/CA.pl.pod +++ b/doc/man1/CA.pl.pod @@ -113,7 +113,7 @@ written to standard output. =item B<-signCA> -This option is the same as the B<-signreq> option except it uses the +This option is the same as the B<-sign> option except it uses the configuration file section B and so makes the signed request a valid CA certificate. This is useful when creating intermediate CA from a root CA. Extra params are passed to L. @@ -165,7 +165,7 @@ the request and finally create a PKCS#12 file containing it. CA.pl -newca CA.pl -newreq - CA.pl -signreq + CA.pl -sign CA.pl -pkcs12 "My Test Certificate" =head1 ENVIRONMENT diff --git a/doc/man1/openssl-ciphers.pod.in b/doc/man1/openssl-ciphers.pod.in index e5a4121f..29e0c9e4 100644 --- a/doc/man1/openssl-ciphers.pod.in +++ b/doc/man1/openssl-ciphers.pod.in @@ -403,6 +403,13 @@ used and only the two suite B compliant cipher suites (ECDHE-ECDSA-AES128-GCM-SHA256 and ECDHE-ECDSA-AES256-GCM-SHA384) are permissible. +=item B + +All cipher suites using encryption algorithm in Cipher Block Chaining (CBC) +mode. These cipher suites are only supported in TLS v1.2 and earlier. Currently +it's an alias for the following cipherstrings: B, B, B, +B, B, B, B, B, B. + =back =head1 EQUAL PREFERENCE GROUPS diff --git a/doc/man1/openssl-cmp.pod.in b/doc/man1/openssl-cmp.pod.in index 102f99ae..89bb549c 100644 --- a/doc/man1/openssl-cmp.pod.in +++ b/doc/man1/openssl-cmp.pod.in @@ -151,7 +151,7 @@ The B command is a client implementation for the Certificate Management Protocol (CMP) as defined in RFC4210. It can be used to request certificates from a CA server, update their certificates, -request certificates to be revoked, and perform other CMP requests. +request certificates to be revoked, and perform other types of CMP requests. =head1 OPTIONS @@ -206,16 +206,16 @@ Currently implemented commands are: =back -B requests initialization of an End Entity into a PKI hierarchy by means of -issuance of a first certificate. +B requests initialization of an End Entity into a PKI hierarchy +by issuing a first certificate. -B requests issuance of an additional certificate for an End Entity already +B requests issuing an additional certificate for an End Entity already initialized to the PKI hierarchy. -B requests issuance of an additional certificate similarly to B +B requests issuing an additional certificate similarly to B but uses PKCS#10 CSR format. -B requests (key) update for an existing, given certificate. +B requests a (key) update for an existing, given certificate. B requests revocation of an existing, given certificate. @@ -268,8 +268,8 @@ This default is used for IR and CR only if no SANs are set. The argument must be formatted as I, characters may be escaped by C<\>E(backslash), no spaces are skipped. -In case B<-cert> is not set, for instance when using MSG_MAC_ALG, -the subject DN is also used as sender of the PKI message. +The subject DN is also used as fallback sender of outgoing CMP messages +if no B<-cert> and no B<-oldcert> are given. =item B<-issuer> I @@ -393,8 +393,9 @@ It must be given for RR, while for KUR it defaults to B<-cert>. The reference certificate determined in this way, if any, is also used for deriving default subject DN and Subject Alternative Names for IR, CR, and KUR. -Its issuer, if any, is used as default recipient in the CMP message header -if neither B<-srvcert>, B<-recipient>, nor B<-issuer> is available. +Its subject is used as sender of outgoing messages if B<-cert> is not given. +Its issuer is used as default recipient in CMP message headers +if neither B<-recipient>, B<-srvcert>, nor B<-issuer> is given. =item B<-revreason> I @@ -428,13 +429,13 @@ Reason numbers defined in RFC 5280 are: The IP address or DNS hostname and optionally port (defaulting to 80 or 443) of the CMP server to connect to using HTTP(S) transport. -The optional "http://" or "https://" prefix is ignored. +The optional I or I prefix is ignored. =item B<-proxy> I<[http[s]://]address[:port][/path]> The HTTP(S) proxy server to use for reaching the CMP server unless B applies, see below. -The optional "http://" or "https://" prefix and any trailing path are ignored. +The optional I or I prefix and any trailing path are ignored. Defaults to the environment variable C if set, else C in case no TLS is used, otherwise C if set, else C. @@ -447,7 +448,7 @@ Default is from the environment variable C if set, else C. =item B<-path> I HTTP path at the CMP server (aka CMP alias) to use for POST requests. -Defaults to "/". +Defaults to I. =item B<-msg_timeout> I @@ -473,8 +474,9 @@ Default is 0 (infinite). When verifying signature-based protection of CMP response messages, these are the CA certificate(s) to trust while checking certificate chains during CMP server authentication. -This option gives more flexibility than the B<-srvcert> option because -it does not pin down the expected CMP server by allowing only one certificate. +This option gives more flexibility than the B<-srvcert> option because the +protection certificate is not pinned but may be any certificate +for which a chain to one of the given trusted certificates can be constructed. Multiple filenames may be given, separated by commas and/or whitespace (where in the latter case the whole argument must be enclosed in "..."). @@ -482,65 +484,55 @@ Each source may contain multiple certificates. =item B<-untrusted> I -Non-trusted intermediate certificate(s) that may be useful -for constructing the TLS client certificate chain (if TLS is enabled) and -for building certificate chains while verifying the CMP server certificate -(when checking signature-based CMP message protection) -and while verifying the newly enrolled certificate. -These may get added to the extraCerts field sent in requests as far as needed. +Non-trusted intermediate CA certificate(s) that may be useful for cert path +construction for the CMP client certificate (to include in the extraCerts field +of outgoing messages), for the TLS client certificate (if TLS is enabled), +when verifying the CMP server certificate (checking signature-based +CMP message protection), and when verifying newly enrolled certificates. Multiple filenames may be given, separated by commas and/or whitespace. Each file may contain multiple certificates. =item B<-srvcert> I -The specific CMP server certificate to use and directly trust (even if it is +The specific CMP server certificate to expect and directly trust (even if it is expired) when verifying signature-based protection of CMP response messages. -May be set alternatively to the B<-trusted> option -if the certificate is available and only this one shall be accepted. +May be set alternatively to the B<-trusted> option to pin the accepted server. -If set, the issuer of the certificate is also used as the recipient of the CMP -request and as the expected sender of the CMP response, -overriding any potential B<-recipient> option. +If set, the subject of the certificate is also used +as default value for the recipient of CMP requests +and as default value for the expected sender of incoming CMP messages. =item B<-recipient> I -This option may be used to explicitly set the Distinguished Name (DN) -of the CMP message recipient, i.e., the CMP server (usually a CA or RA entity). +Distinguished Name (DN) to use in the recipient field of CMP request messages, +i.e., the CMP server (usually a CA or RA entity). The argument must be formatted as I, characters may be escaped by C<\>E(backslash), no spaces are skipped. -If a CMP server certificate is given with the B<-srvcert> option, its subject -name is taken as the recipient name and the B<-recipient> option is ignored. -If neither of the two are given, the recipient of the PKI message is -determined in the following order: from the B<-issuer> option if present, -the issuer of old cert given with the B<-oldcert> option if present, -the issuer of the client certificate (B<-cert> option) if present. - -The recipient field in the header of CMP messagese is mandatory. -If none of the options that enable the derivation of the recipient name are -given, no suitable value for the recipient in the PKIHeader is available. -As a last resort it is set to NULL-DN. - -When a response is received, its sender must match the recipient of the request. +The recipient field in the header of a CMP message is mandatory. +If not given explicitly the recipient is determined in the following order: +the subject of the CMP server certificate given with the B<-srvcert> option, +the B<-issuer> option, +the issuer of the certificate given with the B<-oldcert> option, +the issuer of the CMP client certificate (B<-cert> option), +as far as any of those is present, else the NULL-DN as last resort. =item B<-expect_sender> I -Distinguished Name (DN) of the expected sender of CMP response messages when -MSG_SIG_ALG is used for protection. -This can be used to ensure that only a particular entity is accepted -as the CMP server, and attackers are not able to use arbitrary certificates -of a trusted PKI hierarchy to fraudulently pose as a CMP server. -Note that this option gives slightly more freedom than B<-srvcert>, -which pins down the server to a particular certificate, -while B<-expect_sender> I will continue to match after updates of the -server cert. +Distinguished Name (DN) expected in the sender field of incoming CMP messages. +Defaults to the subject DN of the pinned B<-srvcert>, if any. The argument must be formatted as I, characters may be escaped by C<\>E(backslash), no spaces are skipped. -If not given, the subject DN of B<-srvcert>, if provided, will be used. +This can be used to make sure that only a particular entity is accepted as +CMP message signer, and attackers are not able to use arbitrary certificates +of a trusted PKI hierarchy to fraudulently pose as a CMP server. +Note that this option gives slightly more freedom than setting the B<-srvcert>, +which pins the server to the holder of a particular certificate, while the +expected sender name will continue to match after updates of the server cert. =item B<-ignore_keyusage> @@ -621,8 +613,8 @@ B section in L. The client's current certificate. Requires the corresponding key to be given with B<-key>. -The subject of this certificate will be used as the "sender" field -of outgoing CMP messages, while B<-subjectName> may provide a fallback value. +The subject of this certificate will be used as sender of outgoing CMP messages, +while the subject of B<-oldcert> or B<-subjectName> may provide fallback values. When using signature-based message protection, this "protection certificate" will be included first in the extraCerts field of outgoing messages. In Initialization Request (IR) messages this can be used for authenticating @@ -630,7 +622,6 @@ using an external entity certificate as defined in appendix E.7 of RFC 4210. For Key Update Request (KUR) messages this is also used as the certificate to be updated if the B<-oldcert> option is not given. If the file includes further certs, they are appended to the untrusted certs. -These may get added to the extraCerts field sent in requests as far as needed. =item B<-key> I @@ -740,8 +731,8 @@ when connecting to CMP server. =item B<-tls_cert> I Client's TLS certificate. -If the file includes further certificates, -they are used for constructing the client cert chain provided to the TLS server. +If the file includes further certs they are used (along with B<-untrusted> +certs) for constructing the client cert chain provided to the TLS server. =item B<-tls_key> I @@ -1015,7 +1006,7 @@ the CMP command-line argument B<-proxy>, for example -proxy http://192.168.1.1:8080 In the Insta Demo CA scenario both clients and the server may use the pre-shared -secret "insta" and the reference value "3078" to authenticate to each other. +secret I and the reference value I<3078> to authenticate to each other. Alternatively, CMP messages may be protected in signature-based manner, where the trust anchor in this case is F @@ -1060,7 +1051,7 @@ and/or on the command line. The following examples at first do not make use of a configuration file. They assume that a CMP server can be contacted on the local TCP port 80 -and accepts requests under the alias "/pkix/". +and accepts requests under the alias I. For enrolling its very first certificate the client generates a first client key and sends an initial request message to the local CMP server diff --git a/doc/man1/openssl-cms.pod.in b/doc/man1/openssl-cms.pod.in index 375d3587..5ef1219a 100644 --- a/doc/man1/openssl-cms.pod.in +++ b/doc/man1/openssl-cms.pod.in @@ -569,7 +569,8 @@ Message-digest of the eContent OCTET STRING within encapContentInfo being signed =item * -An ESS signing-certificate or ESS signing-certificate-v2 attribute, as defined in Enhanced Security Services (ESS), RFC 2634 and RFC 5035. +An ESS signing-certificate or ESS signing-certificate-v2 attribute, as defined +in Enhanced Security Services (ESS), RFC 2634 and RFC 5035. An ESS signing-certificate attribute only allows for the use of SHA-1 as a digest algorithm. An ESS signing-certificate-v2 attribute allows for the use of any digest algorithm. @@ -577,9 +578,10 @@ An ESS signing-certificate-v2 attribute allows for the use of any digest algorit The digital signature value computed on the user data and, when present, on the signed attributes. -Note that currently the B<-cades> option applies only to the B<-sign> operation and is ignored during -the B<-verify> operation, i.e. the signing certification is not checked during the verification process. -This feature might be added in a future version. +NOTE that the B<-cades> option applies to the B<-sign> or B<-verify> operations. +With this option, the B<-verify> operation also checks that the signing-certificates +attribute is present, and its value matches the verification trust chain built +during the verification process. =back diff --git a/doc/man1/openssl-fipsinstall.pod.in b/doc/man1/openssl-fipsinstall.pod.in index 1d1cdea7..7675e5e3 100644 --- a/doc/man1/openssl-fipsinstall.pod.in +++ b/doc/man1/openssl-fipsinstall.pod.in @@ -25,20 +25,26 @@ B =head1 DESCRIPTION This command is used to generate a FIPS module configuration file. +This configuration file can be used each time a FIPS module is loaded +in order to pass data to the FIPS module self tests. The FIPS module always +verifies its MAC, but only needs to run the KAT's once, +at installation. + The generated configuration file consists of: =over 4 -=item - A mac of the FIPS module file. +=item - A MAC of the FIPS module file. -=item - A status indicator that indicates if the known answer Self Tests (KAT's) -have successfully run. +=item - A test status indicator. + +This indicates if the Known Answer Self Tests (KAT's) have successfully run. + +=item - A MAC of the status indicator. =back -This configuration file can be used each time a FIPS module is loaded -in order to pass data to the FIPS modules self tests. The FIPS module always -verifies the modules MAC, but only needs to run the KATS once during install. +This file is described in L. =head1 OPTIONS @@ -50,32 +56,36 @@ Print a usage message. =item B<-module> I -Filename of a fips module to perform an integrity check on. +Filename of the FIPS module to perform an integrity check on. =item B<-out> I -Filename to output the configuration data to, or standard output by default. +Filename to output the configuration data to; the default is standard output. =item B<-in> I -Input filename to load configuration data from. Used with the '-verify' option. -Standard input is used if the filename is '-'. +Input filename to load configuration data from. Used with the B<-verify> option. +Standard input is used if the filename is C<->. =item B<-verify> -Verify that the input configuration file contains the correct information +Verify that the input configuration file contains the correct information. =item B<-provider_name> I Name of the provider inside the configuration file. +This must be specified. =item B<-section_name> I Name of the section inside the configuration file. +This must be specified. =item B<-mac_name> I Specifies the name of a supported MAC algorithm which will be used. +The MAC mechanisms that are available will depend on the options +used when building OpenSSL. To see the list of supported MAC's use the command C. The default is B. @@ -122,10 +132,10 @@ Do not output pass/fail messages. Implies B<-noout>. =item B<-corrupt_desc> I, B<-corrupt_type> I -The corrupt options can be used to test failure of one or more self test(s) by +The corrupt options can be used to test failure of one or more self tests by name. -Either option or both may be used to select the self test(s) to corrupt. -Refer to the entries for "st-desc" and "st-type" in L for +Either option or both may be used to select the tests to corrupt. +Refer to the entries for B and B in L for values that can be used. =back @@ -145,18 +155,12 @@ Verify that the configuration file F contains the correct info: -section_name fips_install -mac_name HMAC -macopt digest:SHA256 \ -macopt hexkey:000102030405060708090A0B0C0D0E0F10111213 -verify -Corrupt any self tests which have the description 'SHA1': +Corrupt any self tests which have the description C: openssl fipsinstall -module ./fips.so -out fips.cnf -provider_name fips \ -section_name fipsinstall -mac_name HMAC -macopt digest:SHA256 \ -macopt hexkey:000102030405060708090A0B0C0D0E0F10111213 \ - -corrupt_desc', 'SHA1' - -=head1 NOTES - -The MAC mechanisms that are available will depend on the options -used when building OpenSSL. -The command C command can be used to list them. + -corrupt_desc 'SHA1' =head1 SEE ALSO diff --git a/doc/man1/openssl-genrsa.pod.in b/doc/man1/openssl-genrsa.pod.in index 89ae929c..33aa60ca 100644 --- a/doc/man1/openssl-genrsa.pod.in +++ b/doc/man1/openssl-genrsa.pod.in @@ -33,7 +33,7 @@ B B {- $OpenSSL::safe::opt_provider_synopsis -} [B] -=for openssl ifdef engine +=for openssl ifdef engine 3 =head1 DESCRIPTION @@ -70,6 +70,7 @@ for if it is not supplied via the B<-passout> argument. =item B<-F4>, B<-f4>, B<-3> The public exponent to use, either 65537 or 3. The default is 65537. +The B<-3> option has been deprecated. =item B<-primes> I diff --git a/doc/man1/openssl-kdf.pod.in b/doc/man1/openssl-kdf.pod.in index 9c585325..e92eee27 100644 --- a/doc/man1/openssl-kdf.pod.in +++ b/doc/man1/openssl-kdf.pod.in @@ -46,7 +46,7 @@ Output the derived key in binary form. Uses hexadecimal text format if not speci Passes options to the KDF algorithm. A comprehensive list of parameters can be found in the EVP_KDF_CTX implementation documentation. -Common parameter names used by EVP_KDF_CTX_set_params() are: +Common parameter names used by EVP_KDF_set_ctx_params() are: =over 4 diff --git a/doc/man1/openssl-mac.pod.in b/doc/man1/openssl-mac.pod.in index 4c9cc3bc..ff1b83fb 100644 --- a/doc/man1/openssl-mac.pod.in +++ b/doc/man1/openssl-mac.pod.in @@ -49,7 +49,7 @@ Output the MAC in binary form. Uses hexadecimal text format if not specified. Passes options to the MAC algorithm. A comprehensive list of controls can be found in the EVP_MAC implementation documentation. -Common parameter names used by EVP_MAC_CTX_get_params() are: +Common parameter names used by EVP_MAC_get_ctx_params() are: =over 4 diff --git a/doc/man1/openssl-s_client.pod.in b/doc/man1/openssl-s_client.pod.in index 4d6b54a5..367e59e9 100644 --- a/doc/man1/openssl-s_client.pod.in +++ b/doc/man1/openssl-s_client.pod.in @@ -78,6 +78,7 @@ B B [B<-split_send_frag>] [B<-max_pipelines>] [B<-read_buf>] +[B<-ignore_unexpected_eof>] [B<-bugs>] [B<-comp>] [B<-no_comp>] @@ -578,6 +579,15 @@ effect if the buffer size is larger than the size that would otherwise be used and pipelining is in use (see L for further information). +=item B<-ignore_unexpected_eof> + +Some TLS implementations do not send the mandatory close_notify alert on +shutdown. If the application tries to wait for the close_notify alert but the +peer closes the connection without sending it, an error is generated. When this +option is enabled the peer does not need to send the close_notify alert and a +closed connection will be treated as if the close_notify alert was received. +For more information on shutting down a connection, see L. + =item B<-bugs> There are several known bugs in SSL and TLS implementations. Adding this diff --git a/doc/man1/openssl-s_server.pod.in b/doc/man1/openssl-s_server.pod.in index 8e5da51c..28ef15ea 100644 --- a/doc/man1/openssl-s_server.pod.in +++ b/doc/man1/openssl-s_server.pod.in @@ -47,6 +47,7 @@ B B [B<-WWW>] [B<-http_server_binmode>] [B<-no_ca_names>] +[B<-ignore_unexpected_eof>] [B<-servername>] [B<-servername_fatal>] [B<-tlsextdebug>] @@ -420,6 +421,15 @@ Disable TLS Extension CA Names. You may want to disable it for security reasons or for compatibility with some Windows TLS implementations crashing when this extension is larger than 1024 bytes. +=item B<-ignore_unexpected_eof> + +Some TLS implementations do not send the mandatory close_notify alert on +shutdown. If the application tries to wait for the close_notify alert but the +peer closes the connection without sending it, an error is generated. When this +option is enabled the peer does not need to send the close_notify alert and a +closed connection will be treated as if the close_notify alert was received. +For more information on shutting down a connection, see L. + =item B<-id_prefix> I Generate SSL/TLS session IDs prefixed by I. This is mostly useful diff --git a/doc/man1/openssl.pod b/doc/man1/openssl.pod index 7170a984..c9e75eb5 100644 --- a/doc/man1/openssl.pod +++ b/doc/man1/openssl.pod @@ -1298,9 +1298,9 @@ General SSL/TLS. SSL/TLS cipher. -=item B +=item B -ENGINE configuration. +Show details about provider and engine configuration. =item B @@ -1405,7 +1405,11 @@ The B<-issuer_checks> option is deprecated as of OpenSSL 1.1.0 and is silently ignored. The B<-xcertform> and B<-xkeyform> options -are obsolete since OpenSSL 3.0.0 and have no effect. +are obsolete since OpenSSL 3.0 and have no effect. + +The interactive mode, which could be invoked by running C +with no further arguments, was removed in OpenSSL 3.0, and running +that program with no arguments is now equivalent to C. =head1 COPYRIGHT diff --git a/doc/man3/ASN1_STRING_TABLE_add.pod b/doc/man3/ASN1_STRING_TABLE_add.pod index f7b65fc2..243da826 100644 --- a/doc/man3/ASN1_STRING_TABLE_add.pod +++ b/doc/man3/ASN1_STRING_TABLE_add.pod @@ -13,7 +13,7 @@ ASN1_STRING_TABLE_cleanup - ASN1_STRING_TABLE manipulation functions int ASN1_STRING_TABLE_add(int nid, long minsize, long maxsize, unsigned long mask, unsigned long flags); - ASN1_STRING_TABLE * ASN1_STRING_TABLE_get(int nid); + ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); void ASN1_STRING_TABLE_cleanup(void); =head1 DESCRIPTION @@ -55,7 +55,7 @@ L =head1 COPYRIGHT -Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/ASN1_STRING_length.pod b/doc/man3/ASN1_STRING_length.pod index ae03dd97..e3cf8bb2 100644 --- a/doc/man3/ASN1_STRING_length.pod +++ b/doc/man3/ASN1_STRING_length.pod @@ -11,10 +11,10 @@ ASN1_STRING_to_UTF8 - ASN1_STRING utility functions #include int ASN1_STRING_length(ASN1_STRING *x); - const unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x); - unsigned char * ASN1_STRING_data(ASN1_STRING *x); + const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); + unsigned char *ASN1_STRING_data(ASN1_STRING *x); - ASN1_STRING * ASN1_STRING_dup(const ASN1_STRING *a); + ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a); int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b); @@ -103,7 +103,7 @@ L =head1 COPYRIGHT -Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/ASN1_STRING_new.pod b/doc/man3/ASN1_STRING_new.pod index 581d3f6e..ff20de73 100644 --- a/doc/man3/ASN1_STRING_new.pod +++ b/doc/man3/ASN1_STRING_new.pod @@ -9,8 +9,8 @@ ASN1_STRING allocation functions #include - ASN1_STRING * ASN1_STRING_new(void); - ASN1_STRING * ASN1_STRING_type_new(int type); + ASN1_STRING *ASN1_STRING_new(void); + ASN1_STRING *ASN1_STRING_type_new(int type); void ASN1_STRING_free(ASN1_STRING *a); =head1 DESCRIPTION @@ -42,7 +42,7 @@ L =head1 COPYRIGHT -Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/BIO_f_ssl.pod b/doc/man3/BIO_f_ssl.pod index 6b896e2a..8bbbb043 100644 --- a/doc/man3/BIO_f_ssl.pod +++ b/doc/man3/BIO_f_ssl.pod @@ -96,12 +96,15 @@ chain and calling SSL_shutdown() on its internal SSL pointer. BIO_do_handshake() attempts to complete an SSL handshake on the -supplied BIO and establish the SSL connection. It returns 1 -if the connection was established successfully. A zero or negative -value is returned if the connection could not be established, the -call BIO_should_retry() should be used for non blocking connect BIOs -to determine if the call should be retried. If an SSL connection has -already been established this call has no effect. +-supplied BIO and establish the SSL connection. +For non-SSL BIOs the connection is done typically at TCP level. +If domain name resolution yields multiple IP addresses all of them are tried +after connect() failures. +The function returns 1 if the connection was established successfully. +A zero or negative value is returned if the connection could not be established. +The call BIO_should_retry() should be used for non-blocking connect BIOs +to determine if the call should be retried. +If a connection has already been established this call has no effect. =head1 NOTES diff --git a/doc/man3/BIO_s_connect.pod b/doc/man3/BIO_s_connect.pod index 24f11206..d5a909dc 100644 --- a/doc/man3/BIO_s_connect.pod +++ b/doc/man3/BIO_s_connect.pod @@ -94,11 +94,16 @@ non blocking I/O is set during the connect process. BIO_new_connect() combines BIO_new() and BIO_set_conn_hostname() into a single call: that is it creates a new connect BIO with B. -BIO_do_connect() attempts to connect the supplied BIO. It returns 1 -if the connection was established successfully. A zero or negative -value is returned if the connection could not be established, the -call BIO_should_retry() should be used for non blocking connect BIOs +BIO_do_connect() attempts to connect the supplied BIO. +This performs an SSL/TLS handshake as far as supported by the BIO. +For non-SSL BIOs the connection is done typically at TCP level. +If domain name resolution yields multiple IP addresses all of them are tried +after connect() failures. +The function returns 1 if the connection was established successfully. +A zero or negative value is returned if the connection could not be established. +The call BIO_should_retry() should be used for non blocking connect BIOs to determine if the call should be retried. +If a connection has already been established this call has no effect. =head1 NOTES diff --git a/doc/man3/BIO_set_callback.pod b/doc/man3/BIO_set_callback.pod index eb329f52..f7aaa7a1 100644 --- a/doc/man3/BIO_set_callback.pod +++ b/doc/man3/BIO_set_callback.pod @@ -48,7 +48,7 @@ out information relating to each BIO operation. If the callback argument is set it is interpreted as a BIO to send the information to, otherwise stderr is used. -BIO_callback_fn_ex is the type of the callback function and BIO_callback_fn +BIO_callback_fn_ex() is the type of the callback function and BIO_callback_fn() is the type of the old format callback function. The meaning of each argument is described below: diff --git a/doc/man3/BIO_socket_wait.pod b/doc/man3/BIO_socket_wait.pod deleted file mode 100644 index d105dfe6..00000000 --- a/doc/man3/BIO_socket_wait.pod +++ /dev/null @@ -1,58 +0,0 @@ -=pod - -=head1 NAME - -BIO_socket_wait, -BIO_wait, -BIO_connect_retry -- BIO socket utility functions - -=head1 SYNOPSIS - - #include - - #ifndef OPENSSL_NO_SOCK - int BIO_socket_wait(int fd, int for_read, time_t max_time); - #endif - int BIO_wait(BIO *bio, time_t max_time, unsigned int milliseconds); - int BIO_connect_retry(BIO *bio, long timeout); - -=head1 DESCRIPTION - -BIO_socket_wait() waits on the socket B for reading if B is not 0, -else for writing, at most until B. -It succeeds immediately if B == 0 (which means no timeout given). - -BIO_wait() waits at most until B on the given B, -which is typically socket-based, -for reading if B is supposed to read, else for writing. -It succeeds immediately if B == 0 (which means no timeout given). -If sockets are not available it succeeds after waiting at most given -B in order to help avoiding a tight busy loop at the caller. - -BIO_connect_retry() connects via the given B, retrying BIO_do_connect() -until success or a timeout or error condition is reached. -If the B parameter is > 0 this indicates the maximum number of seconds -to wait until the connection is established. A value of 0 enables waiting -indefinitely, while a value < 0 immediately leads to a timeout condition. - -=head1 RETURN VALUES - -BIO_socket_wait(), BIO_wait(), and BIO_connect_retry() -return -1 on error, 0 on timeout, and 1 on success. - -=head1 HISTORY - -BIO_socket_wait(), BIO_wait(), and BIO_connect_retry() -were added in OpenSSL 3.0. - -=head1 COPYRIGHT - -Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the Apache License 2.0 (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/doc/man3/CMS_verify.pod b/doc/man3/CMS_verify.pod index 159c378b..ed289b1a 100644 --- a/doc/man3/CMS_verify.pod +++ b/doc/man3/CMS_verify.pod @@ -66,10 +66,14 @@ from the content. If the content is not of type B then an error is returned. If B is set the signing certificates are not -verified. +verified, unless CMS_CADES flag is also set. If B is set the signed attributes signature is not -verified. +verified, unless CMS_CADES flag is also set. + +If B is set, each signer certificate is checked against the +"ESS signing-certificate" extension added in the signed attributes of the +signature. If B is set then the content digest is not checked. @@ -122,7 +126,7 @@ L, L =head1 COPYRIGHT -Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/CRYPTO_get_ex_new_index.pod b/doc/man3/CRYPTO_get_ex_new_index.pod index e569a3d5..fcedd0ec 100644 --- a/doc/man3/CRYPTO_get_ex_new_index.pod +++ b/doc/man3/CRYPTO_get_ex_new_index.pod @@ -23,7 +23,7 @@ CRYPTO_free_ex_data, CRYPTO_new_ex_data typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp); typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, - void *from_d, int idx, long argl, void *argp); + void **from_d, int idx, long argl, void *argp); int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) @@ -140,10 +140,8 @@ dup_func() is called when a structure is being copied. This is only done for B, B, B objects and B chains via BIO_dup_chain(). The B and B parameters are pointers to the destination and source B structures, -respectively. The B parameter needs to be cast to a B -as the API has currently the wrong signature; that will be changed in a -future version. The B<*pptr> is a pointer to the source exdata. -When the dup_func() returns, the value in B<*pptr> is copied to the +respectively. The B<*from_d> parameter is a pointer to the source exdata. +When the dup_func() returns, the value in B<*from_d> is copied to the destination ex_data. If the pointer contained in B<*pptr> is not modified by the dup_func(), then both B and B will point to the same data. The B, B and B parameters are as described for the other @@ -165,6 +163,8 @@ dup_func() should return 0 for failure and 1 for success. =head1 HISTORY CRYPTO_alloc_ex_data() was added in OpenSSL 3.0. +The signature of the dup_func() callback was changed in OpenSSL 3.0 to use the +type B for B. Previously this parameter was of type B. =head1 COPYRIGHT diff --git a/doc/man3/EC_GFp_simple_method.pod b/doc/man3/EC_GFp_simple_method.pod index 4d8f1fba..eec721ed 100644 --- a/doc/man3/EC_GFp_simple_method.pod +++ b/doc/man3/EC_GFp_simple_method.pod @@ -8,6 +8,8 @@ EC_GFp_simple_method, EC_GFp_mont_method, EC_GFp_nist_method, EC_GFp_nistp224_me #include +Deprecated since OpenSSL 3.0: + const EC_METHOD *EC_GFp_simple_method(void); const EC_METHOD *EC_GFp_mont_method(void); const EC_METHOD *EC_GFp_nist_method(void); @@ -21,6 +23,10 @@ EC_GFp_simple_method, EC_GFp_mont_method, EC_GFp_nist_method, EC_GFp_nistp224_me =head1 DESCRIPTION + +All const EC_METHOD *EC_GF* functions were deprecated in OpenSSL 3.0, since +EC_METHOD is no longer a public concept. + The Elliptic Curve library provides a number of different implementations through a single common interface. When constructing a curve using EC_GROUP_new (see L) an implementation method must be provided. The functions described here all return a const pointer to an @@ -39,10 +45,8 @@ The functions EC_GFp_nistp224_method, EC_GFp_nistp256_method and EC_GFp_nistp521 optimised implementations for the NIST P224, P256 and P521 curves respectively. Note, however, that these implementations are not available on all platforms. -EC_METHOD_get_field_type identifies what type of field the EC_METHOD structure supports, which will be either -F2^m or Fp. If the field type is Fp then the value B is returned. If the field type is -F2^m then the value B is returned. These values are defined in the -obj_mac.h header file. +EC_METHOD_get_field_type() was deprecated in OpenSSL 3.0. +Applications should use EC_GROUP_get_field_type() as a replacement (see L). =head1 RETURN VALUES @@ -57,9 +61,17 @@ L, L, L, L, L +=head1 HISTORY + +EC_GFp_simple_method(), EC_GFp_mont_method(void), +EC_GFp_nist_method(), EC_GFp_nistp224_method(), +EC_GFp_nistp256_method(), EC_GFp_nistp521_method(), +EC_GF2m_simple_method(), and EC_METHOD_get_field_type() +were deprecated in OpenSSL 3.0. + =head1 COPYRIGHT -Copyright 2013-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EC_GROUP_copy.pod b/doc/man3/EC_GROUP_copy.pod index e9a1d183..ee3ce27b 100644 --- a/doc/man3/EC_GROUP_copy.pod +++ b/doc/man3/EC_GROUP_copy.pod @@ -22,8 +22,6 @@ EC_GROUP_get_pentanomial_basis, EC_GROUP_get0_field int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src); EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); - const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); - int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor); const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); @@ -63,6 +61,10 @@ EC_GROUP_get_pentanomial_basis, EC_GROUP_get0_field int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, unsigned int *k2, unsigned int *k3); +Deprecated since OpenSSL 3.0: + + const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + =head1 DESCRIPTION EC_GROUP_copy() copies the curve B into B. Both B and B must use the same EC_METHOD. @@ -71,6 +73,7 @@ EC_GROUP_dup() creates a new EC_GROUP object and copies the content from B EC_GROUP object. EC_GROUP_method_of() obtains the EC_METHOD of B. +This function was deprecated in OpenSSL 3.0, since EC_METHOD is no longer a public concept. EC_GROUP_set_generator() sets curve parameters that must be agreed by all participants using the curve. These parameters include the B, the B and the B. The B is a well defined point on the @@ -140,8 +143,12 @@ built-in curves within the library provide seed values that can be obtained. It EC_GROUP_set_seed() and passing a pointer to a memory block, along with the length of the seed. Again, the EC library will not use this seed value, although it will be preserved in any ASN1 based communications. -EC_GROUP_get_degree() gets the degree of the field. For Fp fields this will be the number of bits in p. For F2^m fields this will be -the value m. +EC_GROUP_get_degree() gets the degree of the field. +For Fp fields this will be the number of bits in p. +For F2^m fields this will be the value m. + +EC_GROUP_get_field_type() identifies what type of field the EC_GROUP structure supports, +which will be either F2^m or Fp. The function EC_GROUP_check_discriminant() calculates the discriminant for the curve and verifies that it is valid. For a curve defined over Fp the discriminant is given by the formula 4*a^3 + 27*b^2 whilst for F2^m curves the discriminant is @@ -202,6 +209,10 @@ EC_GROUP_get_point_conversion_form() returns the point_conversion_form for B or 0 if the operation is not supported by the underlying group implementation. +EC_GROUP_get_field_type() returns either B for prime curves +or B for binary curves; +these values are defined in the obj_mac.h header file. + EC_GROUP_check_named_curve() returns the nid of the matching named curve, otherwise it returns 0 for no match, or -1 on error. EC_GROUP_get0_order() returns an internal pointer to the group order. @@ -229,11 +240,13 @@ L, L =head1 HISTORY -The EC_GROUP_check_named_curve() function was added in OpenSSL 3.0. +EC_GROUP_method_of() was deprecated in OpenSSL 3.0. + +EC_GROUP_check_named_curve() and EC_GROUP_get_field_type() were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2013-2019 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EC_GROUP_new.pod b/doc/man3/EC_GROUP_new.pod index 08bbd80b..fa612758 100644 --- a/doc/man3/EC_GROUP_new.pod +++ b/doc/man3/EC_GROUP_new.pod @@ -4,7 +4,6 @@ EC_GROUP_get_ecparameters, EC_GROUP_get_ecpkparameters, -EC_GROUP_new_ex, EC_GROUP_new, EC_GROUP_new_from_ecparameters, EC_GROUP_new_from_ecpkparameters, @@ -27,8 +26,6 @@ objects #include - EC_GROUP *EC_GROUP_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth); - EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); EC_GROUP *EC_GROUP_new_from_ecparameters(const ECPARAMETERS *params) EC_GROUP *EC_GROUP_new_from_ecpkparameters(const ECPKPARAMETERS *params) void EC_GROUP_free(EC_GROUP *group); @@ -62,6 +59,7 @@ Deprecated since OpenSSL 3.0, can be hidden entirely by defining B with a suitable version value, see L: + EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); void EC_GROUP_clear_free(EC_GROUP *group); =head1 DESCRIPTION @@ -83,20 +81,20 @@ Operations in a binary field are performed relative to an B. All such curves with OpenSSL use a trinomial or a pentanomial for this parameter. -A new curve can be constructed by calling EC_GROUP_new_ex(), using the +Although deprecated since OpenSSL 3.0 and should no longer be used, +a new curve can be constructed by calling EC_GROUP_new(), using the implementation provided by B (see L) and associated with the library context B (see L). The B parameter may be NULL in which case the default library context is used. It is then necessary to call EC_GROUP_set_curve() to set the curve parameters. +Applications should instead use one of the other EC_GROUP_new_* constructors. + EC_GROUP_new_from_ecparameters() will create a group from the specified B and EC_GROUP_new_from_ecpkparameters() will create a group from the specific PK B. -EC_GROUP_new() is the same as EC_GROUP_new_ex() except that the library context -used is always the default library context. - EC_GROUP_set_curve() sets the curve parameters B

, B and B. For a curve over Fp B

is the prime for the field. For a curve over F2^m B

represents the irreducible polynomial - each bit represents a term in the polynomial. @@ -182,7 +180,9 @@ L =item * -EC_GROUP_new_ex() and EC_GROUP_new_by_curve_name_ex() were added in OpenSSL 3.0. +EC_GROUP_new() was deprecated in OpenSSL 3.0. + +EC_GROUP_new_by_curve_name_ex() was added in OpenSSL 3.0. =item * @@ -193,7 +193,7 @@ instead. =head1 COPYRIGHT -Copyright 2013-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EC_KEY_new.pod b/doc/man3/EC_KEY_new.pod index ff4373ea..04ad740b 100644 --- a/doc/man3/EC_KEY_new.pod +++ b/doc/man3/EC_KEY_new.pod @@ -40,7 +40,6 @@ EC_KEY objects point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform); void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); - int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); int EC_KEY_generate_key(EC_KEY *key); int EC_KEY_check_key(const EC_KEY *key); int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, BIGNUM *y); @@ -56,6 +55,10 @@ EC_KEY objects size_t EC_KEY_priv2buf(const EC_KEY *eckey, unsigned char **pbuf); +Deprecated since OpenSSL 3.0: + + int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); + =head1 DESCRIPTION An EC_KEY represents a public key and, optionally, the associated private @@ -136,11 +139,14 @@ EC_KEY_set_asn1_flag() sets the asn1_flag on the underlying EC_GROUP object (if set). Refer to L for further information on the asn1_flag. +Although deprecated in OpenSSL 3.0 and should no longer be used, EC_KEY_precompute_mult() stores multiples of the underlying EC_GROUP generator for faster point multiplication. See also L. +Modern versions should instead switch to named curves which OpenSSL has +hardcoded lookup tables for. EC_KEY_oct2key() and EC_KEY_key2buf() are identical to the functions -EC_POINT_oct2point() and EC_KEY_point2buf() except they use the public key +EC_POINT_oct2point() and EC_POINT_point2buf() except they use the public key EC_POINT in B. EC_KEY_oct2priv() and EC_KEY_priv2oct() convert between the private key @@ -195,9 +201,13 @@ L, L, L +=head1 HISTORY + +EC_KEY_precompute_mult() was deprecated in OpenSSL 3.0. + =head1 COPYRIGHT -Copyright 2013-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EC_POINT_add.pod b/doc/man3/EC_POINT_add.pod index 3ac567f8..b276be46 100644 --- a/doc/man3/EC_POINT_add.pod +++ b/doc/man3/EC_POINT_add.pod @@ -15,18 +15,18 @@ EC_POINT_add, EC_POINT_dbl, EC_POINT_invert, EC_POINT_is_at_infinity, EC_POINT_i int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx); int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); + int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); + +Deprecated since OpenSSL 3.0: + int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], BN_CTX *ctx); - int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, - const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); - int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); - int EC_GROUP_have_precompute_mult(const EC_GROUP *group); - - Deprecated since OpenSSL 3.0: - int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx); + int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); + int EC_GROUP_have_precompute_mult(const EC_GROUP *group); =head1 DESCRIPTION @@ -43,7 +43,8 @@ EC_POINT_cmp compares the two supplied points and tests whether or not they are The functions EC_POINT_make_affine and EC_POINTs_make_affine force the internal representation of the EC_POINT(s) into the affine co-ordinate system. In the case of EC_POINTs_make_affine the value B provides the number of points in the array B to be -forced. +forced. These functions were deprecated in OpenSSL 3.0 and should no longer be used. +Modern versions automatically perform this conversion when needed. EC_POINT_mul calculates the value generator * B + B * B and stores the result in B. The value B may be NULL in which case the result is just B * B (variable point multiplication). Alternatively, both B and B may be NULL, and B non-NULL, in which case the result is just generator * B (fixed point multiplication). @@ -56,8 +57,9 @@ Modern versions should instead use EC_POINT_mul(), combined (if needed) with EC_ The function EC_GROUP_precompute_mult stores multiples of the generator for faster point multiplication, whilst EC_GROUP_have_precompute_mult tests whether precomputation has already been done. See L for information -about the generator. - +about the generator. Precomputation functionality was deprecated in OpenSSL 3.0. +Users of EC_GROUP_precompute_mult() and EC_GROUP_have_precompute_mult() should +switch to named curves which OpenSSL has hardcoded lookup tables for. =head1 RETURN VALUES @@ -80,11 +82,13 @@ L, L =head1 HISTORY -EC_POINTs_mul() was deprecated in OpenSSL 3.0. +EC_POINT_make_affine(), EC_POINTs_make_affine(), EC_POINTs_mul(), +EC_GROUP_precompute_mult(), and EC_GROUP_have_precompute_mult() +were deprecated in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2013-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2013-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EC_POINT_new.pod b/doc/man3/EC_POINT_new.pod index ab02d607..84b11ee0 100644 --- a/doc/man3/EC_POINT_new.pod +++ b/doc/man3/EC_POINT_new.pod @@ -38,7 +38,6 @@ EC_POINT_hex2point void EC_POINT_clear_free(EC_POINT *point); int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); - const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *p, const BIGNUM *x, const BIGNUM *y, @@ -68,6 +67,7 @@ EC_POINT_hex2point Deprecated since OpenSSL 3.0: + const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, const BIGNUM *x, const BIGNUM *y, @@ -116,6 +116,8 @@ EC_POINT_dup() creates a new B object and copies the content from B to the newly created B object. EC_POINT_method_of() obtains the B associated with B. +This function was deprecated in OpenSSL 3.0, since EC_METHOD is no longer a +public concept. A valid point on a curve is the special point at infinity. A point is set to be at infinity by calling EC_POINT_set_to_infinity(). @@ -249,6 +251,7 @@ L, L =head1 HISTORY +EC_POINT_method_of(), EC_POINT_set_Jprojective_coordinates_GFp(), EC_POINT_get_Jprojective_coordinates_GFp(), EC_POINT_set_affine_coordinates_GFp(), EC_POINT_get_affine_coordinates_GFp(), diff --git a/doc/man3/EVP_EncryptInit.pod b/doc/man3/EVP_EncryptInit.pod index ad4297df..88d0e7da 100644 --- a/doc/man3/EVP_EncryptInit.pod +++ b/doc/man3/EVP_EncryptInit.pod @@ -770,7 +770,7 @@ with a 128-bit key: /* Don't set key or IV right away; we want to check lengths */ ctx = EVP_CIPHER_CTX_new(); - EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, NULL, NULL, + EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, NULL, NULL, do_encrypt); OPENSSL_assert(EVP_CIPHER_CTX_key_length(ctx) == 16); OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == 16); diff --git a/doc/man3/EVP_KDF.pod b/doc/man3/EVP_KDF.pod index 2d7fe49c..7d6228a7 100644 --- a/doc/man3/EVP_KDF.pod +++ b/doc/man3/EVP_KDF.pod @@ -3,11 +3,11 @@ =head1 NAME EVP_KDF, EVP_KDF_fetch, EVP_KDF_free, EVP_KDF_up_ref, -EVP_KDF_CTX, EVP_KDF_CTX_new, EVP_KDF_CTX_free, EVP_KDF_CTX_dup, +EVP_KDF_CTX, EVP_KDF_new_ctx, EVP_KDF_free_ctx, EVP_KDF_dup_ctx, EVP_KDF_reset, EVP_KDF_derive, -EVP_KDF_size, EVP_KDF_provider, EVP_KDF_CTX_kdf, EVP_KDF_is_a, +EVP_KDF_size, EVP_KDF_provider, EVP_KDF_get_ctx_kdf, EVP_KDF_is_a, EVP_KDF_number, EVP_KDF_names_do_all, -EVP_KDF_CTX_get_params, EVP_KDF_CTX_set_params, EVP_KDF_do_all_provided, +EVP_KDF_get_ctx_params, EVP_KDF_set_ctx_params, EVP_KDF_do_all_provided, EVP_KDF_get_params, EVP_KDF_gettable_ctx_params, EVP_KDF_settable_ctx_params, EVP_KDF_gettable_params - EVP KDF routines @@ -18,10 +18,10 @@ EVP_KDF_gettable_params - EVP KDF routines typedef struct evp_kdf_st EVP_KDF; typedef struct evp_kdf_ctx_st EVP_KDF_CTX; - EVP_KDF_CTX *EVP_KDF_CTX_new(const EVP_KDF *kdf); - const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx); - void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx); - EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src); + EVP_KDF_CTX *EVP_KDF_new_ctx(const EVP_KDF *kdf); + const EVP_KDF *EVP_KDF_get_ctx_kdf(EVP_KDF_CTX *ctx); + void EVP_KDF_free_ctx(EVP_KDF_CTX *ctx); + EVP_KDF_CTX *EVP_KDF_dup_ctx(const EVP_KDF_CTX *src); void EVP_KDF_reset(EVP_KDF_CTX *ctx); size_t EVP_KDF_size(EVP_KDF_CTX *ctx); int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen); @@ -39,8 +39,8 @@ EVP_KDF_gettable_params - EVP KDF routines void (*fn)(const char *name, void *data), void *data); int EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[]); - int EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]); - int EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]); + int EVP_KDF_get_ctx_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]); + int EVP_KDF_set_ctx_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]); const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf); const OSSL_PARAM *EVP_KDF_gettable_ctx_params(const EVP_KDF *kdf); const OSSL_PARAM *EVP_KDF_settable_ctx_params(const EVP_KDF *kdf); @@ -52,8 +52,8 @@ The EVP KDF routines are a high level interface to Key Derivation Function algorithms and should be used instead of algorithm-specific functions. After creating a B for the required algorithm using -EVP_KDF_CTX_new(), inputs to the algorithm are supplied -using calls to EVP_KDF_CTX_set_params() before +EVP_KDF_new_ctx(), inputs to the algorithm are supplied +using calls to EVP_KDF_set_ctx_params() before calling EVP_KDF_derive() to derive the key. =head2 Types @@ -68,6 +68,9 @@ EVP_KDF_fetch() fetches an implementation of a KDF I, given a library context I and a set of I. See L for further information. +See L for the lists of +algorithms supported by the default provider. + The returned value must eventually be freed with L. @@ -79,12 +82,12 @@ NULL is a valid parameter, for which this function is a no-op. =head2 Context manipulation functions -EVP_KDF_CTX_new() creates a new context for the KDF implementation I. +EVP_KDF_new_ctx() creates a new context for the KDF implementation I. -EVP_KDF_CTX_free() frees up the context I. If I is NULL, nothing +EVP_KDF_free_ctx() frees up the context I. If I is NULL, nothing is done. -EVP_KDF_CTX_kdf() returns the B associated with the context +EVP_KDF_get_ctx_kdf() returns the B associated with the context I. =head2 Computing functions @@ -104,14 +107,14 @@ parameters should be retrieved. Note that a parameter that is unknown in the underlying context is simply ignored. -EVP_KDF_CTX_get_params() retrieves chosen parameters, given the +EVP_KDF_get_ctx_params() retrieves chosen parameters, given the context I and its underlying context. The set of parameters given with I determine exactly what parameters should be retrieved. Note that a parameter that is unknown in the underlying context is simply ignored. -EVP_KDF_CTX_set_params() passes chosen parameters to the underlying +EVP_KDF_set_ctx_params() passes chosen parameters to the underlying context, given a context I. The set of parameters given with I determine exactly what parameters are passed down. @@ -123,8 +126,8 @@ defined by the implementation. EVP_KDF_gettable_params(), EVP_KDF_gettable_ctx_params() and EVP_KDF_settable_ctx_params() get a constant B array that describes the retrievable and settable parameters, i.e. parameters that -can be used with EVP_KDF_get_params(), EVP_KDF_CTX_get_params() -and EVP_KDF_CTX_set_params(), respectively. +can be used with EVP_KDF_get_params(), EVP_KDF_get_ctx_params() +and EVP_KDF_set_ctx_params(), respectively. See L for the use of B as parameter descriptor. =head2 Information functions @@ -234,10 +237,10 @@ NULL on error. EVP_KDF_up_ref() returns 1 on success, 0 on error. -EVP_KDF_CTX_new() returns either the newly allocated +EVP_KDF_new_ctx() returns either the newly allocated B structure or NULL if an error occurred. -EVP_KDF_CTX_free() and EVP_KDF_reset() do not return a value. +EVP_KDF_free_ctx() and EVP_KDF_reset() do not return a value. EVP_KDF_size() returns the output size. B is returned to indicate that the algorithm produces a variable amount of output; 0 to indicate failure. @@ -248,14 +251,7 @@ supported by the KDF algorithm. =head1 SEE ALSO -L -L -L -L -L -L -L -L +L =head1 HISTORY @@ -263,7 +259,7 @@ This functionality was added to OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EVP_MAC.pod b/doc/man3/EVP_MAC.pod index 1b961d49..14645154 100644 --- a/doc/man3/EVP_MAC.pod +++ b/doc/man3/EVP_MAC.pod @@ -5,8 +5,8 @@ EVP_MAC, EVP_MAC_fetch, EVP_MAC_up_ref, EVP_MAC_free, EVP_MAC_is_a, EVP_MAC_number, EVP_MAC_names_do_all, EVP_MAC_provider, EVP_MAC_get_params, EVP_MAC_gettable_params, -EVP_MAC_CTX, EVP_MAC_CTX_new, EVP_MAC_CTX_free, EVP_MAC_CTX_dup, -EVP_MAC_CTX_mac, EVP_MAC_CTX_get_params, EVP_MAC_CTX_set_params, +EVP_MAC_CTX, EVP_MAC_new_ctx, EVP_MAC_free_ctx, EVP_MAC_dup_ctx, +EVP_MAC_get_ctx_mac, EVP_MAC_get_ctx_params, EVP_MAC_set_ctx_params, EVP_MAC_size, EVP_MAC_init, EVP_MAC_update, EVP_MAC_final, EVP_MAC_gettable_ctx_params, EVP_MAC_settable_ctx_params, EVP_MAC_do_all_provided - EVP MAC routines @@ -30,12 +30,12 @@ EVP_MAC_do_all_provided - EVP MAC routines const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac); int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]); - EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac); - void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx); - EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src); - EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx); - int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]); - int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]); + EVP_MAC_CTX *EVP_MAC_new_ctx(EVP_MAC *mac); + void EVP_MAC_free_ctx(EVP_MAC_CTX *ctx); + EVP_MAC_CTX *EVP_MAC_dup_ctx(const EVP_MAC_CTX *src); + EVP_MAC *EVP_MAC_get_ctx_mac(EVP_MAC_CTX *ctx); + int EVP_MAC_get_ctx_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]); + int EVP_MAC_set_ctx_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]); size_t EVP_MAC_size(EVP_MAC_CTX *ctx); int EVP_MAC_init(EVP_MAC_CTX *ctx); @@ -82,6 +82,9 @@ EVP_MAC_fetch() fetches an implementation of a MAC I, given a library context I and a set of I. See L for further information. +See L for the list +of algorithms supported by the default provider. + The returned value must eventually be freed with L. @@ -93,18 +96,18 @@ NULL is a valid parameter, for which this function is a no-op. =head2 Context manipulation functions -EVP_MAC_CTX_new() creates a new context for the MAC type I. +EVP_MAC_new_ctx() creates a new context for the MAC type I. The created context can then be used with most other functions described here. -EVP_MAC_CTX_free() frees the contents of the context, including an +EVP_MAC_free_ctx() frees the contents of the context, including an underlying context if there is one, as well as the context itself. NULL is a valid parameter, for which this function is a no-op. -EVP_MAC_CTX_dup() duplicates the I context and returns a newly allocated +EVP_MAC_dup_ctx() duplicates the I context and returns a newly allocated context. -EVP_MAC_CTX_mac() returns the B associated with the context +EVP_MAC_get_ctx_mac() returns the B associated with the context I. =head2 Computing functions @@ -133,14 +136,14 @@ parameters should be retrieved. Note that a parameter that is unknown in the underlying context is simply ignored. -EVP_MAC_CTX_get_params() retrieves chosen parameters, given the +EVP_MAC_get_ctx_params() retrieves chosen parameters, given the context I and its underlying context. The set of parameters given with I determine exactly what parameters should be retrieved. Note that a parameter that is unknown in the underlying context is simply ignored. -EVP_MAC_CTX_set_params() passes chosen parameters to the underlying +EVP_MAC_set_ctx_params() passes chosen parameters to the underlying context, given a context I. The set of parameters given with I determine exactly what parameters are passed down. @@ -152,8 +155,8 @@ defined by the implementation. EVP_MAC_gettable_params(), EVP_MAC_gettable_ctx_params() and EVP_MAC_settable_ctx_params() get a constant B array that describes the retrievable and settable parameters, i.e. parameters that -can be used with EVP_MAC_get_params(), EVP_MAC_CTX_get_params() -and EVP_MAC_CTX_set_params(), respectively. +can be used with EVP_MAC_get_params(), EVP_MAC_get_ctx_params() +and EVP_MAC_set_ctx_params(), respectively. See L for the use of B as parameter descriptor. =head2 Information functions @@ -267,12 +270,12 @@ the given name, otherwise 0. EVP_MAC_provider() returns a pointer to the provider for the MAC, or NULL on error. -EVP_MAC_CTX_new() and EVP_MAC_CTX_dup() return a pointer to a newly +EVP_MAC_new_ctx() and EVP_MAC_dup_ctx() return a pointer to a newly created EVP_MAC_CTX, or NULL if allocation failed. -EVP_MAC_CTX_free() returns nothing at all. +EVP_MAC_free_ctx() returns nothing at all. -EVP_MAC_CTX_get_params() and EVP_MAC_CTX_set_params() return 1 on +EVP_MAC_get_ctx_params() and EVP_MAC_set_ctx_params() return 1 on success, 0 on error. EVP_MAC_init(), EVP_MAC_update(), and EVP_MAC_final() return 1 on success, 0 @@ -324,8 +327,8 @@ EVP_MAC_do_all_provided() returns nothing at all. if (mac == NULL || key == NULL - || (ctx = EVP_MAC_CTX_new(mac)) == NULL - || EVP_MAC_CTX_set_params(ctx, params) <= 0) + || (ctx = EVP_MAC_new_ctx(mac)) == NULL + || EVP_MAC_set_ctx_params(ctx, params) <= 0) goto err; if (!EVP_MAC_init(ctx)) @@ -344,12 +347,12 @@ EVP_MAC_do_all_provided() returns nothing at all. printf("%02X", buf[i]); printf("\n"); - EVP_MAC_CTX_free(ctx); + EVP_MAC_free_ctx(ctx); EVP_MAC_free(mac); exit(0); err: - EVP_MAC_CTX_free(ctx); + EVP_MAC_free_ctx(ctx); EVP_MAC_free(mac); fprintf(stderr, "Something went wrong\n"); ERR_print_errors_fp(stderr); diff --git a/doc/man3/EVP_PKEY_ASN1_METHOD.pod b/doc/man3/EVP_PKEY_ASN1_METHOD.pod index ed44749c..bc1f1ad0 100644 --- a/doc/man3/EVP_PKEY_ASN1_METHOD.pod +++ b/doc/man3/EVP_PKEY_ASN1_METHOD.pod @@ -43,7 +43,7 @@ EVP_PKEY_get0_asn1 void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, int (*pub_decode) (EVP_PKEY *pk, - X509_PUBKEY *pub), + const X509_PUBKEY *pub), int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk), int (*pub_cmp) (const EVP_PKEY *a, @@ -170,7 +170,7 @@ They're called by L and L. The pub_cmp() method is called when two public keys are to be compared. It MUST return 1 when the keys are equal, 0 otherwise. -It's called by L. +It's called by L. The pub_print() method is called to print a public key in humanly readable text to B, indented B spaces. @@ -228,7 +228,7 @@ It's called by L. The param_cmp() method compares the parameters of keys B and B. It MUST return 1 when the keys are equal, 0 when not equal, or a negative number on error. -It's called by L. +It's called by L. The param_print() method prints the private key parameters in humanly readable text to B, indented B spaces. @@ -434,7 +434,7 @@ B object otherwise. =head1 COPYRIGHT -Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EVP_PKEY_CTX_ctrl.pod b/doc/man3/EVP_PKEY_CTX_ctrl.pod index 039073ca..db91f010 100644 --- a/doc/man3/EVP_PKEY_CTX_ctrl.pod +++ b/doc/man3/EVP_PKEY_CTX_ctrl.pod @@ -2,10 +2,6 @@ =head1 NAME -EVP_PKEY_CTX_get_params, -EVP_PKEY_CTX_gettable_params, -EVP_PKEY_CTX_set_params, -EVP_PKEY_CTX_settable_params, EVP_PKEY_CTX_ctrl, EVP_PKEY_CTX_ctrl_str, EVP_PKEY_CTX_ctrl_uint64, @@ -78,11 +74,6 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len #include - int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params); - const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx); - int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params); - const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx); - int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, int p1, void *p2); int EVP_PKEY_CTX_ctrl_uint64(EVP_PKEY_CTX *ctx, int keytype, int optype, @@ -186,49 +177,6 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len =head1 DESCRIPTION -The EVP_PKEY_CTX_get_params() and EVP_PKEY_CTX_set_params() functions get and -send arbitrary parameters from and to the algorithm implementation respectively. -Not all parameters may be supported by all providers. -See L for more information on providers. -See L for more information on parameters. -These functions must only be called after the EVP_PKEY_CTX has been initialised -for use in an operation. - -The parameters currently supported by the default provider are: - -=over 4 - -=item "pad" (B) - -Sets the DH padding mode. -If B is 1 then the shared secret is padded with zeros -up to the size of the DH prime I

. -If B is zero (the default) then no padding is -performed. - -=item "digest" (B) - -Gets and sets the name of the digest algorithm used for the input to the -signature functions. - -=item "digest-size" (B) - -Gets and sets the output size of the digest algorithm used for the input to the -signature functions. -The length of the "digest-size" parameter should not exceed that of a B. -The internal algorithm that supports this parameter is DSA. - -=back - -EVP_PKEY_CTX_gettable_params() and EVP_PKEY_CTX_settable_params() gets a -constant B array that describes the gettable and -settable parameters for the current algorithm implementation, i.e. parameters -that can be used with EVP_PKEY_CTX_get_params() and EVP_PKEY_CTX_set_params() -respectively. -See L for the use of B as parameter descriptor. -These functions must only be called after the EVP_PKEY_CTX has been initialised -for use in an operation. - The function EVP_PKEY_CTX_ctrl() sends a control operation to the context I. The key type used must match I if it is not -1. The parameter I is a mask indicating which operations the control can be applied to. @@ -662,17 +610,13 @@ allocate adequate memory space for the I before calling EVP_PKEY_CTX_get1_id =head1 RETURN VALUES -EVP_PKEY_CTX_set_params() returns 1 for success or 0 otherwise. -EVP_PKEY_CTX_settable_params() returns an OSSL_PARAM array on success or NULL on -error. -It may also return NULL if there are no settable parameters available. - All other functions and macros described on this page return a positive value for success and 0 or a negative value for failure. In particular a return value of -2 indicates the operation is not supported by the public key algorithm. =head1 SEE ALSO +L, L, L, L, diff --git a/doc/man3/EVP_PKEY_CTX_new.pod b/doc/man3/EVP_PKEY_CTX_new.pod index b1f3185b..4430967d 100644 --- a/doc/man3/EVP_PKEY_CTX_new.pod +++ b/doc/man3/EVP_PKEY_CTX_new.pod @@ -16,7 +16,8 @@ EVP_PKEY_CTX_new_from_pkey, EVP_PKEY_CTX_dup, EVP_PKEY_CTX_free const char *name, const char *propquery); EVP_PKEY_CTX *EVP_PKEY_CTX_new_from_pkey(OPENSSL_CTX *libctx, - EVP_PKEY *pkey); + EVP_PKEY *pkey, + const char *propquery); EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *ctx); void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); diff --git a/doc/man3/EVP_PKEY_CTX_set_params.pod b/doc/man3/EVP_PKEY_CTX_set_params.pod new file mode 100644 index 00000000..b4959c6f --- /dev/null +++ b/doc/man3/EVP_PKEY_CTX_set_params.pod @@ -0,0 +1,95 @@ +=pod + +=head1 NAME + +EVP_PKEY_CTX_set_params, +EVP_PKEY_CTX_settable_params, +EVP_PKEY_CTX_get_params, +EVP_PKEY_CTX_gettable_params +- provider parameter passing operations + +=head1 SYNOPSIS + + #include + + int EVP_PKEY_CTX_set_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params); + const OSSL_PARAM *EVP_PKEY_CTX_settable_params(EVP_PKEY_CTX *ctx); + int EVP_PKEY_CTX_get_params(EVP_PKEY_CTX *ctx, OSSL_PARAM *params); + const OSSL_PARAM *EVP_PKEY_CTX_gettable_params(EVP_PKEY_CTX *ctx); + +=head1 DESCRIPTION + +The EVP_PKEY_CTX_get_params() and EVP_PKEY_CTX_set_params() functions allow +transfer of arbitrary key parameters to and from providers. +Not all parameters may be supported by all providers. +See L for more information on providers. +See L for more information on parameters. +These functions must only be called after the EVP_PKEY_CTX has been initialised +for use in an operation. +These methods replace the EVP_PKEY_CTX_ctrl() mechanism. (EVP_PKEY_CTX_ctrl now +calls these methods internally to interact with providers). + +EVP_PKEY_CTX_gettable_params() and EVP_PKEY_CTX_settable_params() get a +constant B array that describes the gettable and +settable parameters for the current algorithm implementation, i.e. parameters +that can be used with EVP_PKEY_CTX_get_params() and EVP_PKEY_CTX_set_params() +respectively. +See L for the use of B as parameter descriptor. +These functions must only be called after the EVP_PKEY_CTX has been initialised +for use in an operation. + +=head2 Parameters + +Examples of EVP_PKEY parameters include the following: + +L +L +L + +L +L +L +L +L +L +L +L +L +L + +=head1 RETURN VALUES + +EVP_PKEY_CTX_set_params() returns 1 for success or 0 otherwise. +EVP_PKEY_CTX_settable_params() returns an OSSL_PARAM array on success or NULL on +error. +It may also return NULL if there are no settable parameters available. + +All other functions and macros described on this page return a positive value +for success and 0 or a negative value for failure. In particular a return value +of -2 indicates the operation is not supported by the public key algorithm. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +All functions were added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/EVP_PKEY_cmp.pod b/doc/man3/EVP_PKEY_copy_parameters.pod similarity index 63% rename from doc/man3/EVP_PKEY_cmp.pod rename to doc/man3/EVP_PKEY_copy_parameters.pod index f0008ec1..a3879c4e 100644 --- a/doc/man3/EVP_PKEY_cmp.pod +++ b/doc/man3/EVP_PKEY_copy_parameters.pod @@ -2,7 +2,8 @@ =head1 NAME -EVP_PKEY_copy_parameters, EVP_PKEY_missing_parameters, EVP_PKEY_cmp_parameters, +EVP_PKEY_missing_parameters, EVP_PKEY_copy_parameters, EVP_PKEY_parameters_eq, +EVP_PKEY_cmp_parameters, EVP_PKEY_eq, EVP_PKEY_cmp - public key parameter and comparison functions =head1 SYNOPSIS @@ -12,7 +13,9 @@ EVP_PKEY_cmp - public key parameter and comparison functions int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); + int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b); int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); + int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b); int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); =head1 DESCRIPTION @@ -26,11 +29,11 @@ B to key B. An error is returned if the parameters are missing in B or present in both B and B and mismatch. If the parameters in B and B are both present and match this function has no effect. -The function EVP_PKEY_cmp_parameters() compares the parameters of keys -B and B. +The function EVP_PKEY_parameters_eq() checks the parameters of keys +B and B for equality. -The function EVP_PKEY_cmp() compares the public key components and parameters -(if present) of keys B and B. +The function EVP_PKEY_eq() checks the public key components and parameters +(if present) of keys B and B for equality. =head1 NOTES @@ -40,7 +43,7 @@ parameters are sometimes omitted from a public key if they are inherited from the CA that signed it. Since OpenSSL private keys contain public key components too the function -EVP_PKEY_cmp() can also be used to determine if a private key matches +EVP_PKEY_eq() can also be used to determine if a private key matches a public key. =head1 RETURN VALUES @@ -52,8 +55,8 @@ doesn't use parameters. These functions EVP_PKEY_copy_parameters() returns 1 for success and 0 for failure. -The function EVP_PKEY_cmp_parameters() and EVP_PKEY_cmp() return 1 if the -keys match, 0 if they don't match, -1 if the key types are different and +The function EVP_PKEY_parameters_eq() and EVP_PKEY_eq() return 1 if their +inputs match, 0 if they don't match, -1 if the key types are different and -2 if the operation is not supported. =head1 SEE ALSO @@ -61,9 +64,17 @@ keys match, 0 if they don't match, -1 if the key types are different and L, L +=head1 HISTORY + +The function EVP_PKEY_cmp was deprecated and renamed to B and +EVP_PKEY_cmp_parameters was deprecated and renamed to B +(without changing semantics) in OpenSSL 3.0. +This was done to avoid confusion on their return values with other _cmp() +functions that return 0 in case their arguments are equal. + =head1 COPYRIGHT -Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EVP_PKEY_new.pod b/doc/man3/EVP_PKEY_new.pod index 3efab956..ff5744be 100644 --- a/doc/man3/EVP_PKEY_new.pod +++ b/doc/man3/EVP_PKEY_new.pod @@ -96,7 +96,8 @@ B, B, B or B. EVP_PKEY_new_CMAC_key() works in the same way as EVP_PKEY_new_raw_private_key() except it is only for the B algorithm type. In addition to the raw private key data, it also takes a cipher algorithm to be used during -creation of a CMAC in the B argument. +creation of a CMAC in the B argument. The cipher should be a standard +encryption only cipher. For example AEAD and XTS ciphers should not be used. EVP_PKEY_new_mac_key() works in the same way as EVP_PKEY_new_raw_private_key(). New applications should use EVP_PKEY_new_raw_private_key() instead. diff --git a/doc/man3/EVP_md2.pod b/doc/man3/EVP_md2.pod index a28467f5..15e37a00 100644 --- a/doc/man3/EVP_md2.pod +++ b/doc/man3/EVP_md2.pod @@ -14,7 +14,7 @@ EVP_md2 =head1 DESCRIPTION MD2 is a cryptographic hash function standardized in RFC 1319 and designed by -Ronald Rivest. +Ronald Rivest. This implementation is only available with the legacy provider. =over 4 @@ -38,6 +38,7 @@ IETF RFC 1319. =head1 SEE ALSO L, +L, L =head1 COPYRIGHT diff --git a/doc/man3/EVP_md4.pod b/doc/man3/EVP_md4.pod index 8b3874e5..21c94e91 100644 --- a/doc/man3/EVP_md4.pod +++ b/doc/man3/EVP_md4.pod @@ -14,7 +14,8 @@ EVP_md4 =head1 DESCRIPTION MD4 is a cryptographic hash function standardized in RFC 1320 and designed by -Ronald Rivest, first published in 1990. +Ronald Rivest, first published in 1990. This implementation is only available +with the legacy provider. =over 4 @@ -38,6 +39,7 @@ IETF RFC 1320. =head1 SEE ALSO L, +L, L =head1 COPYRIGHT diff --git a/doc/man3/EVP_mdc2.pod b/doc/man3/EVP_mdc2.pod index 0c9a5fa4..ecbba265 100644 --- a/doc/man3/EVP_mdc2.pod +++ b/doc/man3/EVP_mdc2.pod @@ -14,7 +14,8 @@ EVP_mdc2 =head1 DESCRIPTION MDC-2 (Modification Detection Code 2 or Meyer-Schilling) is a cryptographic -hash function based on a block cipher. +hash function based on a block cipher. This implementation is only available +with the legacy provider. =over 4 @@ -38,6 +39,7 @@ ISO/IEC 10118-2:2000 Hash-Function 2, with DES as the underlying block cipher. =head1 SEE ALSO L, +L, L =head1 COPYRIGHT diff --git a/doc/man3/EVP_ripemd160.pod b/doc/man3/EVP_ripemd160.pod index 4e9ebf73..165b84db 100644 --- a/doc/man3/EVP_ripemd160.pod +++ b/doc/man3/EVP_ripemd160.pod @@ -15,6 +15,7 @@ EVP_ripemd160 RIPEMD-160 is a cryptographic hash function first published in 1996 belonging to the RIPEMD family (RACE Integrity Primitives Evaluation Message Digest). +This implementation is only available with the legacy provider. =over 4 @@ -37,6 +38,7 @@ ISO/IEC 10118-3:2016 Dedicated Hash-Function 1 (RIPEMD-160). =head1 SEE ALSO L, +L, L =head1 COPYRIGHT diff --git a/doc/man3/EVP_whirlpool.pod b/doc/man3/EVP_whirlpool.pod index c7e5d45d..d3a4a1fc 100644 --- a/doc/man3/EVP_whirlpool.pod +++ b/doc/man3/EVP_whirlpool.pod @@ -14,7 +14,8 @@ EVP_whirlpool =head1 DESCRIPTION WHIRLPOOL is a cryptographic hash function standardized in ISO/IEC 10118-3:2004 -designed by Vincent Rijmen and Paulo S. L. M. Barreto. +designed by Vincent Rijmen and Paulo S. L. M. Barreto. This implementation is +only available with the legacy provider. =over 4 @@ -39,6 +40,7 @@ ISO/IEC 10118-3:2004. =head1 SEE ALSO L, +L, L =head1 COPYRIGHT diff --git a/doc/man3/HMAC.pod b/doc/man3/HMAC.pod index 2675969a..b798e6ca 100644 --- a/doc/man3/HMAC.pod +++ b/doc/man3/HMAC.pod @@ -54,7 +54,7 @@ L: =head1 DESCRIPTION All of the functions described on this page are deprecated. Applications should -instead use L, L, L, +instead use L, L, L, L and L. HMAC is a MAC (message authentication code), i.e. a keyed hash diff --git a/doc/man3/ISSUER_SIGN_TOOL_new.pod b/doc/man3/ISSUER_SIGN_TOOL_new.pod deleted file mode 100644 index 4fb1f70f..00000000 --- a/doc/man3/ISSUER_SIGN_TOOL_new.pod +++ /dev/null @@ -1,51 +0,0 @@ -=pod - -=head1 NAME - -ISSUER_SIGN_TOOL_new, ISSUER_SIGN_TOOL_free,ISSUER_SIGN_TOOL_it, -d2i_ISSUER_SIGN_TOOL, i2d_ISSUER_SIGN_TOOL - -=head1 SYNOPSIS - -=for openssl generic - - #include - - extern const ISSUER_SIGN_TOOL_it; - - ISSUER_SIGN_TOOL *ISSUER_SIGN_TOOL_new(void); - void ISSUER_SIGN_TOOL_free(ISSUER_SIGN_TOOL *v); - - ISSUER_SIGN_TOOL *d2i_ISSUER_SIGN_TOOL(ISSUER_SIGN_TOOL **a, const unsigned char **pp, long length); - int i2d_ISSUER_SIGN_TOOL(const ISSUER_SIGN_TOOL *a, unsigned char **pp); - -=head1 DESCRIPTION - -The ISSUER_SIGN_TOOL_new() function returns a new ISSUER_SIGN_TOOL. - -ISSUER_SIGN_TOOL_free() frees up a single ISSUER_SIGN_TOOL object. - -=head1 RETURN VALUES - -ISSUER_SIGN_TOOL_new() returns a newly created ISSUER_SIGN_TOOL or NULL if the call fails. - -ISSUER_SIGN_TOOL_free() does not return values. - -d2i_ISSUER_SIGN_TOOL() and i2d_ISSUER_SIGN_TOOL() decode and encode an B -structure. They otherwise follow the conventions of other ASN.1 functions such as d2i_X509(). - -=head1 HISTORY - -The ISSUER_SIGN_TOOL_up_ref(), ISSUER_SIGN_TOOL_lock() and ISSUER_SIGN_TOOL_unlock() -functions were added in OpenSSL 3.0. - -=head1 COPYRIGHT - -Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the Apache License 2.0 (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/doc/man3/OCSP_sendreq_new.pod b/doc/man3/OCSP_sendreq_new.pod index f3224daa..af792f42 100644 --- a/doc/man3/OCSP_sendreq_new.pod +++ b/doc/man3/OCSP_sendreq_new.pod @@ -10,22 +10,22 @@ OCSP_REQ_CTX_set1_req, OCSP_sendreq_bio - OCSP responder query functions #include - OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, - OCSP_REQUEST *req, int maxline); + OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline); int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); - void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, - unsigned long len); + void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len); int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, const char *name, const char *value); - int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, const OCSP_REQUEST *req); + int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); - OCSP_RESPONSE *OCSP_sendreq_bio(BIO *io, const char *path, OCSP_REQUEST *req); + OCSP_RESPONSE *OCSP_sendreq_bio(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline); =head1 DESCRIPTION @@ -35,14 +35,14 @@ response header maximum line length of B. If B is zero a default value of 4k is used. The OCSP request B may be set to B and provided later if required. -OCSP_sendreq_nbio() performs I/O on the OCSP request context B. -When the operation is complete it returns the response in B<*presp>. +OCSP_sendreq_nbio() performs non-blocking I/O on the OCSP request context +B. When the operation is complete it returns the response in B<*presp>. OCSP_REQ_CTX_free() frees up the OCSP context B. -OCSP_set_max_response_length() sets the maximum response length -for B to B. If the response exceeds this length an error occurs. -If not set a default value of 100k is used. +OCSP_set_max_response_length() sets the maximum response length for B +to B. If the response exceeds this length an error occurs. If not +set a default value of 100k is used. OCSP_REQ_CTX_add1_header() adds header B with value B to the context B. It can be called more than once to add multiple headers. @@ -55,21 +55,23 @@ function should be called after any calls to OCSP_REQ_CTX_add1_header(). OCSP_sendreq_bio() performs an OCSP request using the responder B, the URL path B, the OCSP request B and with a response header maximum line -length 4k. It waits indefinitely on a response. +length of B. If B is zero a default value of 4k is used. =head1 RETURN VALUES -OCSP_sendreq_new() returns a valid B structure or B -if an error occurred. +OCSP_sendreq_new() returns a valid B structure or B if +an error occurred. -OCSP_sendreq_nbio(), OCSP_REQ_CTX_add1_header() and OCSP_REQ_CTX_set1_req() -return B<1> for success and B<0> for failure. +OCSP_sendreq_nbio() returns B<1> if the operation was completed successfully, +B<-1> if the operation should be retried and B<0> if an error occurred. + +OCSP_REQ_CTX_add1_header() and OCSP_REQ_CTX_set1_req() return B<1> for success +and B<0> for failure. OCSP_sendreq_bio() returns the B structure sent by the responder or B if an error occurred. -OCSP_REQ_CTX_free() and OCSP_set_max_response_length() -do not return values. +OCSP_REQ_CTX_free() and OCSP_set_max_response_length() do not return values. =head1 NOTES @@ -90,9 +92,14 @@ a Host header for B you would call: OCSP_REQ_CTX_add1_header(ctx, "Host", "ocsp.com"); -OCSP_sendreq_bio() does not support timeout nor setting extra headers. -It is retained for compatibility. -Better use B instead. +If OCSP_sendreq_nbio() indicates an operation should be retried the +corresponding BIO can be examined to determine which operation (read or +write) should be retried and appropriate action taken (for example a select() +call on the underlying socket). + +OCSP_sendreq_bio() does not support retries and so cannot handle non-blocking +I/O efficiently. It is retained for compatibility and its use in new +applications is not recommended. =head1 SEE ALSO diff --git a/doc/man3/OSSL_CMP_CTX_new.pod b/doc/man3/OSSL_CMP_CTX_new.pod index c8eacfc3..cefed767 100644 --- a/doc/man3/OSSL_CMP_CTX_new.pod +++ b/doc/man3/OSSL_CMP_CTX_new.pod @@ -11,10 +11,12 @@ OSSL_CMP_CTX_set_log_cb, OSSL_CMP_CTX_set_log_verbosity, OSSL_CMP_CTX_print_errors, OSSL_CMP_CTX_set1_serverPath, -OSSL_CMP_CTX_set1_server, +OSSL_CMP_CTX_set1_serverName, OSSL_CMP_CTX_set_serverPort, -OSSL_CMP_CTX_set1_proxy, -OSSL_CMP_CTX_set1_no_proxy, +OSSL_CMP_CTX_set1_proxyName, +OSSL_CMP_CTX_set_proxyPort, +OSSL_CMP_DEFAULT_PORT, +OSSL_CMP_http_cb_t, OSSL_CMP_CTX_set_http_cb, OSSL_CMP_CTX_set_http_cb_arg, OSSL_CMP_CTX_get_http_cb_arg, @@ -73,19 +75,22 @@ OSSL_CMP_CTX_set1_senderNonce /* logging and error reporting: */ int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb); #define OSSL_CMP_CTX_set_log_verbosity(ctx, level) - void OSSL_CMP_CTX_print_errors(OSSL_CMP_CTX *ctx); + void OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX *ctx); /* message transfer: */ int OSSL_CMP_CTX_set1_serverPath(OSSL_CMP_CTX *ctx, const char *path); - int OSSL_CMP_CTX_set1_server(OSSL_CMP_CTX *ctx, const char *address); + int OSSL_CMP_CTX_set1_serverName(OSSL_CMP_CTX *ctx, const char *name); int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port); - int OSSL_CMP_CTX_set1_proxy(OSSL_CMP_CTX *ctx, const char *name); - int OSSL_CMP_CTX_set1_no_proxy(OSSL_CMP_CTX *ctx, const char *names); - int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, HTTP_bio_cb_t cb); + int OSSL_CMP_CTX_set1_proxyName(OSSL_CMP_CTX *ctx, const char *name); + int OSSL_CMP_CTX_set_proxyPort(OSSL_CMP_CTX *ctx, int port); + #define OSSL_CMP_DEFAULT_PORT 80 + typedef BIO *(*OSSL_CMP_http_cb_t)(OSSL_CMP_CTX *ctx, BIO *hbio, + unsigned long detail); + int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_http_cb_t cb); int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg); void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx); - typedef OSSL_CMP_MSG *(*OSSL_CMP_transfer_cb_t)(OSSL_CMP_CTX *ctx, - const OSSL_CMP_MSG *req); + typedef OSSL_CMP_MSG *(*OSSL_CMP_transfer_cb_t) (OSSL_CMP_CTX *ctx, + const OSSL_CMP_MSG *req); int OSSL_CMP_CTX_set_transfer_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_transfer_cb_t cb); int OSSL_CMP_CTX_set_transfer_cb_arg(OSSL_CMP_CTX *ctx, void *arg); @@ -306,7 +311,7 @@ B to print to STDERR (unless OPENSSL_NO_STDIO is defined). OSSL_CMP_CTX_set1_serverPath() sets the HTTP path of the CMP server on the host, also known as "CMP alias". -The default is "/". +The default is I. OSSL_CMP_CTX_set1_server() sets the given server B

(which may be a hostname or IP address or NULL) in the given B. @@ -323,7 +328,7 @@ Otherwise defaults to the value of B if set, else B. An empty proxy string specifies not to use a proxy. Else the format is I<[http[s]://]address[:port][/path]>, where any path given is ignored. -The default port number is 80, or 443 in case "https:" is given. +The default port number is 80, or 443 in case I is given. OSSL_CMP_CTX_set1_no_proxy() sets the list of server hostnames not to use an HTTP proxy for. The names may be separated by commas and/or whitespace. @@ -380,32 +385,40 @@ OSSL_CMP_CTX_get_transfer_cb_arg() gets the argument, respectively the pointer to a structure containing arguments, previously set by OSSL_CMP_CTX_set_transfer_cb_arg() or NULL if unset. -OSSL_CMP_CTX_set1_srvCert() pins the given server certificate B -directly trusts it (even if it is expired) for verifying response messages. +OSSL_CMP_CTX_set1_srvCert() sets the expected server cert B and trusts +it directly (even if it is expired) when verifying signed response messages. +May be used alternatively to OSSL_CMP_CTX_set0_trustedStore() +to pin the accepted server. +Any previously set value is freed. The B argument may be NULL to clear the entry. +If set, the subject of the certificate is also used +as default value for the recipient of CMP requests +and as default value for the expected sender of CMP responses. -OSSL_CMP_CTX_set1_expected_sender() sets the Distinguished Name (DN) expected to -be given in the sender response for messages protected with MSG_SIG_ALG. This -may be used to enforce that during validation of received messages the given DN -matches the sender field of the PKIMessage header, which in turn is used to -identify the server certificate. -This can be used to ensure that only a particular entity is accepted to act as -CMP server, and attackers are not able to use arbitrary certificates of a -trusted PKI hierarchy to fraudulently pose as server. -This defaults to the subject of the B, if any. +OSSL_CMP_CTX_set1_expected_sender() sets the Distinguished Name (DN) +expected in the sender field of CMP response messages. +Defaults to the subject of the pinned server certificate B<-srvcert>, if any. +This can be used to make sure that only a particular entity is accepted as +CMP message signer, and attackers are not able to use arbitrary certificates +of a trusted PKI hierarchy to fraudulently pose as CMP server. +Note that this gives slightly more freedom than OSSL_CMP_CTX_set1_srvCert(), +which pins the server to the holder of a particular certificate, while the +expected sender name will continue to match after updates of the server cert. -OSSL_CMP_CTX_set0_trustedStore() sets the X509_STORE type certificate store -containing trusted (root) CA certificates. The certificate store may also hold -CRLs and a certificate verification callback function used for CMP server -authentication. Any already existing store entry is freed. When given a NULL -parameter the entry is cleared. +OSSL_CMP_CTX_set0_trustedStore() sets the certificate store of type X509_STORE +containing trusted (root) CA certificates. +The store may also hold CRLs and +a certificate verification callback function used for CMP server authentication. +Any store entry already set before is freed. +When given a NULL parameter the entry is cleared. -OSSL_CMP_CTX_get0_trustedStore() returns a pointer to the certificate store -containing trusted root CA certificates, which may be empty if unset. +OSSL_CMP_CTX_get0_trustedStore() returns a pointer to the currently set +certificate store containing trusted cert etc., or an empty store if unset. OSSL_CMP_CTX_set1_untrusted_certs() sets up a list of non-trusted certificates -of intermediate CAs that may be useful for path construction when authenticating -the CMP server and when verifying newly enrolled certificates. +of intermediate CAs that may be useful for path construction for the CMP client +certificate, for the TLS client certificate (if any), when verifying +the CMP server certificate, and when verifying newly enrolled certificates. The reference counts of those certificates handled successfully are increased. OSSL_CMP_CTX_get0_untrusted_certs(OSSL_CMP_CTX *ctx) returns a pointer to the @@ -416,13 +429,13 @@ The public key of this B must correspond to the private key set via B. When using signature-based protection of CMP request messages this "protection certificate" will be included first in the extraCerts field. -The subject of this B will be used as the "sender" field -of outgoing CMP messages, with the fallback being -the B set via B. +The subject of this B will be used as the sender field of outgoing +messages, while the subject of any cert set via B +and any value set via B are used as fallback. The B argument may be NULL to clear the entry. OSSL_CMP_CTX_set1_pkey() sets the private key corresponding to the -protecting certificate B set via B. +protection certificate B set via B. This key is used create signature-based protection (protectionAlg = MSG_SIG_ALG) of outgoing messages unless a PBM secret has been set via B. @@ -437,22 +450,25 @@ PBM-based protection takes precedence over signature-based protection. OSSL_CMP_CTX_set1_referenceValue() sets the given referenceValue B with length B in the given B or clears it if the B argument is NULL. -According to RFC 4210 section 5.1.1, if no value for the "sender" field in -CMP message headers can be determined (i.e., no protecting certificate B -and no B is given) then the "sender" field will contain the NULL-DN +According to RFC 4210 section 5.1.1, if no value for the sender field in +CMP message headers can be determined (i.e., no protection certificate B +and no B is given) then the sender field will contain the NULL-DN and the senderKID field of the CMP message header must be set. When signature-based protection is used the senderKID will be set to -the subjectKeyIdentifier of the protecting B as far as present. +the subjectKeyIdentifier of the protection B as far as present. If not present or when PBM-based protection is used the B value is taken as the fallback value for the senderKID. OSSL_CMP_CTX_set1_recipient() sets the recipient name that will be used in the -PKIHeader of a request message, i.e. the X509 name of the (CA) server. -Setting is overruled by subject of B if set. -If neither B nor recipient are set, the recipient of the PKI message is -determined in the following order: issuer, issuer of old cert (oldCert), -issuer of protecting certificate (B), else NULL-DN. -When a response is received, its sender must match the recipient of the request. +PKIHeader of CMP request messages, i.e. the X509 name of the (CA) server. + +The recipient field in the header of a CMP message is mandatory. +If not given explicitly the recipient is determined in the following order: +the subject of the CMP server certificate set using OSSL_CMP_CTX_set1_srvCert(), +the value set using OSSL_CMP_CTX_set1_issuer(), +the issuer of the certificate set using OSSL_CMP_CTX_set1_oldCert(), +the issuer of the protection certificate (B), +as far as any of those is present, else the NULL-DN as last resort. OSSL_CMP_CTX_push0_geninfo_ITAV() adds B to the stack in the B to be added to the GeneralInfo field of the CMP PKIMessage header of a request @@ -480,8 +496,8 @@ the CertTemplate structure when requesting a new cert. For Key Update Requests (KUR), it defaults to the subject DN of the B, see B. This default is used for Initialization Requests (IR) and Certification Requests (CR) only if no SANs are set. -The B is also used as the "sender" field for outgoing CMP messages -if no B has been set (e.g., in case requests are protected using PBM). +The B is also used as fallback for the sender field +of outgoing CMP messages if no B and no B are available. OSSL_CMP_CTX_push1_subjectAltName() adds the given X509 name to the list of alternate names on the certificate template request. This cannot be used if @@ -507,10 +523,11 @@ to the X509_EXTENSIONS of the requested certificate template. OSSL_CMP_CTX_set1_oldCert() sets the old certificate to be updated in Key Update Requests (KUR) or to be revoked in Revocation Requests (RR). -It must be given for RR, else it defaults to the protecting B. +It must be given for RR, else it defaults to the protection B. The B determined in this way, if any, is also used for deriving default subject DN and Subject Alternative Names for IR, CR, and KUR. -Its issuer, if any, is used as default recipient in the CMP message header. +Its subject is used as sender in CMP message headers if no protection cert is given. +Its issuer is used as default recipient in CMP message headers. OSSL_CMP_CTX_set1_p10CSR() sets the PKCS#10 CSR to be used in P10CR. diff --git a/doc/man3/OSSL_CMP_MSG_http_perform.pod b/doc/man3/OSSL_CMP_MSG_http_perform.pod deleted file mode 100644 index 344c6b77..00000000 --- a/doc/man3/OSSL_CMP_MSG_http_perform.pod +++ /dev/null @@ -1,60 +0,0 @@ -=pod - -=head1 NAME - -OSSL_CMP_MSG_http_perform -- client-side HTTP(S) transfer of a CMP request-response pair - -=head1 SYNOPSIS - - #include - - OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, - const OSSL_CMP_MSG *req); - -=head1 DESCRIPTION - -OSSL_CMP_MSG_http_perform() sends the given PKIMessage B -to the CMP server specified in B via L -and optionally L, using -any "CMP alias" optionally specified via L. -The default port is 80 for HTTP and 443 for HTTPS; the default path is "/". -On success the function returns the server's response PKIMessage. - -The function makes use of any HTTP callback function -set via L. -It respects any timeout value set via L -with an B argument. -It also respects any HTTP(S) proxy options set via L -and L and the respective environment variables. -Proxying plain HTTP is supported directly, -while using a proxy for HTTPS connections requires a suitable callback function -such as L. - -=head1 NOTES - -CMP is defined in RFC 4210. -HTTP transfer for CMP is defined in RFC 6712. - -=head1 RETURN VALUES - -OSSL_CMP_MSG_http_perform() returns a CMP message on success, else NULL. - -=head1 SEE ALSO - -L, L. - -=head1 HISTORY - -The OpenSSL CMP support was added in OpenSSL 3.0. - -=head1 COPYRIGHT - -Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the Apache License 2.0 (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/doc/man3/OSSL_CMP_SRV_CTX_new.pod b/doc/man3/OSSL_CMP_SRV_CTX_new.pod index a2d47a45..27d4f6ca 100644 --- a/doc/man3/OSSL_CMP_SRV_CTX_new.pod +++ b/doc/man3/OSSL_CMP_SRV_CTX_new.pod @@ -85,32 +85,33 @@ OSSL_CMP_SRV_CTX_set_grant_implicit_confirm =head1 DESCRIPTION OSSL_CMP_SRV_process_request() implements the generic aspects of a CMP server. -It does the typical generic checks on the given request message, calls +Its arguments are the B I and the CMP request message +I. It does the typical generic checks on I, calls the respective callback function (if present) for more specific processing, and then assembles a result message, which may be a CMP error message. OSSL_CMP_CTX_server_perform() is an interface to B that can be used by a CMP client in the same way as B. -The B must be set as B of B. +The B must be set as I of I. OSSL_CMP_SRV_CTX_new() creates and initializes an OSSL_CMP_SRV_CTX structure and returns a pointer to it on success, NULL on error. -OSSL_CMP_SRV_CTX_free() deletes the given B. +OSSL_CMP_SRV_CTX_free() deletes the given I. -OSSL_CMP_SRV_CTX_init() sets in the given B a custom server context +OSSL_CMP_SRV_CTX_init() sets in the given I a custom server context pointer as well as callback functions performing the specific processing of CMP certificate requests, revocation requests, certificate confirmation requests, general messages, error messages, and poll requests. -All arguments except B may be NULL. +All arguments except I may be NULL. If a callback for some message type is not given this means that the respective type of CMP message is not supported by the server. -OSSL_CMP_SRV_CTX_get0_cmp_ctx() returns the B from the B. +OSSL_CMP_SRV_CTX_get0_cmp_ctx() returns the B from the I. OSSL_CMP_SRV_CTX_get0_custom_ctx() returns the custom server context from -B that has been set using B. +I that has been set using B. OSSL_CMP_SRV_CTX_set_send_unprotected_errors() enables sending error messages and other forms of negative responses unprotected. @@ -142,7 +143,7 @@ OSSL_CMP_SRV_CTX_get0_cmp_ctx() returns a B structure on success, NULL on error. OSSL_CMP_SRV_CTX_get0_custom_ctx() returns the custom server context -that has been set using B. +that has been set using B. All other functions return 1 on success, 0 on error. diff --git a/doc/man3/OSSL_CMP_validate_msg.pod b/doc/man3/OSSL_CMP_validate_msg.pod index 3b06532c..3bf5c068 100644 --- a/doc/man3/OSSL_CMP_validate_msg.pod +++ b/doc/man3/OSSL_CMP_validate_msg.pod @@ -46,13 +46,6 @@ according to TS 33.310 [Network Domain Security (NDS); Authentication Framework Any cert that has been found as described above is cached and tried first when validating the signatures of subsequent messages in the same transaction. -After successful validation of PBM-based protection of a certificate response -the certificates in the caPubs field (if any) are added to the trusted -certificates provided via L, such that -they are available for validating subsequent messages in the same context. -Those could apply to any Polling Response (pollRep), error, or PKI Confirmation -(PKIConf) messages following in the same or future transactions. - OSSL_CMP_validate_cert_path() attempts to validate the given certificate and its path using the given store of trusted certs (possibly including CRLs and a cert verification callback) and non-trusted intermediate certs from the B. diff --git a/doc/man3/OSSL_HTTP_transfer.pod b/doc/man3/OSSL_HTTP_transfer.pod deleted file mode 100644 index e0adb2a1..00000000 --- a/doc/man3/OSSL_HTTP_transfer.pod +++ /dev/null @@ -1,233 +0,0 @@ -=pod - -=head1 NAME - -OSSL_HTTP_get, -OSSL_HTTP_get_asn1, -OSSL_HTTP_post_asn1, -OSSL_HTTP_transfer, -OSSL_HTTP_bio_cb_t, -OSSL_HTTP_proxy_connect, -OSSL_HTTP_parse_url -- http client functions - -=head1 SYNOPSIS - - #include - - typedef BIO *(*OSSL_HTTP_bio_cb_t)(BIO *bio, void *arg, - int connect, int detail); - BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, - BIO *bio, BIO *rbio, - OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, - const STACK_OF(CONF_VALUE) *headers, - int maxline, unsigned long max_resp_len, int timeout, - const char *expected_content_type, int expect_asn1); - ASN1_VALUE *OSSL_HTTP_get_asn1(const char *url, - const char *proxy, const char *no_proxy, - BIO *bio, BIO *rbio, - OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, - const STACK_OF(CONF_VALUE) *headers, - int maxline, unsigned long max_resp_len, - int timeout, const char *expected_content_type, - const ASN1_ITEM *it); - ASN1_VALUE *OSSL_HTTP_post_asn1(const char *server, const char *port, - const char *path, int use_ssl, - const char *proxy, const char *no_proxy, - BIO *bio, BIO *rbio, - OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, - const STACK_OF(CONF_VALUE) *headers, - const char *content_type, - const ASN1_VALUE *req, const ASN1_ITEM *req_it, - int maxline, unsigned long max_resp_len, - int timeout, const char *expected_ct, - const ASN1_ITEM *rsp_it); - BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path, - int use_ssl, const char *proxy, const char *no_proxy, - BIO *bio, BIO *rbio, - OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, - const STACK_OF(CONF_VALUE) *headers, - const char *content_type, BIO *req_mem, - int maxline, unsigned long max_resp_len, int timeout, - const char *expected_ct, int expect_asn1, - char **redirection_url); - int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port, - const char *proxyuser, const char *proxypass, - int timeout, BIO *bio_err, const char *prog); - int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport, - char **ppath, int *pssl); - -=head1 DESCRIPTION - -OSSL_HTTP_get() uses HTTP GET to obtain data (of any type) from the given B -and returns it as a memory BIO. - -OSSL_HTTP_get_asn1() uses HTTP GET to obtain an ASN.1-encoded value -(e.g., an X.509 certificate) with the expected structure specified by B -(e.g., I) from the given B -and returns it on success as a pointer to I. - -OSSL_HTTP_post_asn1() uses the HTTP POST method to send a request B -with the ASN.1 structure defined in B and the given B to -the given B and optional B and B. -If B is nonzero a TLS connection is requested and the B -parameter, described below, must be provided. -The optional list B may contain additional custom HTTP header lines. -The expected structure of the response is specified by B. -On success it returns the response as a pointer to B. - -OSSL_HTTP_transfer() exchanges any form of HTTP request and response. -It implements the core of the functions described above. -If B parameter is NULL it defaults to "/". -If B is nonzero a TLS connection is requested -and the B parameter, described below, must be provided. -If B is NULL it uses the HTTP GET method, else it uses HTTP POST to -send a request with the contents of the memory BIO and optional B. -The optional list B may contain additional custom HTTP header lines. -If B is NULL (i.e., the HTTP method is GET) and B -is not NULL the latter pointer is used to provide any new location that -the server may return with HTTP code 301 (MOVED_PERMANENTLY) or 302 (FOUND). -In this case the caller is responsible for deallocating this URL with -L. - -The above functions have the following parameters in common. - -Typically the OpenSSL build supports sockets -and the B and B parameters are both NULL. -In this case the client creates a network BIO internally -for connecting to the given B -at the specified B (if any, defaulting to 80 for HTTP or 443 for HTTPS), -optionally via a B (respecting B) as described below. -Then the client uses this internal BIO for exchanging the request and response. -If B is given and B is NULL then the client uses this B instead. -If both B and B are given (which may be memory BIOs for instance) -then no explicit connection is attempted, -B is used for writing the request, and B for reading the response. -As soon as the client has flushed B the server must be ready to provide -a response or indicate a waiting condition via B. - -The optional B parameter can be used to set the address of the an -HTTP(S) proxy to use (unless overridden by "no_proxy" settings). -If TLS is not used this defaults to the environment variable B -if set, else B. -If B != 0 it defaults to B if set, else B. -An empty proxy string specifies not to use a proxy. -Else the format is I<[http[s]://]address[:port][/path]>, -where any path given is ignored. -The default proxy port number is 80, or 443 in case "https:" is given. -The HTTP client functions connect via the given proxy unless the B -is found in the optional list B of proxy hostnames (if not NULL; -default is the environment variable B if set, else B). -Proxying plain HTTP is supported directly, -while using a proxy for HTTPS connections requires a suitable callback function -such as B, described below. - -The B parameter specifies the response header maximum line length, -where 0 indicates the default value, which currently is 4k. -The B parameter specifies the maximum response length, -where 0 indicates the default value, which currently is 100k. - -An ASN.1-encoded response is expected by OSSL_HTTP_get_asn1() and -OSSL_HTTP_post_asn1(), while for OSSL_HTTP_get() or OSSL_HTTP_transfer() -this is only the case if the B parameter is nonzero. -If the response header contains one or more "Content-Length" header lines and/or -an ASN.1-encoded response is expected, which should include a total length, -the length indications received are checked for consistency -and for not exceeding the maximum response length. - -If the parameter B (or B, respectively) -is not NULL then the HTTP client checks that the given content type string -is included in the HTTP header of the response and returns an error if not. - -If the B parameter is > 0 this indicates the maximum number of seconds -to wait until the transfer is complete. -A value of 0 enables waiting indefinitely, -while a value < 0 immediately leads to a timeout condition. - -The optional parameter B with its optional argument B may -be used to modify the connection BIO used by the HTTP client (and cannot be -used when both B and B are given). -B is a BIO connect/disconnect callback function with prototype - - BIO *(*OSSL_HTTP_bio_cb_t)(BIO *bio, void *arg, int connect, int detail) - -The callback may modify the HTTP BIO provided in the B argument, -whereby it may make use of a custom defined argument B, -which may for instance refer to an I structure. -During connection establishment, just after calling BIO_connect_retry(), -the function is invoked with the B argument being 1 and the B -argument being 1 if HTTPS is requested, i.e., SSL/TLS should be enabled. -On disconnect B is 0 and B is 1 if no error occurred, else 0. -For instance, on connect the function may prepend a TLS BIO to implement HTTPS; -after disconnect it may do some diagnostic output and/or specific cleanup. -The function should return NULL to indicate failure. -Here is a simple example that supports TLS connections (but not via a proxy): - - BIO *http_tls_cb(BIO *hbio, void *arg, int connect, int detail) - { - SSL_CTX *ctx = (SSL_CTX *)arg; - - if (connect && detail) { /* connecting with TLS */ - BIO *sbio = BIO_new_ssl(ctx, 1); - hbio = sbio != NULL ? BIO_push(sbio, hbio) : NULL; - } else if (!connect && !detail) { /* disconnecting after error */ - /* optionally add diagnostics here */ - } - return hbio; - } - -After disconnect the modified BIO will be deallocated using BIO_free_all(). - -OSSL_HTTP_proxy_connect() may be used by an above BIO connect callback function -to set up an SSL/TLS connection via an HTTPS proxy. -It promotes the given BIO B representing a connection -pre-established with a TLS proxy using the HTTP CONNECT method, -optionally using proxy client credentials B and B, -to connect with TLS protection ultimately to B and B. -If the B argument is NULL or the empty string it defaults to "443". -The B parameter is used as described above. -Since this function is typically called by appplications such as -L it uses the B and B parameters (unless -NULL) to print additional diagnostic information in a user-oriented way. - -OSSL_HTTP_parse_url() parses its input string B as a URL and splits it up -into host, port and path components and a flag whether it begins with 'https'. -The host component may be a DNS name or an IPv4 or an IPv6 address. -The port component is optional and defaults to "443" for HTTPS, else "80". -The path component is also optional and defaults to "/". -As far as the result pointer arguments are not NULL it assigns via -them copies of the respective string components. -The strings returned this way must be deallocated by the caller using -L unless they are NULL, which is their default value on error. - -=head1 NOTES - -The names of the environment variables used by this implementation: -B, B, B, B, B, and -B, have been chosen for maximal compatibility with -other HTTP client implementations such as wget, curl, and git. - -=head1 RETURN VALUES - -OSSL_HTTP_get(), OSSL_HTTP_get_asn1(), OSSL_HTTP_post_asn1(), and -OSSL_HTTP_transfer() return on success the data received via HTTP, else NULL. -Error conditions include connection/transfer timeout, parse errors, etc. - -OSSL_HTTP_proxy_connect() and OSSL_HTTP_parse_url() -return 1 on success, 0 on error. - -=head1 HISTORY - -OSSL_HTTP_get(), OSSL_HTTP_get_asn1(), OSSL_HTTP_post_asn1(), -OSSL_HTTP_proxy_connect(), and OSSL_HTTP_parse_url() were added in OpenSSL 3.0. - -=head1 COPYRIGHT - -Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the Apache License 2.0 (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/doc/man3/OSSL_PARAM_allocate_from_text.pod b/doc/man3/OSSL_PARAM_allocate_from_text.pod index 011685c8..539b2179 100644 --- a/doc/man3/OSSL_PARAM_allocate_from_text.pod +++ b/doc/man3/OSSL_PARAM_allocate_from_text.pod @@ -175,7 +175,7 @@ Can be written like this instead: goto err; } params[params_n] = OSSL_PARAM_construct_end(); - if (!EVP_MAC_CTX_set_params(ctx, params)) + if (!EVP_MAC_set_ctx_params(ctx, params)) goto err; while (params_n-- > 0) OPENSSL_free(params[params_n].data); diff --git a/doc/man3/OSSL_PROVIDER.pod b/doc/man3/OSSL_PROVIDER.pod index 3f1a9466..d6f0af53 100644 --- a/doc/man3/OSSL_PROVIDER.pod +++ b/doc/man3/OSSL_PROVIDER.pod @@ -4,8 +4,9 @@ OSSL_PROVIDER_set_default_search_path, OSSL_PROVIDER, OSSL_PROVIDER_load, OSSL_PROVIDER_unload, -OSSL_PROVIDER_available, +OSSL_PROVIDER_available, OSSL_PROVIDER_do_all, OSSL_PROVIDER_gettable_params, OSSL_PROVIDER_get_params, +OSSL_PROVIDER_query_operation, OSSL_PROVIDER_get0_provider_ctx, OSSL_PROVIDER_add_builtin, OSSL_PROVIDER_name - provider routines =head1 SYNOPSIS @@ -20,10 +21,18 @@ OSSL_PROVIDER_add_builtin, OSSL_PROVIDER_name - provider routines OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *libctx, const char *name); int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov); int OSSL_PROVIDER_available(OPENSSL_CTX *libctx, const char *name); + int OSSL_PROVIDER_do_all(OPENSSL_CTX *ctx, + int (*cb)(OSSL_PROVIDER *provider, void *cbdata), + void *cbdata); const OSSL_PARAM *OSSL_PROVIDER_gettable_params(OSSL_PROVIDER *prov); int OSSL_PROVIDER_get_params(OSSL_PROVIDER *prov, OSSL_PARAM params[]); + const OSSL_ALGORITHM *OSSL_PROVIDER_query_operation(const OSSL_PROVIDER *prov, + int operation_id, + int *no_cache); + void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov); + int OSSL_PROVIDER_add_builtin(OPENSSL_CTX *libctx, const char *name, ossl_provider_init_fn *init_fn); @@ -66,6 +75,10 @@ runs its teardown function. OSSL_PROVIDER_available() checks if a named provider is available for use. +OSSL_PROVIDER_do_all() iterates over all loaded providers, calling +I for each one, with the current provider in I and the +I that comes from the caller. + OSSL_PROVIDER_gettable_params() is used to get a provider parameter descriptor set as a constant B array. See L for more information. @@ -75,6 +88,20 @@ The caller must prepare the B array before calling this function, and the variables acting as buffers for this parameter array should be filled with data when it returns successfully. +OSSL_PROVIDER_query_operation() calls the provider's I +function (see L), if the provider has one. It returns an +array of I for the given I terminated by an all +NULL OSSL_ALGORITHM entry. This is considered a low-level function that most +applications should not need to call. + +OSSL_PROVIDER_get0_provider_ctx() returns the provider context for the given +provider. The provider context is an opaque handle set by the provider itself +and is passed back to the provider by libcrypto in various function calls. + +If it is permissible to cache references to this array then I<*no_store> is set +to 0 or 1 otherwise. If the array is not cacheable then it is assumed to +have a short lifetime. + OSSL_PROVIDER_name() returns the name of the given provider. =head1 RETURN VALUES @@ -94,6 +121,9 @@ of constant B, or NULL if none is provided. OSSL_PROVIDER_get_params() returns 1 on success, or 0 on error. +OSSL_PROVIDER_query_operation() returns an array of OSSL_ALGORITHM or NULL on +error. + =head1 EXAMPLES This demonstrates how to load the provider module "foo" and ask for diff --git a/doc/man3/OSSL_STORE_INFO.pod b/doc/man3/OSSL_STORE_INFO.pod index bf694749..095a4028 100644 --- a/doc/man3/OSSL_STORE_INFO.pod +++ b/doc/man3/OSSL_STORE_INFO.pod @@ -54,25 +54,24 @@ loaders to create B holders. =head2 Types B is an opaque type that's just an intermediary holder for -the objects that have been retrieved by OSSL_STORE_load() and similar -functions. +the objects that have been retrieved by OSSL_STORE_load() and similar functions. Supported OpenSSL type object can be extracted using one of -STORE_INFO_get0_TYPE(). +STORE_INFO_get0_() where can be NAME, PARAMS, PKEY, CERT, or CRL. The life time of this extracted object is as long as the life time of the B it was extracted from, so care should be taken not to free the latter too early. -As an alternative, STORE_INFO_get1_TYPE() extracts a duplicate (or the +As an alternative, STORE_INFO_get1_() extracts a duplicate (or the same object with its reference count increased), which can be used after the containing B has been freed. -The object returned by STORE_INFO_get1_TYPE() must be freed separately +The object returned by STORE_INFO_get1_() must be freed separately by the caller. -See L for more information on the types that are -supported. +See L for more information on the types that are supported. =head2 Functions OSSL_STORE_INFO_get_type() takes a B and returns the STORE type number for the object inside. + STORE_INFO_get_type_string() takes a STORE type number and returns a short string describing it. @@ -94,6 +93,8 @@ OSSL_STORE_INFO_new_NAME() , OSSL_STORE_INFO_new_PARAMS(), OSSL_STORE_INFO_new_PKEY(), OSSL_STORE_INFO_new_CERT() and OSSL_STORE_INFO_new_CRL() create a B object to hold the given input object. +On success the input object is consumed. + Additionally, for B` objects, OSSL_STORE_INFO_set0_NAME_description() can be used to add an extra description. @@ -162,9 +163,9 @@ OSSL_STORE_INFO_get0_PARAMS(), OSSL_STORE_INFO_get0_PKEY(), OSSL_STORE_INFO_get0_CERT() and OSSL_STORE_INFO_get0_CRL() all return a pointer to the OpenSSL object on success, NULL otherwise. -OSSL_STORE_INFO_get0_NAME(), OSSL_STORE_INFO_get0_NAME_description(), -OSSL_STORE_INFO_get0_PARAMS(), OSSL_STORE_INFO_get0_PKEY(), -OSSL_STORE_INFO_get0_CERT() and OSSL_STORE_INFO_get0_CRL() all return +OSSL_STORE_INFO_get1_NAME(), OSSL_STORE_INFO_get1_NAME_description(), +OSSL_STORE_INFO_get1_PARAMS(), OSSL_STORE_INFO_get1_PKEY(), +OSSL_STORE_INFO_get1_CERT() and OSSL_STORE_INFO_get1_CRL() all return a pointer to a duplicate of the OpenSSL object on success, NULL otherwise. OSSL_STORE_INFO_type_string() returns a string on success, or B on @@ -184,13 +185,7 @@ L, L, L =head1 HISTORY -OSSL_STORE_INFO(), OSSL_STORE_INFO_get_type(), OSSL_STORE_INFO_get0_NAME(), -OSSL_STORE_INFO_get0_PARAMS(), OSSL_STORE_INFO_get0_PKEY(), -OSSL_STORE_INFO_get0_CERT(), OSSL_STORE_INFO_get0_CRL(), -OSSL_STORE_INFO_type_string(), OSSL_STORE_INFO_free(), OSSL_STORE_INFO_new_NAME(), -OSSL_STORE_INFO_new_PARAMS(), OSSL_STORE_INFO_new_PKEY(), -OSSL_STORE_INFO_new_CERT() and OSSL_STORE_INFO_new_CRL() -were added in OpenSSL 1.1.1. +The OSSL_STORE API was added in OpenSSL 1.1.1. =head1 COPYRIGHT diff --git a/doc/man3/OSSL_STORE_open.pod b/doc/man3/OSSL_STORE_open.pod index be61ad5b..6d4ae018 100644 --- a/doc/man3/OSSL_STORE_open.pod +++ b/doc/man3/OSSL_STORE_open.pod @@ -46,21 +46,22 @@ OSSL_STORE_close() to work together. =head2 Functions -OSSL_STORE_open() takes a uri or path B, password UI method -B with associated data B, and post processing -callback B with associated data B, +OSSL_STORE_open() takes a uri or path I, password UI method +I with associated data I, and post processing +callback I with associated data I, opens a channel to the data located at that URI and returns a B with all necessary internal information. -The given B and B will be reused by all -functions that use B when interaction is needed. -The given B and B will be reused by +The given I and I will be reused by all +functions that use B when interaction is needed, +for instance to provide a password. +The given I and I will be reused by OSSL_STORE_load() to manipulate or drop the value to be returned. -The B function drops values by returning B, which +The I function drops values by returning NULL, which will cause OSSL_STORE_load() to start its process over with loading -the next object, until B returns something other than -B, or the end of data is reached as indicated by OSSL_STORE_eof(). +the next object, until I returns something other than +NULL, or the end of data is reached as indicated by OSSL_STORE_eof(). -OSSL_STORE_ctrl() takes a B, and command number B and +OSSL_STORE_ctrl() takes a B, and command number I and more arguments not specified here. The available loader specific command numbers and arguments they each take depends on the loader that's used and is documented together with @@ -94,6 +95,7 @@ OSSL_STORE_eof() shows that the end of data has been reached. OSSL_STORE_close() takes a B, closes the channel that was opened by OSSL_STORE_open() and frees all other information that was stored in the B, as well as the B itself. +If I is NULL it does nothing. =head1 SUPPORTED SCHEMES @@ -123,12 +125,12 @@ See L for further information. =head1 RETURN VALUES OSSL_STORE_open() returns a pointer to a B on success, or -B on failure. +NULL on failure. OSSL_STORE_load() returns a pointer to a B on success, or -B on error or when end of data is reached. +NULL on error or when end of data is reached. Use OSSL_STORE_error() and OSSL_STORE_eof() to determine the meaning of a -returned B. +returned NULL. OSSL_STORE_eof() returns 1 if the end of data has been reached, otherwise 0. @@ -149,6 +151,9 @@ OSSL_STORE_CTX(), OSSL_STORE_post_process_info_fn(), OSSL_STORE_open(), OSSL_STORE_ctrl(), OSSL_STORE_load(), OSSL_STORE_eof() and OSSL_STORE_close() were added in OpenSSL 1.1.1. +Handling of NULL I argument for OSSL_STORE_close() +was introduced in OpenSSL 1.1.1h. + =head1 COPYRIGHT Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/OSSL_trace_set_channel.pod b/doc/man3/OSSL_trace_set_channel.pod index 1105479a..57a5a1c8 100644 --- a/doc/man3/OSSL_trace_set_channel.pod +++ b/doc/man3/OSSL_trace_set_channel.pod @@ -178,9 +178,9 @@ point during evaluation. Traces BIGNUM context operations. -=item C +=item C -Traces the OSSL_PROVIDER configuration. +Traces details about the provider and engine configuration. =back diff --git a/doc/man3/SSL_CIPHER_get_name.pod b/doc/man3/SSL_CIPHER_get_name.pod index c70e0d27..1f4b59f4 100644 --- a/doc/man3/SSL_CIPHER_get_name.pod +++ b/doc/man3/SSL_CIPHER_get_name.pod @@ -13,6 +13,7 @@ SSL_CIPHER_get_digest_nid, SSL_CIPHER_get_handshake_digest, SSL_CIPHER_get_kx_nid, SSL_CIPHER_get_auth_nid, +SSL_CIPHER_get_prf_nid, SSL_CIPHER_is_aead, SSL_CIPHER_find, SSL_CIPHER_get_id, @@ -34,6 +35,7 @@ SSL_CIPHER_get_protocol_id const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c); int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c); int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c); + int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *c); int SSL_CIPHER_is_aead(const SSL_CIPHER *c); const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr); uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *c); @@ -91,6 +93,15 @@ TLS 1.3 cipher suites) B is returned. Examples (not comprehensive) NID_auth_ecdsa NID_auth_psk +SSL_CIPHER_get_prf_nid() retuns the pseudo-random function NID for B. If B is +a pre-TLS-1.2 cipher, it returns B but note these ciphers use +SHA-256 in TLS 1.2. Other return values may be treated uniformly in all +applicable versions. Examples (not comprehensive): + + NID_md5_sha1 + NID_sha256 + NID_sha384 + SSL_CIPHER_is_aead() returns 1 if the cipher B is AEAD (e.g. GCM or ChaCha20/Poly1305), and 0 if it is not AEAD. @@ -201,6 +212,8 @@ required to enable this function. The OPENSSL_cipher_name() function was added in OpenSSL 1.1.1. +The SSL_CIPHER_get_prf_nid() function was added in OpenSSL 3.0.0. + =head1 COPYRIGHT Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/SSL_CTX_load_verify_locations.pod b/doc/man3/SSL_CTX_load_verify_locations.pod index d28ec4c8..7408a208 100644 --- a/doc/man3/SSL_CTX_load_verify_locations.pod +++ b/doc/man3/SSL_CTX_load_verify_locations.pod @@ -22,20 +22,16 @@ SSL_CTX_set_default_verify_store, SSL_CTX_load_verify_locations int SSL_CTX_set_default_verify_file(SSL_CTX *ctx); int SSL_CTX_set_default_verify_store(SSL_CTX *ctx); -Deprecated since OpenSSL 3.0, can be hidden entirely by defining -B with a suitable version value, see -L: - int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); =head1 DESCRIPTION -SSL_CTX_load_verify_dir(), SSL_CTX_load_verify_file(), -SSL_CTX_load_verify_store() specifies the locations for B, at -which CA certificates for verification purposes are located. The -certificates available via B, B and B are -trusted. +SSL_CTX_load_verify_locations(), SSL_CTX_load_verify_dir(), +SSL_CTX_load_verify_file(), SSL_CTX_load_verify_store() specifies the +locations for B, at which CA certificates for verification purposes +are located. The certificates available via B, B and +B are trusted. SSL_CTX_set_default_verify_paths() specifies that the default locations from which CA certificates are loaded should be used. There is one default directory, @@ -176,7 +172,7 @@ L =head1 COPYRIGHT -Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/SSL_CTX_set_options.pod b/doc/man3/SSL_CTX_set_options.pod index 39cb2ec3..24bf66ad 100644 --- a/doc/man3/SSL_CTX_set_options.pod +++ b/doc/man3/SSL_CTX_set_options.pod @@ -217,6 +217,20 @@ not propose, and servers will not accept the extension. Disable all renegotiation in TLSv1.2 and earlier. Do not send HelloRequest messages, and ignore renegotiation requests via ClientHello. +=item SSL_OP_IGNORE_UNEXPECTED_EOF + +Some TLS implementations do not send the mandatory close_notify alert on +shutdown. If the application tries to wait for the close_notify alert but the +peer closes the connection without sending it, an error is generated. When this +option is enabled the peer does not need to send the close_notify alert and a +closed connection will be treated as if the close_notify alert was received. + +You should only enable this option if the protocol running over TLS +can detect a truncation attack itself, and that the application is checking for +that truncation attack. + +For more information on shutting down a connection, see L. + =item SSL_OP_ALLOW_NO_DHE_KEX In TLSv1.3 allow a non-(ec)dhe based key exchange mode on resumption. This means @@ -367,7 +381,7 @@ secure renegotiation and 0 if it does not. =head1 SEE ALSO -L, L, L, +L, L, L, L L, L, L @@ -380,7 +394,8 @@ OpenSSL 0.9.8m. The B and B options were added in OpenSSL 1.1.1. -The B option was added in OpenSSL 3.0. +The B and B +options were added in OpenSSL 3.0. =head1 COPYRIGHT diff --git a/doc/man3/SSL_CTX_set_psk_client_callback.pod b/doc/man3/SSL_CTX_set_psk_client_callback.pod index 55ffb31c..c7e51f74 100644 --- a/doc/man3/SSL_CTX_set_psk_client_callback.pod +++ b/doc/man3/SSL_CTX_set_psk_client_callback.pod @@ -123,7 +123,9 @@ and it will use that in preference. If no such callback is present then it will check to see if a callback has been set via SSL_CTX_set_psk_client_callback() or SSL_set_psk_client_callback() and use that. In this case the B value will always be NULL and the handshake digest will default to SHA-256 for any returned -PSK. +PSK. TLSv1.3 early data exchanges are possible in PSK connections only with the +B callback, and are not possible with the +B callback. =head1 NOTES @@ -167,7 +169,7 @@ were added in OpenSSL 1.1.1. =head1 COPYRIGHT -Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/SSL_CTX_set_quic_method.pod b/doc/man3/SSL_CTX_set_quic_method.pod new file mode 100644 index 00000000..60bf7049 --- /dev/null +++ b/doc/man3/SSL_CTX_set_quic_method.pod @@ -0,0 +1,232 @@ +=pod + +=head1 NAME + +SSL_QUIC_METHOD, +OSSL_ENCRYPTION_LEVEL, +SSL_CTX_set_quic_method, +SSL_set_quic_method, +SSL_set_quic_transport_params, +SSL_get_peer_quic_transport_params, +SSL_quic_max_handshake_flight_len, +SSL_quic_read_level, +SSL_quic_write_level, +SSL_provide_quic_data, +SSL_process_quic_post_handshake, +SSL_is_quic +- QUIC support + +=head1 SYNOPSIS + + #include + + typedef struct ssl_quic_method_st SSL_QUIC_METHOD; + typedef enum ssl_encryption_level_t OSSL_ENCRYPTION_LEVEL; + + int SSL_CTX_set_quic_method(SSL_CTX *ctx, const SSL_QUIC_METHOD *quic_method); + int SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method); + int SSL_set_quic_transport_params(SSL *ssl, + const uint8_t *params, + size_t params_len); + void SSL_get_peer_quic_transport_params(const SSL *ssl, + const uint8_t **out_params, + size_t *out_params_len); + size_t SSL_quic_max_handshake_flight_len(const SSL *ssl, OSSL_ENCRYPTION_LEVEL level); + OSSL_ENCRYPTION_LEVEL SSL_quic_read_level(const SSL *ssl); + OSSL_ENCRYPTION_LEVEL SSL_quic_write_level(const SSL *ssl); + int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, + const uint8_t *data, size_t len); + int SSL_process_quic_post_handshake(SSL *ssl); + int SSL_is_quic(SSL *ssl); + +=head1 DESCRIPTION + +SSL_CTX_set_quic_method() and SSL_set_quic_method() configures the QUIC methods. +This should only be configured with a minimum version of TLS 1.3. B +must remain valid for the lifetime of B or B. Calling this disables +the SSL_OP_ENABLE_MIDDLEBOX_COMPAT option, which is not required for QUIC. + +SSL_set_quic_transport_params() configures B to send B (of length +B) in the quic_transport_parameters extension in either the +ClientHello or EncryptedExtensions handshake message. This extension will +only be sent if the TLS version is at least 1.3, and for a server, only if +the client sent the extension. The buffer pointed to by B only need be +valid for the duration of the call to this function. + +SSL_get_peer_quic_transport_params() provides the caller with the value of the +quic_transport_parameters extension sent by the peer. A pointer to the buffer +containing the TransportParameters will be put in B<*out_params>, and its +length in B<*out_params_len>. This buffer will be valid for the lifetime of the +B. If no params were received from the peer, B<*out_params_len> will be 0. + +SSL_quic_max_handshake_flight_len() returns the maximum number of bytes +that may be received at the given encryption level. This function should be +used to limit buffering in the QUIC implementation. + +See https://tools.ietf.org/html/draft-ietf-quic-transport-16#section-4.4. + +SSL_quic_read_level() returns the current read encryption level. + +SSL_quic_write_level() returns the current write encryption level. + +SSL_provide_quic_data() provides data from QUIC at a particular encryption +level B. It is an error to call this function outside of the handshake +or with an encryption level other than the current read level. It returns one +on success and zero on error. + +SSL_process_quic_post_handshake() processes any data that QUIC has provided +after the handshake has completed. This includes NewSessionTicket messages +sent by the server. + +SSL_is_quic() indicates whether a connection uses QUIC. + +=head1 NOTES + +These APIs are implementations of BoringSSL's QUIC APIs. + +QUIC acts as an underlying transport for the TLS 1.3 handshake. The following +functions allow a QUIC implementation to serve as the underlying transport as +described in draft-ietf-quic-tls. + +When configured for QUIC, SSL_do_handshake() will drive the handshake as +before, but it will not use the configured B. It will call functions on +B to configure secrets and send data. If data is needed from +the peer, it will return B. When received, the caller +should call SSL_provide_quic_data() and then SSL_do_handshake() to continue +the handshake. After the handshake is complete, the caller should call +SSL_provide_quic_data() for any post-handshake data, followed by +SSL_process_quic_post_handshake() to process it. It is an error to call +SSL_read()/SSL_read_ex() and SSL_write()/SSL_write_ex() in QUIC. + +Note that secrets for an encryption level may be available to QUIC before the +level is active in TLS. Callers should use SSL_quic_read_level() to determine +the active read level for SSL_provide_quic_data(). SSL_do_handshake() will +pass the active write level to add_handshake_data() when writing data. Callers +can use SSL_quic_write_level() to query the active write level when +generating their own errors. + +See https://tools.ietf.org/html/draft-ietf-quic-tls-15#section-4.1 for more +details. + +To avoid DoS attacks, the QUIC implementation must limit the amount of data +being queued up. The implementation can call +SSL_quic_max_handshake_flight_len() to get the maximum buffer length at each +encryption level. + +draft-ietf-quic-tls defines a new TLS extension quic_transport_parameters +used by QUIC for each endpoint to unilaterally declare its supported +transport parameters. draft-ietf-quic-transport (section 7.4) defines the +contents of that extension (a TransportParameters struct) and describes how +to handle it and its semantic meaning. + +OpenSSL handles this extension as an opaque byte string. The caller is +responsible for serializing and parsing it. + +=head2 OSSL_ENCRYPTION_LEVEL + +B (B) represents the +encryption levels: + +=over 4 + +=item ssl_encryption_initial + +The initial encryption level that is used for client and server hellos. + +=item ssl_encryption_early_data + +The encryption level for early data. This is a write-level for the client +and a read-level for the server. + +=item ssl_encryption_handshake + +The encryption level for the remainder of the handshake. + +=item ssl_encryption_application + +The encryption level for the application data. + +=back + +=head2 SSL_QUIC_METHOD + +The B (B) describes the +QUIC methods. + + struct ssl_quic_method_st { + int (*set_encryption_secrets)(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, + const uint8_t *read_secret, + const uint8_t *write_secret, size_t secret_len); + int (*add_handshake_data)(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, + const uint8_t *data, size_t len); + int (*flush_flight)(SSL *ssl); + int (*send_alert)(SSL *ssl, enum ssl_encryption_level_t level, uint8_t alert); + }; + typedef struct ssl_quic_method_st SSL_QUIC_METHOD; + +set_encryption_secrets() configures the read and write secrets for the given +encryption level. This function will always be called before an encryption +level other than B is used. Note, however, that +secrets for a level may be configured before TLS is ready to send or accept +data at that level. + +When reading packets at a given level, the QUIC implementation must send +ACKs at the same level, so this function provides read and write secrets +together. The exception is B, where secrets are +only available in the client to server direction. The other secret will be +NULL. The server acknowledges such data at B, +which will be configured in the same SSL_do_handshake() call. + +This function should use SSL_get_current_cipher() to determine the TLS +cipher suite. + +add_handshake_data() adds handshake data to the current flight at the given +encryption level. It returns one on success and zero on error. + +OpenSSL will pack data from a single encryption level together, but a +single handshake flight may include multiple encryption levels. Callers +should defer writing data to the network until flush_flight() to better +pack QUIC packets into transport datagrams. + +flush_flight() is called when the current flight is complete and should be +written to the transport. Note a flight may contain data at several +encryption levels. + +send_alert() sends a fatal alert at the specified encryption level. + +All QUIC methods return 1 on success and 0 on error. + +=head1 RETURN VALUES + +SSL_CTX_set_quic_method(), +SSL_set_quic_method(), +SSL_set_quic_transport_params(), and +SSL_process_quic_post_handshake() +return 1 on success, and 0 on error. + +SSL_quic_read_level() and SSL_quic_write_level() return the current +encryption level as B (B). + +SSL_quic_max_handshake_flight_len() returns the maximum length of a flight +for a given encryption level. + +SSL_is_quic() returns 1 if QUIC is being used, 0 if not. + +=head1 SEE ALSO + +L, L, L + +=head1 HISTORY + +These functions were added in OpenSSL 3.0.0. + +=head1 COPYRIGHT + +Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/SSL_CTX_set_record_padding_callback.pod b/doc/man3/SSL_CTX_set_record_padding_callback.pod index 3df66218..445953ef 100644 --- a/doc/man3/SSL_CTX_set_record_padding_callback.pod +++ b/doc/man3/SSL_CTX_set_record_padding_callback.pod @@ -16,7 +16,7 @@ SSL_set_block_padding - install callback to specify TLS 1.3 record padding #include void SSL_CTX_set_record_padding_callback(SSL_CTX *ctx, size_t (*cb)(SSL *s, int type, size_t len, void *arg)); - void SSL_set_record_padding_callback(SSL *ssl, size_t (*cb)(SSL *s, int type, size_t len, void *arg)); + int SSL_set_record_padding_callback(SSL *ssl, size_t (*cb)(SSL *s, int type, size_t len, void *arg)); void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg); void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx); @@ -32,6 +32,8 @@ SSL_set_block_padding - install callback to specify TLS 1.3 record padding SSL_CTX_set_record_padding_callback() or SSL_set_record_padding_callback() can be used to assign a callback function I to specify the padding for TLS 1.3 records. The value set in B is copied to a new SSL by SSL_new(). +Kernel TLS is not possible if the record padding callback is set, and the callback +function cannot be set if Kernel TLS is already configured for the current SSL object. SSL_CTX_set_record_padding_callback_arg() and SSL_set_record_padding_callback_arg() assign a value B that is passed to the callback when it is invoked. The value @@ -64,6 +66,9 @@ indicates no padding will be added. A return value that causes the record to exceed the maximum record size (SSL3_RT_MAX_PLAIN_LENGTH) will pad out to the maximum record size. +The SSL_CTX_get_record_padding_callback_arg() function returns 1 on success or 0 if +the callback function is not set because Kernel TLS is configured for the SSL object. + =head1 NOTES The default behavior is to add no padding to the record. @@ -84,6 +89,9 @@ L, L The record padding API was added for TLS 1.3 support in OpenSSL 1.1.1. +The return type of SSL_CTX_set_record_padding_callback() function was +changed to int in OpenSSL 3.0. + =head1 COPYRIGHT Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/SSL_CTX_set_session_ticket_cb.pod b/doc/man3/SSL_CTX_set_session_ticket_cb.pod index 8cdb88cc..2a9576e2 100644 --- a/doc/man3/SSL_CTX_set_session_ticket_cb.pod +++ b/doc/man3/SSL_CTX_set_session_ticket_cb.pod @@ -177,7 +177,7 @@ L =head1 HISTORY -The SSL_CTX_set_session_ticket_cb(), SSSL_SESSION_set1_ticket_appdata() +The SSL_CTX_set_session_ticket_cb(), SSL_SESSION_set1_ticket_appdata() and SSL_SESSION_get_ticket_appdata() functions were added in OpenSSL 1.1.1. =head1 COPYRIGHT diff --git a/doc/man3/SSL_CTX_set_tlsext_ticket_key_cb.pod b/doc/man3/SSL_CTX_set_tlsext_ticket_key_cb.pod index 99aaf7a5..ae2ee2b4 100644 --- a/doc/man3/SSL_CTX_set_tlsext_ticket_key_cb.pod +++ b/doc/man3/SSL_CTX_set_tlsext_ticket_key_cb.pod @@ -49,7 +49,7 @@ ticket information or it starts a full TLS handshake to create a new session ticket. Before the callback function is started I and I have been -initialised with L and L +initialised with L and L respectively. For new sessions tickets, when the client doesn't present a session ticket, or @@ -66,7 +66,7 @@ maximum IV length is B bytes defined in B. The initialization vector I should be a random value. The cipher context I should use the initialisation vector I. The cipher context can be set using L. The hmac context and digest can be set using -L with the B and +L with the B and B parameters respectively. When the client presents a session ticket, the callback function with be called @@ -76,7 +76,7 @@ the session ticket. The OpenSSL library expects that the I will be used to retrieve a cryptographic parameters and that the cryptographic context I will be set with the retrieved parameters and the initialization vector I. using a function like L. The key material and -digest for I need to be set using L with the +digest for I need to be set using L with the B and B parameters respectively. If the I is still valid but a renewal of the ticket is required the @@ -120,8 +120,8 @@ The SSL_CTX_set_tlsext_ticket_key_cb() function is identical to SSL_CTX_set_tlsext_ticket_key_evp_cb() except that it takes a deprecated HMAC_CTX pointer instead of an EVP_MAC_CTX one. Before this callback function is started I will have been -initialised with L and the digest set with -L. +initialised with L and the digest set with +L. The I key material can be set using L. =head1 NOTES @@ -185,7 +185,7 @@ Reference Implementation: params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, "sha256", 0); params[2] = OSSL_PARAM_construct_end(); - EVP_MAC_CTX_set_params(hctx, params); + EVP_MAC_set_ctx_params(hctx, params); return 1; @@ -200,7 +200,7 @@ Reference Implementation: params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, "sha256", 0); params[2] = OSSL_PARAM_construct_end(); - EVP_MAC_CTX_set_params(hctx, params); + EVP_MAC_set_ctx_params(hctx, params); EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key->aes_key, iv); diff --git a/doc/man3/SSL_CTX_use_psk_identity_hint.pod b/doc/man3/SSL_CTX_use_psk_identity_hint.pod index 937c91a3..69f7e9d4 100644 --- a/doc/man3/SSL_CTX_use_psk_identity_hint.pod +++ b/doc/man3/SSL_CTX_use_psk_identity_hint.pod @@ -83,7 +83,9 @@ via SSL_CTX_set_psk_find_session_callback() or SSL_set_psk_find_session_callback and it will use that in preference. If no such callback is present then it will check to see if a callback has been set via SSL_CTX_set_psk_server_callback() or SSL_set_psk_server_callback() and use that. In this case the handshake digest -will default to SHA-256 for any returned PSK. +will default to SHA-256 for any returned PSK. TLSv1.3 early data exchanges are +possible in PSK connections only with the B +callback, and are not possible with the B callback. A connection established via a TLSv1.3 PSK will appear as if session resumption has occurred so that L will return true. @@ -144,7 +146,7 @@ were added in OpenSSL 1.1.1. =head1 COPYRIGHT -Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/SSL_get_error.pod b/doc/man3/SSL_get_error.pod index 8d081a5e..07466731 100644 --- a/doc/man3/SSL_get_error.pod +++ b/doc/man3/SSL_get_error.pod @@ -25,6 +25,15 @@ other OpenSSL function calls should appear in between. The current thread's error queue must be empty before the TLS/SSL I/O operation is attempted, or SSL_get_error() will not work reliably. +=head1 NOTES + +Some TLS implementations do not send a close_notify alert on shutdown. + +On an unexpected EOF, versions before OpenSSL 3.0 returned +B, nothing was added to the error stack, and errno was 0. +Since OpenSSL 3.0 the returned error is B with a meaningful +error on the error stack. + =head1 RETURN VALUES The following return values can currently occur: @@ -44,6 +53,9 @@ No more data can be read. Note that B does not necessarily indicate that the underlying transport has been closed. +This error can also appear when the option B +is set. See L for more details. + =item SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE The operation did not complete and can be retried later. @@ -166,7 +178,7 @@ The SSL_ERROR_WANT_CLIENT_HELLO_CB error code was added in OpenSSL 1.1.1. =head1 COPYRIGHT -Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/SSL_read_early_data.pod b/doc/man3/SSL_read_early_data.pod index 4f159363..460a436e 100644 --- a/doc/man3/SSL_read_early_data.pod +++ b/doc/man3/SSL_read_early_data.pod @@ -58,10 +58,11 @@ SSL_set_allow_early_data_cb These functions are used to send and receive early data where TLSv1.3 has been negotiated. Early data can be sent by the client immediately after its initial ClientHello without having to wait for the server to complete the handshake. -Early data can only be sent if a session has previously been established with -the server, and the server is known to support it. Additionally these functions -can be used to send data from the server to the client when the client has not -yet completed the authentication stage of the handshake. +Early data can be sent if a session has previously been established with the +server or when establishing a new session using an out-of-band PSK, and only +when the server is known to support it. Additionally these functions can be used +to send data from the server to the client when the client has not yet completed +the authentication stage of the handshake. Early data has weaker security properties than other data sent over an SSL/TLS connection. In particular the data does not have forward secrecy. There are also @@ -364,7 +365,7 @@ All of the functions described above were added in OpenSSL 1.1.1. =head1 COPYRIGHT -Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/SSL_shutdown.pod b/doc/man3/SSL_shutdown.pod index 25191130..34469bae 100644 --- a/doc/man3/SSL_shutdown.pod +++ b/doc/man3/SSL_shutdown.pod @@ -83,8 +83,10 @@ message, otherwise an unexpected EOF will be reported. There are implementations that do not send the required close_notify alert. If there is a need to communicate with such an implementation, and it's clear that all data has been received, do not wait for the peer's close_notify alert. -Waiting for the close_notify alert when the peer just closes the connection will -result in an error being generated. +Waiting for the close_notify alert when the peer just closes the connection +will result in an error being generated. +The error can be ignored using the B. +For more information see L. =head2 First to close the connection @@ -159,7 +161,7 @@ It can also occur when not all data was read using SSL_read(). L, L, L, L, -L, +L, L L, L, L, L diff --git a/doc/man3/X509_PUBKEY_new.pod b/doc/man3/X509_PUBKEY_new.pod index 551031b8..76034fa8 100644 --- a/doc/man3/X509_PUBKEY_new.pod +++ b/doc/man3/X509_PUBKEY_new.pod @@ -5,8 +5,8 @@ X509_PUBKEY_new, X509_PUBKEY_free, X509_PUBKEY_dup, X509_PUBKEY_set, X509_PUBKEY_get0, X509_PUBKEY_get, d2i_PUBKEY, i2d_PUBKEY, d2i_PUBKEY_bio, d2i_PUBKEY_fp, -i2d_PUBKEY_fp, i2d_PUBKEY_bio, X509_PUBKEY_set0_param, -X509_PUBKEY_get0_param - SubjectPublicKeyInfo public key functions +i2d_PUBKEY_fp, i2d_PUBKEY_bio, X509_PUBKEY_set0_param, X509_PUBKEY_get0_param, +X509_PUBKEY_eq - SubjectPublicKeyInfo public key functions =head1 SYNOPSIS @@ -17,8 +17,8 @@ X509_PUBKEY_get0_param - SubjectPublicKeyInfo public key functions X509_PUBKEY *X509_PUBKEY_dup(const X509_PUBKEY *a); int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); - EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key); - EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); + EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key); + EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key); EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length); int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp); @@ -34,7 +34,8 @@ X509_PUBKEY_get0_param - SubjectPublicKeyInfo public key functions unsigned char *penc, int penclen); int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen, - X509_ALGOR **pa, X509_PUBKEY *pub); + X509_ALGOR **pa, const X509_PUBKEY *pub); + int X509_PUBKEY_eq(X509_PUBKEY *a, X509_PUBKEY *b); =head1 DESCRIPTION @@ -81,6 +82,8 @@ parameters is not required it can be set to B. All of the retrieved pointers are internal and must not be freed after the call. +X509_PUBKEY_eq() compares two B values. + =head1 NOTES The B functions can be used to encode and decode public keys @@ -104,15 +107,21 @@ structure or B if an error occurs. X509_PUBKEY_set(), X509_PUBKEY_set0_param() and X509_PUBKEY_get0_param() return 1 for success and 0 if an error occurred. +X509_PUBKEY_eq() returns 1 for equal, 0 for different, and < 0 on error. + =head1 SEE ALSO L, L, L, +=head1 HISTORY + +The X509_PUBKEY_eq() function was added in OpenSSL 3.0. + =head1 COPYRIGHT -Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/X509_STORE_add_cert.pod b/doc/man3/X509_STORE_add_cert.pod index d41f2ae5..ce50e368 100644 --- a/doc/man3/X509_STORE_add_cert.pod +++ b/doc/man3/X509_STORE_add_cert.pod @@ -32,8 +32,6 @@ X509_STORE_load_locations int X509_STORE_load_path(X509_STORE *ctx, const char *dir); int X509_STORE_load_store(X509_STORE *ctx, const char *uri); -Deprecated: - int X509_STORE_load_locations(X509_STORE *ctx, const char *file, const char *dir); diff --git a/doc/man3/X509_dup.pod b/doc/man3/X509_dup.pod index 16c99357..a92d8209 100644 --- a/doc/man3/X509_dup.pod +++ b/doc/man3/X509_dup.pod @@ -81,7 +81,11 @@ IPAddressOrRange_free, IPAddressOrRange_new, IPAddressRange_free, IPAddressRange_new, +ISSUER_SIGN_TOOL_free, +ISSUER_SIGN_TOOL_it, +ISSUER_SIGN_TOOL_new, ISSUING_DIST_POINT_free, +ISSUING_DIST_POINT_it, ISSUING_DIST_POINT_new, NAME_CONSTRAINTS_free, NAME_CONSTRAINTS_new, @@ -252,6 +256,7 @@ TS_TST_INFO_new, USERNOTICE_free, USERNOTICE_new, X509_ALGOR_free, +X509_ALGOR_it, X509_ALGOR_new, X509_ATTRIBUTE_dup, X509_ATTRIBUTE_free, diff --git a/doc/man3/X509_get0_distinguishing_id.pod b/doc/man3/X509_get0_distinguishing_id.pod index 20a67410..7db260cd 100644 --- a/doc/man3/X509_get0_distinguishing_id.pod +++ b/doc/man3/X509_get0_distinguishing_id.pod @@ -21,7 +21,9 @@ The Distinguishing ID is defined in FIPS 196 as follows: =over 4 -I: information which unambiguously distinguishes +=item I + +Information which unambiguously distinguishes an entity in the authentication process. =back diff --git a/doc/man3/X509_load_http.pod b/doc/man3/X509_load_http.pod deleted file mode 100644 index 483597b5..00000000 --- a/doc/man3/X509_load_http.pod +++ /dev/null @@ -1,63 +0,0 @@ -=pod - -=head1 NAME - -X509_load_http, -X509_http_nbio, -X509_CRL_load_http, -X509_CRL_http_nbio -- certificate and CRL loading functions - -=head1 SYNOPSIS - - #include - - X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout); - X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout); - - #define X509_http_nbio(url) - #define X509_CRL_http_nbio(url) - -=head1 DESCRIPTION - -X509_load_http() and X509_CRL_load_http() loads a certificate or a CRL, -respectively, in ASN.1 format using HTTP from the given B. - -If B is given and B is NULL then this BIO is used instead of an -internal one for connecting, writing the request, and reading the response. -If both B and B are given (which may be memory BIOs, for instance) -then no explicit connection is attempted, -B is used for writing the request, and B for reading the response. - -If the B parameter is > 0 this indicates the maximum number of seconds -to wait until the transfer is complete. -A value of 0 enables waiting indefinitely, -while a value < 0 immediately leads to a timeout condition. - -X509_http_nbio() and X509_CRL_http_nbio() are macros for backward compatibility -that have the same effect as the functions above but with infinite timeout -and without the possibility to specify custom BIOs. - -=head1 RETURN VALUES - -On success the function yield the loaded value, else NULL. -Error conditions include connection/transfer timeout, parse errors, etc. - -=head1 SEE ALSO - -L - -=head1 HISTORY - -X509_load_http() and X509_CRL_load_http() were added in OpenSSL 3.0. - -=head1 COPYRIGHT - -Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the Apache License 2.0 (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/doc/man3/d2i_X509.pod b/doc/man3/d2i_X509.pod index 03548b23..4dea774f 100644 --- a/doc/man3/d2i_X509.pod +++ b/doc/man3/d2i_X509.pod @@ -75,6 +75,7 @@ d2i_IPAddressChoice, d2i_IPAddressFamily, d2i_IPAddressOrRange, d2i_IPAddressRange, +d2i_ISSUER_SIGN_TOOL, d2i_ISSUING_DIST_POINT, d2i_NAMING_AUTHORITY, d2i_NETSCAPE_CERT_SEQUENCE, @@ -267,6 +268,7 @@ i2d_IPAddressChoice, i2d_IPAddressFamily, i2d_IPAddressOrRange, i2d_IPAddressRange, +i2d_ISSUER_SIGN_TOOL, i2d_ISSUING_DIST_POINT, i2d_NAMING_AUTHORITY, i2d_NETSCAPE_CERT_SEQUENCE, diff --git a/doc/man5/fips_config.pod b/doc/man5/fips_config.pod index 0fb7e3ef..9f7650f2 100644 --- a/doc/man5/fips_config.pod +++ b/doc/man5/fips_config.pod @@ -6,26 +6,36 @@ fips_config - OpenSSL FIPS configuration =head1 DESCRIPTION -A separate configuration file containing data related to FIPS 'self tests' is -written to during installation time. -This data is used for 2 purposes when the fips module is loaded: +A separate configuration file, using the OpenSSL L syntax, +is used to hold information about the FIPS module. This includes a digest +of the shared library file, and status about the self-testing. +This data is used automatically by the module itself for two +purposes: =over 4 -=item - Verify the module's checksum each time the fips module loads. +=item - Run the startup FIPS self-test known answer tests (KATS). -=item - Run the startup FIPS self test KATS (known answer tests). -This only needs to be run once during installation. +This is done once, at installation time. + +=item - Verify the module's checksum. + +This is done each time the module is used. =back -The supported options are: +This file is generated by the L program, and +used internally by the FIPS module during its initialization. + +The following options are supported. They should all appear in a section +whose name is identified by the B option in the B +section, as desribed in L. =over 4 -=item B +=item B -The calculated MAC of the module file +The calculated MAC of the FIPS provider file. =item B @@ -33,26 +43,26 @@ A version number for the fips install process. Should be 1. =item B -The install status indicator description that will be verified. -If this field is not present the FIPS self tests will run when the fips module -loads. -This value should only be written to after the FIPS module has +An indicator that the self-tests were run. +This should only be written after the module has successfully passed its self tests during installation. +If this field is not present, then the self tests will run when the module +loads. -=item B +=item B -The calculated MAC of the install status indicator. -It is initially empty and is written to at the same time as the install_status. +A MAC of the value of the B option, to prevent accidental +changes to that value. +It is written-to at the same time as B is updated. =back For example: [fips_install] - install-version = 1 - module-checksum = 41:D0:FA:C2:5D:41:75:CD:7D:C3:90:55:6F:A4:DC - install-checksum = FE:10:13:5A:D3:B4:C7:82:1B:1E:17:4C:AC:84:0C + module-mac = 41:D0:FA:C2:5D:41:75:CD:7D:C3:90:55:6F:A4:DC + install-mac = FE:10:13:5A:D3:B4:C7:82:1B:1E:17:4C:AC:84:0C install-status = INSTALL_SELF_TEST_KATS_RUN =head1 SEE ALSO @@ -61,7 +71,7 @@ L =head1 COPYRIGHT -Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man5/x509v3_config.pod b/doc/man5/x509v3_config.pod index 2d375735..88a336c3 100644 --- a/doc/man5/x509v3_config.pod +++ b/doc/man5/x509v3_config.pod @@ -6,112 +6,148 @@ x509v3_config - X509 V3 certificate extension configuration format =head1 DESCRIPTION -Several of the OpenSSL utilities can add extensions to a certificate or +Several OpenSSL commands can add extensions to a certificate or certificate request based on the contents of a configuration file. +The syntax of this file is described in L. +The commands typically have an option to specify the name of the configuration +file, and a section within that file; see the documentation of the +individual command for details. -Typically the application will contain an option to point to an extension -section. Each line of the extension section takes the form: +This page uses B as the name of the section, when needed +in examples. - extension_name=[critical,] extension_options +Each entry in the extension section takes the form: -If B is present then the extension will be critical. + name = [critical, ]value(s) -The format of B depends on the value of B. +If B is present then the extension will be marked as critical. -There are four main types of extension: I extensions, I -extensions, I and I extensions. +The format of B depends on the value of B, many have a +type-value pairing where the type and value are separated by a colon. +There are four main types of extension: + + string + multi-valued + raw + arbitrary + +Each is described in the following paragraphs. String extensions simply have a string which contains either the value itself or how it is obtained. -For example: - - nsComment="This is a Comment" - Multi-valued extensions have a short form and a long form. The short form -is a list of names and values: +is a commma-separated list of names and values: - basicConstraints=critical,CA:true,pathlen:1 + basicConstraints = critical, CA:true, pathlen:1 The long form allows the values to be placed in a separate section: - basicConstraints=critical,@bs_section + [extensions] + basicConstraints = critical, @basic_constraints - [bs_section] - - CA=true - pathlen=1 + [basic_constraints] + CA = true + pathlen = 1 Both forms are equivalent. -The syntax of raw extensions is governed by the extension code: it can -for example contain data in multiple sections. The correct syntax to -use is defined by the extension code itself: check out the certificate -policies extension for an example. +If an extension is multi-value and a field value must contain a comma the long +form must be used otherwise the comma would be misinterpreted as a field +separator. For example: -If an extension type is unsupported then the I extension syntax + subjectAltName = URI:ldap://somehost.com/CN=foo,OU=bar + +will produce an error but the equivalent form: + + [extensions] + subjectAltName = @subject_alt_section + + [subject_alt_section] + subjectAltName = URI:ldap://somehost.com/CN=foo,OU=bar + +is valid. + +OpenSSL does not support multiple occurences of the same field within a +section. In this example: + + [extensions] + subjectAltName = @alt_section + + [alt_section] + email = steve@here + email = steve@there + +will only recognize the last value. To specify multiple values append a +numeric identifier, as shown here: + + [extensions] + subjectAltName = @alt_section + + [alt_section] + email.1 = steve@here + email.2 = steve@there + +The syntax of raw extensions is defined by the source code that parses +the extension but should be documened. +See L for an example of a raw extension. + +If an extension type is unsupported, then the I extension syntax must be used, see the L section for more details. =head1 STANDARD EXTENSIONS -The following sections describe each supported extension in detail. +The following sections describe the syntax of each supported extension. +They do not define the semantics of the extension. =head2 Basic Constraints -This is a multi valued extension which indicates whether a certificate is -a CA certificate. The first (mandatory) name is B followed by B or +This is a multi-valued extension which indicates whether a certificate is +a CA certificate. The first value is B followed by B or B. If B is B then an optional B name followed by a non-negative value can be included. For example: - basicConstraints=CA:TRUE + basicConstraints = CA:TRUE - basicConstraints=CA:FALSE + basicConstraints = CA:FALSE - basicConstraints=critical,CA:TRUE, pathlen:0 - -A CA certificate B include the basicConstraints value with the CA field -set to TRUE. An end user certificate must either set CA to FALSE or exclude the -extension entirely. Some software may require the inclusion of basicConstraints -with CA set to FALSE for end entity certificates. - -The pathlen parameter indicates the maximum number of CAs that can appear -below this one in a chain. So if you have a CA with a pathlen of zero it can -only be used to sign end user certificates and not further CAs. + basicConstraints = critical, CA:TRUE, pathlen:1 +A CA certificate I include the B name with the B +parameter set to B. An end-user certificate must either have B +or omit the extension entirely. +The B parameter specifies the maximum number of CAs that can appear +below this one in a chain. A B of zero means the CA cannot sign +any sub-CA's, and can only sign end-entity certificates. =head2 Key Usage -Key usage is a multi valued extension consisting of a list of names of the -permitted key usages. - -The supported names are: digitalSignature, nonRepudiation, keyEncipherment, -dataEncipherment, keyAgreement, keyCertSign, cRLSign, encipherOnly -and decipherOnly. +Key usage is a multi-valued extension consisting of a list of names of +the permitted key usages. The defined values are: C, +C, C, C, C, +C, C, C, and C. Examples: - keyUsage=digitalSignature, nonRepudiation - - keyUsage=critical, keyCertSign + keyUsage = digitalSignature, nonRepudiation + keyUsage = critical, keyCertSign =head2 Extended Key Usage -This extensions consists of a list of usages indicating purposes for which -the certificate public key can be used for, - -These can either be object short names or the dotted numerical form of OIDs. -While any OID can be used only certain values make sense. In particular the -following PKIX, NS and MS values are meaningful: +This extension consists of a list of values indicating purposes for which +the certificate public key can be used for, Each value can be either a +short text name or an OID. +The following text names, and their intended meaning, are known: Value Meaning ----- ------- - serverAuth SSL/TLS Web Server Authentication. - clientAuth SSL/TLS Web Client Authentication. - codeSigning Code signing. - emailProtection E-mail Protection (S/MIME). + serverAuth SSL/TLS Web Server Authentication + clientAuth SSL/TLS Web Client Authentication + codeSigning Code signing + emailProtection E-mail Protection (S/MIME) timeStamping Trusted Timestamping OCSPSigning OCSP Signing ipsecIKE ipsec Internet Key Exchange @@ -122,242 +158,267 @@ following PKIX, NS and MS values are meaningful: Examples: - extendedKeyUsage=critical,codeSigning,1.2.3.4 - extendedKeyUsage=serverAuth,clientAuth + extendedKeyUsage = critical, codeSigning, 1.2.3.4 + extendedKeyUsage = serverAuth, clientAuth =head2 Subject Key Identifier -This is really a string extension and can take two possible values. Either -the word B which will automatically follow the guidelines in RFC3280 -or a hex string giving the extension value to include. The use of the hex -string is strongly discouraged. +This is a string extension with one of two legal values. If it is the word +B, then OpenSSL will follow the process in RFC 5280 to calculate the +hash value. +Otherwise, the value should be a hex string to output directly, however this +is strongly discouraged. Example: - subjectKeyIdentifier=hash - + subjectKeyIdentifier = hash =head2 Authority Key Identifier -The authority key identifier extension permits two options. keyid and issuer: -both can take the optional value "always". +This extension has two options, B and B. Either or both +can have the value B, indicated by putting a colon between +the option and its value. -If the keyid option is present an attempt is made to copy the subject key -identifier from the parent certificate. If the value "always" is present -then an error is returned if the option fails. - -The issuer option copies the issuer and serial number from the issuer -certificate. This will only be done if the keyid option fails or -is not included unless the "always" flag will always include the value. - -Example: - - authorityKeyIdentifier=keyid,issuer - - -=head2 Subject Alternative Name - -The subject alternative name extension allows various literal values to be -included in the configuration file. These include B (an email address) -B a uniform resource indicator, B (a DNS domain name), B (a -registered ID: OBJECT IDENTIFIER), B (an IP address), B -(a distinguished name) and otherName. - -The email option include a special 'copy' value. This will automatically -include any email addresses contained in the certificate subject name in -the extension. - -The IP address used in the B options can be in either IPv4 or IPv6 format. - -The value of B should point to a section containing the distinguished -name to use as a set of name value pairs. Multi values AVAs can be formed by -prefacing the name with a B<+> character. - -otherName can include arbitrary data associated with an OID: the value -should be the OID followed by a semicolon and the content in standard -L format. +If B is present, than an attempt is made to copy the subject key +identifier from the parent certificate. If the value B is present, +then an error can be returned if the option fails. If B is present, +an attempt is made to copy the issuer and serial number from the parent +certificate. This is done if the B option fails, or if B +has B specified. Examples: - subjectAltName=email:copy,email:my@other.address,URI:http://my.url.here/ - subjectAltName=IP:192.168.7.1 - subjectAltName=IP:13::17 - subjectAltName=email:my@other.address,RID:1.2.3.4 - subjectAltName=otherName:1.2.3.4;UTF8:some other identifier + authorityKeyIdentifier = keyid, issuer - subjectAltName=dirName:dir_sect + authorityKeyIdentifier = keyid, issuer:always + +=head2 Subject Alternative Name + +This is a multi-valued extension that supports several types of name +identifier, including +B (an email address), +B (a uniform resource indicator), +B (a DNS domain name), +B (a registered ID: OBJECT IDENTIFIER), +B (an IP address), +B (a distinguished name), +and B. +The syntax of each is described in the following paragraphs. + +The B option has a special C value, which will automatically +include any email addresses contained in the certificate subject name in +the extension. + +The IP address used in the B option can be in either IPv4 or IPv6 format. + +The value of B is specifies the configuration section containing +the distinguished name to use, as a set of name-value pairs. +Multi-valued AVAs can be formed by prefacing the name with a B<+> character. + +The value of B can include arbitrary data associated with an OID; +the value should be the OID followed by a semicolon and the content in specified +using the syntax in L. + +Examples: + + subjectAltName = email:copy, email:my@other.address, URI:http://my.url.here/ + + subjectAltName = IP:192.168.7.1 + + subjectAltName = IP:13::17 + + subjectAltName = email:my@other.address, RID:1.2.3.4 + + subjectAltName = otherName:1.2.3.4;UTF8:some other identifier + + [extensions] + subjectAltName = dirName:dir_sect [dir_sect] - C=UK - O=My Organization - OU=My Unit - CN=My Name - + C = UK + O = My Organization + OU = My Unit + CN = My Name =head2 Issuer Alternative Name -The issuer alternative name option supports all the literal options of -subject alternative name. It does B support the email:copy option because -that would not make sense. It does support an additional issuer:copy option -that will copy all the subject alternative name values from the issuer -certificate (if possible). +This extension supports most of the options of subject alternative name; +it does not support B. +It also adds B as an allowed value, which copies any subject +alternative names from the issuer certificate, if possible. Example: issuerAltName = issuer:copy - =head2 Authority Info Access -The authority information access extension gives details about how to access -certain information relating to the CA. Its syntax is accessOID;location -where I has the same syntax as subject alternative name (except -that email:copy is not supported). accessOID can be any valid OID but only -certain values are meaningful, for example OCSP and caIssuers. +This extension gives details about how to retrieve information that +related to the certificate that the CA makes available. The syntax is +B, where B is an object identifier +(although only a few values are well-known) and B has the same +syntax as subject alternative name (except that B is not supported). -Example: +Examples: authorityInfoAccess = OCSP;URI:http://ocsp.my.host/ - authorityInfoAccess = caIssuers;URI:http://my.ca/ca.html - =head2 CRL distribution points -This is a multi-valued extension whose options can be either in name:value pair -using the same form as subject alternative name or a single value representing -a section name containing all the distribution point fields. +This is a multi-valued extension whose values can be either a name-value +pair using the same form as subject alternative name or a single value +specifying the section name containing all the distribution point values. -For a name:value pair a new DistributionPoint with the fullName field set to -the given value both the cRLissuer and reasons fields are omitted in this case. +When a name-value pair is used, a DistributionPoint extension will +be set with the given value as the fullName field as the distributionPoint +value, and the reasons and cRLIssuer fields will be omitted. -In the single option case the section indicated contains values for each -field. In this section: +When a single option is used, the value specifies the section, and that +section can have the following items: -If the name is "fullname" the value field should contain the full name -of the distribution point in the same format as subject alternative name. +=over 4 -If the name is "relativename" then the value field should contain a section -name whose contents represent a DN fragment to be placed in this field. +=item fullname -The name "CRLIssuer" if present should contain a value for this field in -subject alternative name format. +The full name of the distribution point, in the same format as the subject +alternative name. -If the name is "reasons" the value field should consist of a comma -separated field containing the reasons. Valid reasons are: "keyCompromise", -"CACompromise", "affiliationChanged", "superseded", "cessationOfOperation", -"certificateHold", "privilegeWithdrawn" and "AACompromise". +=item relativename +The value is taken as a distinguished name fragment that is set as the +value of the nameRelativeToCRLIssuer field. + +=item CRLIssuer + +The value must in the same format as the subject alternative name. + +=item reasons + +A multi-value field that contains the reasons for revocation. The recognized +values are: C, C, C, +C, C, C, +C, and C. + +=back + +Only one of B or B should be specified. Simple examples: - crlDistributionPoints=URI:http://myhost.com/myca.crl - crlDistributionPoints=URI:http://my.com/my.crl,URI:http://oth.com/my.crl + crlDistributionPoints = URI:http://myhost.com/myca.crl + + crlDistributionPoints = URI:http://my.com/my.crl, URI:http://oth.com/my.crl Full distribution point example: - crlDistributionPoints=crldp1_section + [extensions] + crlDistributionPoints = crldp1_section [crldp1_section] - - fullname=URI:http://myhost.com/myca.crl - CRLissuer=dirName:issuer_sect - reasons=keyCompromise, CACompromise + fullname = URI:http://myhost.com/myca.crl + CRLissuer = dirName:issuer_sect + reasons = keyCompromise, CACompromise [issuer_sect] - C=UK - O=Organisation - CN=Some Name + C = UK + O = Organisation + CN = Some Name =head2 Issuing Distribution Point -This extension should only appear in CRLs. It is a multi valued extension +This extension should only appear in CRLs. It is a multi-valued extension whose syntax is similar to the "section" pointed to by the CRL distribution -points extension with a few differences. +points extension. The following names have meaning: -The names "reasons" and "CRLissuer" are not recognized. +=over 4 -The name "onlysomereasons" is accepted which sets this field. The value is -in the same format as the CRL distribution point "reasons" field. +=item fullname -The names "onlyuser", "onlyCA", "onlyAA" and "indirectCRL" are also accepted -the values should be a boolean value (TRUE or FALSE) to indicate the value of -the corresponding field. +The full name of the distribution point, in the same format as the subject +alternative name. + +=item relativename + +The value is taken as a distinguished name fragment that is set as the +value of the nameRelativeToCRLIssuer field. + +=item onlysomereasons + +A multi-value field that contains the reasons for revocation. The recognized +values are: C, C, C, +C, C, C, +C, and C. + +=item onlyuser, onlyCA, onlyAA, indirectCRL + +The value for each of these names is a boolean. + +=back Example: - issuingDistributionPoint=critical, @idp_section + [extensions] + issuingDistributionPoint = critical, @idp_section [idp_section] - - fullname=URI:http://myhost.com/myca.crl - indirectCRL=TRUE - onlysomereasons=keyCompromise, CACompromise - - [issuer_sect] - C=UK - O=Organisation - CN=Some Name - + fullname = URI:http://myhost.com/myca.crl + indirectCRL = TRUE + onlysomereasons = keyCompromise, CACompromise =head2 Certificate Policies -This is a I extension. All the fields of this extension can be set by -using the appropriate syntax. +This is a I extension that supports all of the defined fields of the +certificate extension. -If you follow the PKIX recommendations and just using one OID then you just -include the value of that OID. Multiple OIDs can be set separated by commas, -for example: +Policies without qualifiers are specified by giving the OID. +Multiple policies are comma-separated. For example: - certificatePolicies= 1.2.4.5, 1.1.3.4 + certificatePolicies = 1.2.4.5, 1.1.3.4 -If you wish to include qualifiers then the policy OID and qualifiers need to -be specified in a separate section: this is done by using the @section syntax -instead of a literal OID value. +To include policy qualifiers, use the "@section" syntax to point to a +section that specifies all the information. The section referred to must include the policy OID using the name -policyIdentifier, cPSuri qualifiers can be included using the syntax: +B. cPSuri qualifiers can be included using the syntax: - CPS.nnn=value + CPS.nnn = value + +where C is a number. userNotice qualifiers can be set using the syntax: - userNotice.nnn=@notice + userNotice.nnn = @notice The value of the userNotice qualifier is specified in the relevant section. -This section can include explicitText, organization and noticeNumbers +This section can include B, B, and B options. explicitText and organization are text strings, noticeNumbers is a comma separated list of numbers. The organization and noticeNumbers options -(if included) must BOTH be present. If you use the userNotice option with IE5 -then you need the 'ia5org' option at the top level to modify the encoding: -otherwise it will not be interpreted properly. +(if included) must BOTH be present. Some software might require +the B option at the top level; this changes the encoding from +Displaytext to IA5String. Example: - certificatePolicies=ia5org,1.2.3.4,1.5.6.7.8,@polsect + [extensions] + certificatePolicies = ia5org, 1.2.3.4, 1.5.6.7.8, @polsect [polsect] - policyIdentifier = 1.3.5.8 - CPS.1="http://my.host.name/" - CPS.2="http://my.your.name/" - userNotice.1=@notice + CPS.1 = "http://my.host.name/" + CPS.2 = "http://my.your.name/" + userNotice.1 = @notice [notice] + explicitText = "Explicit Text Here" + organization = "Organisation Name" + noticeNumbers = 1, 2, 3, 4 - explicitText="Explicit Text Here" - organization="Organisation Name" - noticeNumbers=1,2,3,4 - -The B option changes the type of the I field. In RFC2459 -it can only be of type DisplayText. In RFC3280 IA5String is also permissible. -Some software (for example some versions of MSIE) may require ia5org. - -ASN1 type of explicitText can be specified by prepending B, -B or B prefix followed by colon. For example: +The character encoding of explicitText can be specified by prefixing the +value with B, B, or B followed by colon. For example: [notice] - explicitText="UTF8:Explicit Text Here" + explicitText = "UTF8:Explicit Text Here" =head2 Policy Constraints @@ -369,7 +430,6 @@ Example: policyConstraints = requireExplicitPolicy:3 - =head2 Inhibit Any Policy This is a string extension whose value must be a non negative integer. @@ -378,33 +438,31 @@ Example: inhibitAnyPolicy = 2 - =head2 Name Constraints -The name constraints extension is a multi-valued extension. The name should +This is a multi-valued extension. The name should begin with the word B or B followed by a B<;>. The rest of -the name and the value follows the syntax of subjectAltName except email:copy +the name and the value follows the syntax of subjectAltName except +B is not supported and the B form should consist of an IP addresses and subnet mask separated by a B. Examples: - nameConstraints=permitted;IP:192.168.0.0/255.255.0.0 + nameConstraints = permitted;IP:192.168.0.0/255.255.0.0 - nameConstraints=permitted;email:.somedomain.com - - nameConstraints=excluded;email:.com + nameConstraints = permitted;email:.somedomain.com + nameConstraints = excluded;email:.com =head2 OCSP No Check -The OCSP No Check extension is a string extension but its value is ignored. +This is a string extension. It is parsed, but ignored. Example: noCheck = ignored - =head2 TLS Feature (aka Must Staple) This is a multi-valued extension consisting of a list of TLS extension @@ -418,7 +476,6 @@ Example: tlsfeature = status_request - =head1 DEPRECATED EXTENSIONS The following extensions are non standard, Netscape specific and largely @@ -428,16 +485,10 @@ obsolete. Their use in new applications is discouraged. Netscape Comment (B) is a string extension containing a comment which will be displayed when the certificate is viewed in some browsers. - -Example: - - nsComment = "Some Random Comment" - -Other supported extensions in this category are: B, +Other extensions of this type are: B, B, B, B, B and B. - =head2 Netscape Certificate Type This is a multi-valued extensions which consists of a list of flags to be @@ -448,7 +499,6 @@ now used instead. Acceptable values for nsCertType are: B, B, B, B, B, B, B, B. - =head1 ARBITRARY EXTENSIONS If an extension is not supported by the OpenSSL code then it must be encoded @@ -462,26 +512,25 @@ The first way is to use the word ASN1 followed by the extension content using the same syntax as L. For example: - 1.2.3.4=critical,ASN1:UTF8String:Some random data - - 1.2.3.4=ASN1:SEQUENCE:seq_sect + [extensions] + 1.2.3.4 = critical, ASN1:UTF8String:Some random data + 1.2.3.4.1 = ASN1:SEQUENCE:seq_sect [seq_sect] - field1 = UTF8:field1 field2 = UTF8:field2 It is also possible to use the word DER to include the raw encoded data in any extension. - 1.2.3.4=critical,DER:01:02:03:04 - 1.2.3.4=DER:01020304 + 1.2.3.4 = critical, DER:01:02:03:04 + 1.2.3.4.1 = DER:01020304 The value following DER is a hex dump of the DER encoding of the extension Any extension can be placed in this form to override the default behaviour. For example: - basicConstraints=critical,DER:00:01:02:03 + basicConstraints = critical, DER:00:01:02:03 =head1 WARNINGS @@ -491,41 +540,7 @@ purposes prohibited by their extensions because a specific application does not recognize or honour the values of the relevant extensions. The DER and ASN1 options should be used with caution. It is possible to create -totally invalid extensions if they are not used carefully. - -=head1 NOTES - -If an extension is multi-value and a field value must contain a comma the long -form must be used otherwise the comma would be misinterpreted as a field -separator. For example: - - subjectAltName=URI:ldap://somehost.com/CN=foo,OU=bar - -will produce an error but the equivalent form: - - subjectAltName=@subject_alt_section - - [subject_alt_section] - subjectAltName=URI:ldap://somehost.com/CN=foo,OU=bar - -is valid. - -Due to the behaviour of the OpenSSL B library the same field name -can only occur once in a section. This means that: - - subjectAltName=@alt_section - - [alt_section] - - email=steve@here - email=steve@there - -will only recognize the last value. This can be worked around by using the form: - - [alt_section] - - email.1=steve@here - email.2=steve@there +invalid extensions if they are not used carefully. =head1 SEE ALSO diff --git a/doc/man7/EVP_KDF-HKDF.pod b/doc/man7/EVP_KDF-HKDF.pod index 6a4c7eb8..f0bcd91e 100644 --- a/doc/man7/EVP_KDF-HKDF.pod +++ b/doc/man7/EVP_KDF-HKDF.pod @@ -87,7 +87,7 @@ an error will occur. A context for HKDF can be obtained by calling: EVP_KDF *kdf = EVP_KDF_fetch(NULL, "HKDF", NULL); - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_CTX *kctx = EVP_KDF_new_ctx(kdf); The output length of an HKDF expand operation is specified via the I parameter to the L function. When using @@ -107,7 +107,7 @@ salt value "salt" and info value "label": OSSL_PARAM params[5], *p = params; kdf = EVP_KDF_fetch(NULL, "HKDF", NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, @@ -119,14 +119,14 @@ salt value "salt" and info value "label": *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, "salt", (size_t)4); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { - error("EVP_KDF_CTX_set_params"); + if (EVP_KDF_set_ctx_params(kctx, params) <= 0) { + error("EVP_KDF_set_ctx_params"); } if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { error("EVP_KDF_derive"); } - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); =head1 CONFORMING TO @@ -135,10 +135,10 @@ RFC 5869 =head1 SEE ALSO L, -L, -L, +L, +L, L, -L, +L, L, L diff --git a/doc/man7/EVP_KDF-KB.pod b/doc/man7/EVP_KDF-KB.pod index 8a84a3d0..d31a1ce0 100644 --- a/doc/man7/EVP_KDF-KB.pod +++ b/doc/man7/EVP_KDF-KB.pod @@ -57,7 +57,7 @@ Depending on whether mac is CMAC or HMAC, either digest or cipher is required A context for KBKDF can be obtained by calling: EVP_KDF *kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL); - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_CTX *kctx = EVP_KDF_new_ctx(kdf); The output length of an KBKDF is specified via the C parameter to the L function. @@ -76,7 +76,7 @@ Label "label", and Context "context". OSSL_PARAM params[6], *p = params; kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, @@ -90,12 +90,12 @@ Label "label", and Context "context". *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, "context", strlen("context")); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) <= 0) - error("EVP_KDF_CTX_set_params"); + if (EVP_KDF_set_ctx_params(kctx, params) <= 0) + error("EVP_KDF_set_ctx_params"); else if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) error("EVP_KDF_derive"); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); This example derives 10 bytes using FEEDBACK-CMAC-AES256, with KI "secret", Label "label", and IV "sixteen bytes iv". @@ -107,7 +107,7 @@ Label "label", and IV "sixteen bytes iv". unsigned char *iv = "sixteen bytes iv"; kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CIPHER, "AES256", 0); @@ -122,12 +122,12 @@ Label "label", and IV "sixteen bytes iv". *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, iv, strlen(iv)); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) <= 0) - error("EVP_KDF_CTX_set_params"); + if (EVP_KDF_set_ctx_params(kctx, params) <= 0) + error("EVP_KDF_set_ctx_params"); else if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) error("EVP_KDF_derive"); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); =head1 CONFORMING TO @@ -136,7 +136,7 @@ NIST SP800-108, IETF RFC 6803, IETF RFC 8009. =head1 SEE ALSO L, -L, +L, L, L, L diff --git a/doc/man7/EVP_KDF-KRB5KDF.pod b/doc/man7/EVP_KDF-KRB5KDF.pod index 071cb4e8..192ca3f3 100644 --- a/doc/man7/EVP_KDF-KRB5KDF.pod +++ b/doc/man7/EVP_KDF-KRB5KDF.pod @@ -44,7 +44,7 @@ If a value is already set, the contents are replaced. A context for KRB5KDF can be obtained by calling: EVP_KDF *kdf = EVP_KDF_fetch(NULL, "KRB5KDF", NULL); - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_CTX *kctx = EVP_KDF_new_ctx(kdf); The output length of the KRB5KDF derivation is specified via the I parameter to the L function, and MUST match the key @@ -70,7 +70,7 @@ This example derives a key using the AES-128-CBC cipher: OSSL_PARAM params[4], *p = params; kdf = EVP_KDF_fetch(NULL, "KRB5KDF", NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_CIPHER, @@ -87,7 +87,7 @@ This example derives a key using the AES-128-CBC cipher: if (EVP_KDF_derive(kctx, out, outlen) <= 0) /* Error */ - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); =head1 CONFORMING TO @@ -96,7 +96,7 @@ RFC 3961 =head1 SEE ALSO L, -L, +L, L, L, L, diff --git a/doc/man7/EVP_KDF-PBKDF2.pod b/doc/man7/EVP_KDF-PBKDF2.pod index 43d074bd..270d50bc 100644 --- a/doc/man7/EVP_KDF-PBKDF2.pod +++ b/doc/man7/EVP_KDF-PBKDF2.pod @@ -82,9 +82,9 @@ SP800-132 =head1 SEE ALSO L, -L, -L, -L, +L, +L, +L, L, L diff --git a/doc/man7/EVP_KDF-SCRYPT.pod b/doc/man7/EVP_KDF-SCRYPT.pod index 1459d07c..db54aa48 100644 --- a/doc/man7/EVP_KDF-SCRYPT.pod +++ b/doc/man7/EVP_KDF-SCRYPT.pod @@ -66,7 +66,7 @@ Both r and p are parameters of type B. A context for scrypt can be obtained by calling: EVP_KDF *kdf = EVP_KDF_fetch(NULL, "SCRYPT", NULL); - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_CTX *kctx = EVP_KDF_new_ctx(kdf); The output length of an scrypt key derivation is specified via the "keylen" parameter to the L function. @@ -82,7 +82,7 @@ This example derives a 64-byte long test vector using scrypt with the password OSSL_PARAM params[6], *p = params; kdf = EVP_KDF_fetch(NULL, "SCRYPT", NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, @@ -93,8 +93,8 @@ This example derives a 64-byte long test vector using scrypt with the password *p++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_SCRYPT_R, (uint32_t)8); *p++ = OSSL_PARAM_construct_uint32(OSSL_KDF_PARAM_SCRYPT_P, (uint32_t)16); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { - error("EVP_KDF_CTX_set_params"); + if (EVP_KDF_set_ctx_params(kctx, params) <= 0) { + error("EVP_KDF_set_ctx_params"); } if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { error("EVP_KDF_derive"); @@ -115,7 +115,7 @@ This example derives a 64-byte long test vector using scrypt with the password assert(!memcmp(out, expected, sizeof(out))); } - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); =head1 CONFORMING TO @@ -124,9 +124,9 @@ RFC 7914 =head1 SEE ALSO L, -L, -L, -L, +L, +L, +L, L, L diff --git a/doc/man7/EVP_KDF-SS.pod b/doc/man7/EVP_KDF-SS.pod index 2281cc3c..e8915fb6 100644 --- a/doc/man7/EVP_KDF-SS.pod +++ b/doc/man7/EVP_KDF-SS.pod @@ -66,7 +66,7 @@ This parameter sets an optional value for fixedinfo, also known as otherinfo. A context for SSKDF can be obtained by calling: EVP_KDF *kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_CTX *kctx = EVP_KDF_new_ctx(kdf); The output length of an SSKDF is specified via the I parameter to the L function. @@ -82,7 +82,7 @@ and fixedinfo value "label": OSSL_PARAM params[4], *p = params; kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, @@ -92,14 +92,14 @@ and fixedinfo value "label": *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, "label", (size_t)5); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { - error("EVP_KDF_CTX_set_params"); + if (EVP_KDF_set_ctx_params(kctx, params) <= 0) { + error("EVP_KDF_set_ctx_params"); } if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { error("EVP_KDF_derive"); } - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); This example derives 10 bytes using H(x) = HMAC(SHA-256), with the secret key "secret", fixedinfo value "label" and salt "salt": @@ -110,7 +110,7 @@ fixedinfo value "label" and salt "salt": OSSL_PARAM params[6], *p = params; kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, @@ -124,14 +124,14 @@ fixedinfo value "label" and salt "salt": *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, "salt", (size_t)4); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { - error("EVP_KDF_CTX_set_params"); + if (EVP_KDF_set_ctx_params(kctx, params) <= 0) { + error("EVP_KDF_set_ctx_params"); } if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { error("EVP_KDF_derive"); } - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); This example derives 10 bytes using H(x) = KMAC128(x,salt,outlen), with the secret key "secret" fixedinfo value "label", salt of "salt" and KMAC outlen of 20: @@ -142,7 +142,7 @@ fixedinfo value "label", salt of "salt" and KMAC outlen of 20: OSSL_PARAM params[7], *p = params; kdf = EVP_KDF_fetch(NULL, "SSKDF", NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, @@ -157,14 +157,14 @@ fixedinfo value "label", salt of "salt" and KMAC outlen of 20: "salt", (size_t)4); *p++ = OSSL_PARAM_construct_size_t(OSSL_KDF_PARAM_MAC_SIZE, (size_t)20); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { - error("EVP_KDF_CTX_set_params"); + if (EVP_KDF_set_ctx_params(kctx, params) <= 0) { + error("EVP_KDF_set_ctx_params"); } if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { error("EVP_KDF_derive"); } - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); =head1 CONFORMING TO @@ -173,9 +173,9 @@ NIST SP800-56Cr1. =head1 SEE ALSO L, -L, -L, -L, +L, +L, +L, L, L, L diff --git a/doc/man7/EVP_KDF-SSHKDF.pod b/doc/man7/EVP_KDF-SSHKDF.pod index e91858c0..f7145721 100644 --- a/doc/man7/EVP_KDF-SSHKDF.pod +++ b/doc/man7/EVP_KDF-SSHKDF.pod @@ -87,7 +87,7 @@ A single char of value 70 (ASCII char 'F'). A context for SSHKDF can be obtained by calling: EVP_KDF *kdf = EVP_KDF_fetch(NULL, "SSHKDF", NULL); - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_CTX *kctx = EVP_KDF_new_ctx(kdf); The output length of the SSHKDF derivation is specified via the I parameter to the L function. @@ -111,7 +111,7 @@ This example derives an 8 byte IV using SHA-256 with a 1K "key" and appropriate OSSL_PARAM params[6], *p = params; kdf = EVP_KDF_fetch(NULL, "SSHKDF", NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, @@ -125,7 +125,7 @@ This example derives an 8 byte IV using SHA-256 with a 1K "key" and appropriate *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_SSHKDF_TYPE, EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) <= 0) + if (EVP_KDF_set_ctx_params(kctx, params) <= 0) /* Error */ if (EVP_KDF_derive(kctx, out, &outlen) <= 0) @@ -139,9 +139,9 @@ RFC 4253 =head1 SEE ALSO L, -L, -L, -L, +L, +L, +L, L, L, L diff --git a/doc/man7/EVP_KDF-TLS1_PRF.pod b/doc/man7/EVP_KDF-TLS1_PRF.pod index d6c73655..94597111 100644 --- a/doc/man7/EVP_KDF-TLS1_PRF.pod +++ b/doc/man7/EVP_KDF-TLS1_PRF.pod @@ -51,7 +51,7 @@ this should be more than enough for any normal use of the TLS PRF. A context for the TLS PRF can be obtained by calling: EVP_KDF *kdf = EVP_KDF_fetch(NULL, "TLS1-PRF", NULL); - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_CTX *kctx = EVP_KDF_new_ctx(kdf); The digest, secret value and seed must be set before a key is derived otherwise an error will occur. @@ -70,7 +70,7 @@ and seed value "seed": OSSL_PARAM params[4], *p = params; kdf = EVP_KDF_fetch(NULL, "TLS1-PRF", NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, @@ -80,13 +80,13 @@ and seed value "seed": *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, "seed", (size_t)4); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { - error("EVP_KDF_CTX_set_params"); + if (EVP_KDF_set_ctx_params(kctx, params) <= 0) { + error("EVP_KDF_set_ctx_params"); } if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { error("EVP_KDF_derive"); } - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); =head1 CONFORMING TO @@ -95,9 +95,9 @@ RFC 2246, RFC 5246 and NIST SP 800-135 r1 =head1 SEE ALSO L, -L, -L, -L, +L, +L, +L, L, L diff --git a/doc/man7/EVP_KDF-X942.pod b/doc/man7/EVP_KDF-X942.pod index c88d2f52..0dc1b388 100644 --- a/doc/man7/EVP_KDF-X942.pod +++ b/doc/man7/EVP_KDF-X942.pod @@ -49,7 +49,7 @@ This parameter sets the CEK wrapping algorithm name. A context for X942KDF can be obtained by calling: EVP_KDF *kdf = EVP_KDF_fetch(NULL, "X942KDF", NULL); - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_CTX *kctx = EVP_KDF_new_ctx(kdf); The output length of an X942KDF is specified via the I parameter to the L function. @@ -71,9 +71,9 @@ keying material: kdf = EVP_KDF_fetch(NULL, "X942KDF", NULL); if (kctx == NULL) error("EVP_KDF_fetch"); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); if (kctx == NULL) - error("EVP_KDF_CTX_new"); + error("EVP_KDF_new_ctx"); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, @@ -85,12 +85,12 @@ keying material: SN_id_smime_alg_CMS3DESwrap, strlen(SN_id_smime_alg_CMS3DESwrap)); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) <= 0) - error("EVP_KDF_CTX_set_params"); + if (EVP_KDF_set_ctx_params(kctx, params) <= 0) + error("EVP_KDF_set_ctx_params"); if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) error("EVP_KDF_derive"); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); =head1 CONFORMING TO @@ -99,9 +99,9 @@ RFC 2631 =head1 SEE ALSO L, -L, -L, -L, +L, +L, +L, L, L, L diff --git a/doc/man7/EVP_KDF-X963.pod b/doc/man7/EVP_KDF-X963.pod index 0248869a..11645725 100644 --- a/doc/man7/EVP_KDF-X963.pod +++ b/doc/man7/EVP_KDF-X963.pod @@ -46,7 +46,7 @@ X963KDF appends the counter to the secret, whereas SSKDF prepends the counter. A context for X963KDF can be obtained by calling: EVP_KDF *kdf = EVP_KDF_fetch(NULL, "X963KDF", NULL); - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_CTX *kctx = EVP_KDF_new_ctx(kdf); The output length of an X963KDF is specified via the I parameter to the L function. @@ -62,7 +62,7 @@ value "label": OSSL_PARAM params[4], *p = params; kdf = EVP_KDF_fetch(NULL, "X963KDF", NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, @@ -72,14 +72,14 @@ value "label": *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, "label", (size_t)5); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { - error("EVP_KDF_CTX_set_params"); + if (EVP_KDF_set_ctx_params(kctx, params) <= 0) { + error("EVP_KDF_set_ctx_params"); } if (EVP_KDF_derive(kctx, out, sizeof(out)) <= 0) { error("EVP_KDF_derive"); } - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); =head1 CONFORMING TO @@ -88,9 +88,9 @@ value "label": =head1 SEE ALSO L, -L, -L, -L, +L, +L, +L, L, L, L diff --git a/doc/man7/EVP_KEYEXCH-DH.pod b/doc/man7/EVP_KEYEXCH-DH.pod new file mode 100644 index 00000000..9e9cee7d --- /dev/null +++ b/doc/man7/EVP_KEYEXCH-DH.pod @@ -0,0 +1,98 @@ +=pod + +=head1 NAME + +EVP_KEYEXCH-DH +- DH Key Exchange algorithm support + +=head1 DESCRIPTION + +Key exchange support for the B key type. + +=head2 DH key exchange parameters + +=over 4 + +=item "pad" (B) + +See L. + +=back + +=head1 EXAMPLES + +The examples assume a host and peer both generate keys using the same +named group (or domain parameters). See L. +Both the host and peer transfer their public key to each other. + +To convert the peer's generated key pair to a public key in DER format in order +to transfer to the host: + + EVP_PKEY *peer_key; /* It is assumed this contains the peers generated key */ + unsigned char *peer_pub_der = NULL; + int peer_pub_der_len; + + peer_pub_der_len = i2d_PUBKEY(peer_key, &peer_pub_der); + ... + OPENSSL_free(peer_pub_der); + +To convert the received peer's public key from DER format on the host: + + const unsigned char *pd = peer_pub_der; + EVP_PKEY *peer_pub_key = d2i_PUBKEY(NULL, &pd, peer_pub_der_len); + ... + EVP_PKEY_free(peer_pub_key); + +To derive a shared secret on the host using the host's key and the peer's public +key: + /* It is assumed that the host_key and peer_pub_key are set up */ + void derive_secret(EVP_KEY *host_key, EVP_PKEY *peer_pub_key) + { + unsigned int pad = 1; + OSSL_PARAM params[2]; + unsigned char *secret = NULL; + size_t secret_len = 0; + EVP_PKEY_CTX *dctx = EVP_PKEY_CTX_new_from_pkey(NULL, host_key, NULL); + + EVP_PKEY_derive_init(dctx); + + /* Optionally set the padding */ + params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD, &pad); + params[1] = OSSL_PARAM_construct_end(); + EVP_PKEY_CTX_set_params(dctx, params); + + EVP_PKEY_derive_set_peer(dctx, peer_pub_key); + + /* Get the size by passing NULL as the buffer */ + EVP_PKEY_derive(dctx, NULL, &secret_len); + secret = OPENSSL_zalloc(secret_len); + + EVP_PKEY_derive(dctx, secret, &secret_len); + ... + OPENSSL_clear_free(secret, secret_len); + EVP_PKEY_CTX_free(dctx); + } + +Very similar code can be used by the peer to derive the same shared secret +using the host's public key and the peer's generated key pair. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L, + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_KEYEXCH-ECDH.pod b/doc/man7/EVP_KEYEXCH-ECDH.pod new file mode 100644 index 00000000..1add4b71 --- /dev/null +++ b/doc/man7/EVP_KEYEXCH-ECDH.pod @@ -0,0 +1,133 @@ +=pod + +=head1 NAME + +EVP_KEYEXCH-ECDH - ECDH Key Exchange algorithm support + +=head1 DESCRIPTION + +Key exchange support for the B key type. + +=head2 ECDH Key Exchange parameters + +=over 4 + +=item "ecdh-cofactor-mode" (B) + +Sets or gets the ECDH mode of operation for the associated key exchange ctx. + +In the context of an Elliptic Curve Diffie-Hellman key exchange, this parameter +can be used to select between the plain Diffie-Hellman (DH) or Cofactor +Diffie-Hellman (CDH) variants of the key exchange algorithm. + +When setting, the value should be 1, 0 or -1, respectively forcing cofactor mode +on, off, or resetting it to the default for the private key associated with the +given key exchange ctx. + +When getting, the value should be either 1 or 0, respectively signaling if the +cofactor mode is on or off. + +See also L for the related +B parameter that can be set on a +per-key basis. + +=item "kdf-type" (B) + +Sets or gets the Key Derivation Function type to apply within the associated key +exchange ctx. + +=item "kdf-digest" (B) + +Sets or gets the Digest algorithm to be used as part of the Key Derivation Function +associated with the given key exchange ctx. + +=item "kdf-digest-props" (B) + +Sets properties to be used upon look up of the implementation for the selected +Digest algorithm for the Key Derivation Function associated with the given key +exchange ctx. + +=item "kdf-outlen" (B) + +Sets or gets the desired size for the output of the chosen Key Derivation Function +associated with the given key exchange ctx. + +=item "kdf-ukm" (B) + +Sets the User Key Material to be used as part of the selected Key Derivation +Function associated with the given key exchange ctx. + +=item "kdf-ukm" (B) + +Gets a pointer to the User Key Material to be used as part of the selected +Key Derivation Function associated with the given key exchange ctx. + +=item "kdf-ukm-len" (B) + +Gets the size of the User Key Material to be used as part of the selected +Key Derivation Function associated with the given key exchange ctx. + +=back + +=head1 EXAMPLES + +Keys for the host and peer must be generated as shown in +L using the same curve name. + +The code to generate a shared secret for the normal case is identical to +L. + +To derive a shared secret on the host using the host's key and the peer's public +key but also using X963KDF with a user key material: + + /* It is assumed that the host_key, peer_pub_key and ukm are set up */ + void derive_secret(EVP_PKEY *host_key, EVP_PKEY *peer_key, + unsigned char *ukm, size_t ukm_len) + { + unsigned char secret[64]; + size_t out_len = sizeof(secret); + size_t secret_len = out_len; + unsigned int pad = 1; + OSSL_PARAM params[6]; + EVP_PKET_CTX *dctx = EVP_PKEY_CTX_new_from_pkey(NULL, host_key, NULL); + + EVP_PKEY_derive_init(dctx); + + params[0] = OSSL_PARAM_construct_uint(OSSL_EXCHANGE_PARAM_PAD, &pad); + params[1] = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_TYPE, + "X963KDF", 0); + params[2] = OSSL_PARAM_construct_utf8_string(OSSL_EXCHANGE_PARAM_KDF_DIGEST, + "SHA1", 0); + params[3] = OSSL_PARAM_construct_size_t(OSSL_EXCHANGE_PARAM_KDF_OUTLEN, + &out_len); + params[4] = OSSL_PARAM_construct_octet_string(OSSL_EXCHANGE_PARAM_KDF_UKM, + ukm, ukm_len); + params[5] = OSSL_PARAM_construct_end(); + EVP_PKEY_CTX_set_params(dctx, params); + + EVP_PKEY_derive_set_peer(dctx, peer_pub_key); + EVP_PKEY_derive(dctx, secret, &secret_len); + ... + OPENSSL_clear_free(secret, secret_len); + EVP_PKEY_CTX_free(dctx); + } + +=head1 SEE ALSO + +L +L, +L, +L, +L, +L, + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_KEYEXCH-X25519.pod b/doc/man7/EVP_KEYEXCH-X25519.pod new file mode 100644 index 00000000..6140c561 --- /dev/null +++ b/doc/man7/EVP_KEYEXCH-X25519.pod @@ -0,0 +1,50 @@ +=pod + +=head1 NAME + +EVP_KEYEXCH-X25519, +EVP_KEYEXCH-X448 +- X25519 and X448 Key Exchange algorithm support + +=head1 DESCRIPTION + +Key exchange support for the B and B key types. + +=head2 Key exchange parameters + +=over 4 + +=item "pad" (B) + +See L. + +=back + +=head1 EXAMPLES + +Keys for the host and peer can be generated as shown in +L. + +The code to generate a shared secret is identical to +L. + +=head1 SEE ALSO + +L, +L +L, +L, +L, +L, +L, + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_MAC-BLAKE2.pod b/doc/man7/EVP_MAC-BLAKE2.pod index 90b06534..d5673fa8 100644 --- a/doc/man7/EVP_MAC-BLAKE2.pod +++ b/doc/man7/EVP_MAC-BLAKE2.pod @@ -27,9 +27,9 @@ properties, to be used with EVP_MAC_fetch(): The general description of these parameters can be found in L. -All these parameters can be set with EVP_MAC_CTX_set_params(). +All these parameters can be set with EVP_MAC_set_ctx_params(). Furthermore, the "size" parameter can be retrieved with -EVP_MAC_CTX_get_params(), or with EVP_MAC_size(). +EVP_MAC_get_ctx_params(), or with EVP_MAC_size(). The length of the "size" parameter should not exceed that of a B. =over 4 @@ -61,7 +61,7 @@ It is 32 and 64 respectively by default. =head1 SEE ALSO -L, L, +L, L, L, L =head1 HISTORY diff --git a/doc/man7/EVP_MAC-CMAC.pod b/doc/man7/EVP_MAC-CMAC.pod index c210d693..699a5082 100644 --- a/doc/man7/EVP_MAC-CMAC.pod +++ b/doc/man7/EVP_MAC-CMAC.pod @@ -24,7 +24,7 @@ used with EVP_MAC_fetch(): The general description of these parameters can be found in L. -The following parameter can be set with EVP_MAC_CTX_set_params(): +The following parameter can be set with EVP_MAC_set_ctx_params(): =over 4 @@ -37,7 +37,7 @@ The following parameter can be set with EVP_MAC_CTX_set_params(): =back The following parameters can be retrieved with -EVP_MAC_CTX_get_params(): +EVP_MAC_get_ctx_params(): =over 4 @@ -50,7 +50,7 @@ The length of the "size" parameter is equal to that of an B. =head1 SEE ALSO -L, L, +L, L, L, L =head1 COPYRIGHT diff --git a/doc/man7/EVP_MAC-GMAC.pod b/doc/man7/EVP_MAC-GMAC.pod index 7c9477c2..8e4d28e7 100644 --- a/doc/man7/EVP_MAC-GMAC.pod +++ b/doc/man7/EVP_MAC-GMAC.pod @@ -24,7 +24,7 @@ used with EVP_MAC_fetch(): The general description of these parameters can be found in L. -The following parameter can be set with EVP_MAC_CTX_set_params(): +The following parameter can be set with EVP_MAC_set_ctx_params(): =over 4 @@ -39,7 +39,7 @@ The following parameter can be set with EVP_MAC_CTX_set_params(): =back The following parameters can be retrieved with -EVP_MAC_CTX_get_params(): +EVP_MAC_get_ctx_params(): =over 4 @@ -52,7 +52,7 @@ The length of the "size" parameter is equal to that of an B. =head1 SEE ALSO -L, L, +L, L, L, L =head1 COPYRIGHT diff --git a/doc/man7/EVP_MAC-HMAC.pod b/doc/man7/EVP_MAC-HMAC.pod index 7f0ec35b..31ff102a 100644 --- a/doc/man7/EVP_MAC-HMAC.pod +++ b/doc/man7/EVP_MAC-HMAC.pod @@ -24,7 +24,7 @@ used with EVP_MAC_fetch(): The general description of these parameters can be found in L. -The following parameter can be set with EVP_MAC_CTX_set_params(): +The following parameter can be set with EVP_MAC_set_ctx_params(): =over 4 @@ -41,7 +41,7 @@ The following parameter can be set with EVP_MAC_CTX_set_params(): The "flags" parameter is passed directly to HMAC_CTX_set_flags(). The following parameter can be retrieved with -EVP_MAC_CTX_get_params(): +EVP_MAC_get_ctx_params(): =over 4 @@ -54,7 +54,7 @@ The length of the "size" parameter is equal to that of an B. =head1 SEE ALSO -L, L, +L, L, L, L, L =head1 COPYRIGHT diff --git a/doc/man7/EVP_MAC-KMAC.pod b/doc/man7/EVP_MAC-KMAC.pod index df7ac1dd..88044540 100644 --- a/doc/man7/EVP_MAC-KMAC.pod +++ b/doc/man7/EVP_MAC-KMAC.pod @@ -27,9 +27,9 @@ properties, to be used with EVP_MAC_fetch(): The general description of these parameters can be found in L. -All these parameters can be set with EVP_MAC_CTX_set_params(). +All these parameters can be set with EVP_MAC_set_ctx_params(). Furthermore, the "size" parameter can be retrieved with -EVP_MAC_CTX_get_params(), or with EVP_MAC_size(). +EVP_MAC_get_ctx_params(), or with EVP_MAC_size(). The length of the "size" parameter should not exceed that of a B. =over 4 @@ -50,7 +50,7 @@ the input stream is set to zero. =head1 SEE ALSO -L, L, +L, L, L, L =head1 COPYRIGHT diff --git a/doc/man7/EVP_MAC-Poly1305.pod b/doc/man7/EVP_MAC-Poly1305.pod index da9953a1..8e288172 100644 --- a/doc/man7/EVP_MAC-Poly1305.pod +++ b/doc/man7/EVP_MAC-Poly1305.pod @@ -24,7 +24,7 @@ used with EVP_MAC_fetch(): The general description of these parameters can be found in L. -The following parameter can be set with EVP_MAC_CTX_set_params(): +The following parameter can be set with EVP_MAC_set_ctx_params(): =over 4 @@ -33,7 +33,7 @@ The following parameter can be set with EVP_MAC_CTX_set_params(): =back The following parameters can be retrieved with -EVP_MAC_CTX_get_params(): +EVP_MAC_get_ctx_params(): =over 4 @@ -46,7 +46,7 @@ The length of the "size" parameter should not exceed that of an B. =head1 SEE ALSO -L, L, +L, L, L, L =head1 COPYRIGHT diff --git a/doc/man7/EVP_MAC-Siphash.pod b/doc/man7/EVP_MAC-Siphash.pod index d8013b33..a65e5919 100644 --- a/doc/man7/EVP_MAC-Siphash.pod +++ b/doc/man7/EVP_MAC-Siphash.pod @@ -25,9 +25,9 @@ used with EVP_MAC_fetch(): The general description of these parameters can be found in L. -All these parameters can be set with EVP_MAC_CTX_set_params(). +All these parameters can be set with EVP_MAC_set_ctx_params(). Furthermore, the "size" parameter can be retrieved with -EVP_MAC_CTX_get_params(), or with EVP_MAC_size(). +EVP_MAC_get_ctx_params(), or with EVP_MAC_size(). The length of the "size" parameter should not exceed that of a B. =over 4 @@ -40,7 +40,7 @@ The length of the "size" parameter should not exceed that of a B. =head1 SEE ALSO -L, L, +L, L, L, L =head1 COPYRIGHT diff --git a/doc/man7/EVP_MD-common.pod b/doc/man7/EVP_MD-common.pod index 78384498..58d8ed56 100644 --- a/doc/man7/EVP_MD-common.pod +++ b/doc/man7/EVP_MD-common.pod @@ -7,11 +7,8 @@ EVP_MD-common - The OpenSSL EVP_MD implementations, common things =head1 DESCRIPTION All the OpenSSL EVP_MD implementations understand the following -L entries: - -=over 4 - -Gettable with L: +L entries that are +gettable with L, as well as these: =over 4 @@ -49,8 +46,6 @@ This value can also be retrieved with L. =back -=back - =head1 SEE ALSO L, L diff --git a/doc/man7/EVP_PKEY-DH.pod b/doc/man7/EVP_PKEY-DH.pod new file mode 100644 index 00000000..67204176 --- /dev/null +++ b/doc/man7/EVP_PKEY-DH.pod @@ -0,0 +1,234 @@ +=pod + +=head1 NAME + +EVP_PKEY-DH, EVP_KEYMGMT-DH - EVP_PKEY DH keytype and algorithm support + +=head1 DESCRIPTION + +For B FFC key agreement, two classes of domain parameters can be used: +"safe" domain parameters that are associated with approved named safe-prime +groups, and a class of "FIPS 186-type" domain parameters. FIPS 186-type domain +parameters should only be used for backward compatibility with existing +applications that cannot be upgraded to use the approved safe-prime groups. + +See L for more information about FFC keys. + +For B that is not a named group) the FIPS186-4 standard specifies that the +values used for FFC parameter generation are also required for parameter +validation. This means that optional FFC domain parameter values for +I, I and I may need to be stored for validation purposes. +For B the I and I can be stored in ASN1 data +(but the I is not). + +=head2 DH parameters + +In addition to the common FCC parameters that all FFC keytypes should support +(see L)) the B keytype +implementation supports the following: + +=over 4 + +=item "group" (B) + +Set or gets a string that associates a B named safe prime group with known +values for I

, I and I. + +The following values can be used by the OpenSSL's default and FIPS providers: +"ffdhe2048", "ffdhe3072", "ffdhe4096", "ffdhe6144", "ffdhe8192", +"modp_2048", "modp_3072", "modp_4096", "modp_6144", "modp_8192". + +The following additional values can also be used by OpenSSL's default provider: +"modp_1536", "dh_1024_160", "dh_2048_224", "dh_2048_256". + +DH named groups can be easily validated since the parameters are well known. +For protocols that only transfer I

and I the value of I can also be +retrieved. + +=item "safeprime-generator" (B) + +Used for DH generation of safe primes using the old generator code. +It is recommended to use a named safe prime group instead, if domain parameter +validation is required. The default value is 2. + +These are not named safe prime groups so setting this value for the OpenSSL FIPS +provider will instead choose a named safe prime group based on the size of I

. + +=item "tls-encoded-pt" (B) + +Used for getting and setting the encoding of the DH public key used in a key +exchange message for the TLS protocol. + +=back + +=head2 DH domain parameter / key generation parameters + +In addition to the common FCC key generation parameters that all FFC key types +should support (see L)) the +B keytype implementation supports the following: + +=over 4 + +=item "type" (B) + +Sets the type of parameter generation. For B valid values are: + +=over 4 + +=item "fips186_4" + +=item "default" + +=item "fips186_2" + +These are described in L + +=item "group" + +This specifies that a named safe prime name will be chosen using the "pbits" +type. + +=item "generator" + +A safe prime generator. See the "safeprime-generator" type above. + +=back + +=item "pbits" (B) + +Sets the size (in bits) of the prime 'p'. + +For "fips186_4" this must be 2048. +For "fips186_2" this must be 1024. +For "group" this can be any one of 2048, 3072, 4096, 6144 or 8192. + +=item "priv_len" (B) + +An optional value to set the maximum length of the generated private key. +The default valure used if this is not set is the maximum value of +BN_num_bits(I)). The minimum value that this can be set to is 2 * s. +Where s is the security strength of the key which has values of +112, 128, 152, 176 and 200 for key sizes of 2048, 3072, 4096, 6144 and 8192. + +=back + +=head1 EXAMPLES + +An B context can be obtained by calling: + + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL); + +An B key can be generated with a named safe prime group by calling: + + int priv_len = 2 * 112; + OSSL_PARAM params[3]; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL); + + params[0] = OSSL_PARAM_construct_utf8_string("group", "ffdhe2048", 0); + /* "priv_len" is optional */ + params[1] = OSSL_PARAM_construct_int("priv_len", &priv_len); + params[2] = OSSL_PARAM_construct_end(); + + EVP_PKEY_keygen_init(pctx); + EVP_PKEY_CTX_set_params(pctx, params); + EVP_PKEY_gen(pctx, &pkey); + ... + EVP_PKEY_free(key); + EVP_PKEY_CTX_free(pctx); + +Legacy B domain parameters can be generated by calling: + unsigned int pbits = 2048; + unsigned int qbits = 256; + int gindex = 1; + OSSL_PARAM params[5]; + EVP_PKEY *param_key = NULL; + EVP_PKEY_CTX *pctx = NULL; + + pctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL); + EVP_PKEY_paramgen_init(pctx); + + params[0] = OSSL_PARAM_construct_uint("pbits", &pbits); + params[1] = OSSL_PARAM_construct_uint("qbits", &qbits); + params[2] = OSSL_PARAM_construct_int("gindex", &gindex); + params[3] = OSSL_PARAM_construct_utf8_string("digest", "SHA384", 0); + params[4] = OSSL_PARAM_construct_end(); + EVP_PKEY_CTX_set_params(pctx, params); + + EVP_PKEY_gen(pctx, ¶m_key); + + EVP_PKEY_print_params(bio_out, param_key, 0, NULL); + ... + EVP_PKEY_free(param_key); + EVP_PKEY_CTX_free(pctx); + +An B key can be generated using domain parameters by calling: + + EVP_PKEY *key = NULL; + EVP_PKEY_CTX *gctx = EVP_PKEY_CTX_new_from_pkey(NULL, param_key, NULL); + + EVP_PKEY_keygen_init(gctx); + EVP_PKEY_gen(gctx, &key); + EVP_PKEY_print_private(bio_out, key, 0, NULL); + ... + EVP_PKEY_free(key); + EVP_PKEY_CTX_free(gctx); + +=for comment TODO(3.0): To validate domain parameters, additional values used +during generation may be required to be set into the key. + +=head1 CONFORMING TO + +=over 4 + +=item RFC 7919 (TLS ffdhe named safe prime groups) + +=item RFC 3526 (IKE modp named safe prime groups) + +=item RFC 5114 (Additional DH named groups for dh_1024_160", "dh_2048_224" + and "dh_2048_256"). + +=back + +The following sections of SP800-56Ar3: + +=over 4 + +=item 5.5.1.1 FFC Domain Parameter Selection/Generation + +=item Appendix D: FFC Safe-prime Groups + +=back + +The following sections of FIPS 186-4: + +=over 4 + +=item A.1.1.2 Generation of Probable Primes p and q Using an Approved Hash Function. + +=item A.2.3 Generation of canonical generator g. + +=item A.2.1 Unverifiable Generation of the Generator g. + +=back + +=head1 SEE ALSO + +L, +L +L, +L, +L, +L, +L + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_PKEY-DSA.pod b/doc/man7/EVP_PKEY-DSA.pod index ccb34a9f..680717b1 100644 --- a/doc/man7/EVP_PKEY-DSA.pod +++ b/doc/man7/EVP_PKEY-DSA.pod @@ -2,240 +2,77 @@ =head1 NAME -EVP_PKEY-DSA, EVP_KEYMGMT-DSA, EVP_PKEY-DH, EVP_KEYMGMT-DH -- EVP_PKEY DSA and DH keytype and algorithm support +EVP_PKEY-DSA, EVP_KEYMGMT-DSA - EVP_PKEY DSA keytype and algorithm support =head1 DESCRIPTION -The B and B keytypes are implemented in OpenSSL's default and FIPS -providers. -The implementations support the basic DSA and DH keys, containing the public -and private keys I and I as well as the three main domain parameters -I

, I and I. - -Finite field cryptography (FFC) is a method of implementing discrete logarithm -cryptography using finite field mathematics. DSA is an example of FFC and -Diffie-Hellman key establishment algorithms specified in SP800-56A can also be -implemented as FFC. - -For B FFC key agreement, two classes of domain parameters can be used: -"safe" domain parameters that are associated with approved named safe-prime -groups, and a class of "FIPS 186-type" domain parameters. FIPS 186-type domain -parameters should only be used for backward compatibility with existing -applications that cannot be upgraded to use the approved safe-prime groups. - -For B (and B that is not a named group) the FIPS186-4 standard -specifies that the values used for FFC parameter generation are also required -for parameter validation. +For B the FIPS186-4 standard specifies that the values used for FFC +parameter generation are also required for parameter validation. This means that optional FFC domain parameter values for I, I -and I may need to be stored for validation purposes. -For B the I and I can be stored in ASN1 data -(but the I is not). For B however, these fields are not stored in -the ASN1 data so they need to be stored externally if validation is required. +and I may need to be stored for validation purposes. For B these +fields are not stored in the ASN1 data so they need to be stored externally if +validation is required. -=head2 Common DH parameters +=head2 DSA parameters -=over 4 +The B key type supports the FFC parameters (see +L). -=item "group" (B) +=head2 DSA key generation parameters -A string that associates a B named safe prime group with known values for -I

, I and I. +The B key type supports the FFC key generation parameters (see +L -The following values can be used by the default and OpenSSL's FIPS providers: -"ffdhe2048", "ffdhe3072", "ffdhe4096", "ffdhe6144", "ffdhe8192", -"modp_2048", "modp_3072", "modp_4096", "modp_6144", "modp_8192". +The following restrictions apply to the "pbits" field: -The following additional values can also be used by the default provider: -"modp_1536", "dh_1024_160", "dh_2048_224", "dh_2048_256". - -DH named groups can be easily validated since the parameters are well known. -For protocols that only transfer I

and I the value of I can also be -retrieved. - -=item "safeprime-generator" (B) - -Used for DH generation of safe primes using the old generator code. -It is recommended to use a named safe prime group instead, if domain parameter -validation is required. The default value is 2. - -These are not named safe prime groups so setting this value for the OpenSSL FIPS -provider will instead choose a named safe prime group based on the size of I

. - -=back - -=head2 Common DSA & DH parameters - -In addition to the common parameters that all keytypes should support (see -L), the B and B keytype -implementations support the following. - -=over 4 - -=item "pub" (B) - -The public key value. - -=item "priv" (B) - -The private key value. - -=item "p" (B) - -A DSA or Diffie-Hellman prime "p" value. - -=item "q" (B) - -A DSA or Diffie-Hellman prime "q" value. - -=item "g" (B) - -A DSA or Diffie-Hellman generator "g" value. - -=item "seed" (B) - -An optional domain parameter I value used during generation and validation -of I

, I and canonical I. -For validation this needs to set the I that was produced during generation. - -=item "gindex" (B) - -Sets the index to use for canonical generation and verification of the generator -I. -Set this to a positive value from 0..FF to use this mode. This I can -then be reused during key validation to verify the value of I. If this value -is not set or is -1 then unverifiable generation of the generator I will be -used. - -=item "pcounter" (B) - -An optional domain parameter I value that is output during generation -of I

. This value must be saved if domain parameter validation is required. - -=item "hindex" (B) - -For unverifiable generation of the generator I this value is output during -generation of I. Its value is the first integer larger than one that -satisfies g = h^j mod p (where g != 1 and "j" is the cofactor). - -=item "j" (B) - -An optional informational cofactor parameter that should equal (p - 1) / q. - -=back - - -=head2 DSA / DH key generation (FFC) parameters - -The following Key Generation types are available for the built-in FFC algorithms: - -=over 4 - -=item "type" (B) - -Sets the type of parameter generation. For DH Valid values are: - -=over 4 - -=item "fips186_4" - -The current standard. This is the default value. - -=item "default" - -This is an alias to use the latest implemented standard. -It is currently set to "fips186_4". - -=item "group" - -This specifies that a named safe prime name will be chosen using the "pbits" -type. - -=item "fips186_2" - -The old standard that should only be used for legacy purposes. - -=item "generator" - -A safe prime generator. See the "safeprime-generator" type. - -=back - -For DSA valid values are one of "default", "fips186_4" or "fips186_2" as -described above. - -=item "pbits" (B) - -Sets the size (in bits) of the prime 'p'. - -For "fips186_4" this must be 2048 for DH, and either of 2048 or 3072 for DSA. +For "fips186_4" this must be either 2048 or 3072. For "fips186_2" this must be 1024. For "group" this can be any one of 2048, 3072, 4096, 6144 or 8192. -=item "qbits" (B) +=head1 EXAMPLES -Sets the size (in bits) of the prime 'q'. +An B context can be obtained by calling: -For "fips186_4" this can be either 224 or 256. -For "fips186_2" this has a size of 160. + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL); -=item "digest" (B) +An B domain parameters key can be generated by calling: -Sets the Digest algorithm to be used as part of the Key Generation Function -associated with the given Key Generation I. -This must also be set for key validation. + unsigned int pbits = 2048; + unsigned int qbits = 256; + int gindex = 1; + OSSL_PARAM params[5]; + EVP_PKEY *param_key = NULL; + EVP_PKEY_CTX *pctx = NULL; -=item "properties" (B) + pctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL); + EVP_PKEY_paramgen_init(pctx); -Sets properties to be used upon look up of the implementation for the selected -Digest algorithm for the Key Generation Function associated with the given key -generation I. This may also be set for key validation. + params[0] = OSSL_PARAM_construct_uint("pbits", &pbits); + params[1] = OSSL_PARAM_construct_uint("qbits", &qbits); + params[2] = OSSL_PARAM_construct_int("gindex", &gindex); + params[3] = OSSL_PARAM_construct_utf8_string("digest", "SHA384", 0); + params[4] = OSSL_PARAM_construct_end(); + EVP_PKEY_CTX_set_params(pctx, params); -=item "seed" (B) + EVP_PKEY_gen(pctx, ¶m_key); + EVP_PKEY_CTX_free(pctx); -For "fips186_4" or "fips186_2" generation this sets the I data to use -instead of generating a random seed internally. This should be used for -testing purposes only. This will either produce fixed values for the generated -parameters OR it will fail if the seed did not generate valid primes. + EVP_PKEY_print_params(bio_out, param_key, 0, NULL); -=item "group" (B) +An B key can be generated using domain parameters by calling: -=item "safeprime-generator" (B) + EVP_PKEY *key = NULL; + EVP_PKEY_CTX *gctx = NULL; -=item "gindex" (B) - -=item "pcounter" (B) - -=item "hindex" (B) - -These types are described above. - -=back + gctx = EVP_PKEY_CTX_new_from_pkey(NULL, param_key, NULL); + EVP_PKEY_keygen_init(gctx); + EVP_PKEY_gen(gctx, &key); + EVP_PKEY_CTX_free(gctx); + EVP_PKEY_print_private(bio_out, key, 0, NULL); =head1 CONFORMING TO -=over 4 - -=item RFC 7919 (TLS ffdhe named safe prime groups) - -=item RFC 3526 (IKE modp named safe prime groups) - -=item RFC 5114 (Additional DH named groups for dh_1024_160", "dh_2048_224" - and "dh_2048_256"). - -=back - -The following sections of SP800-56Ar3: - -=over 4 - -=item 5.5.1.1 FFC Domain Parameter Selection/Generation - -=item Appendix D: FFC Safe-prime Groups - -=back - The following sections of FIPS 186-4: =over 4 @@ -250,9 +87,13 @@ The following sections of FIPS 186-4: =head1 SEE ALSO -L, L, L, -L, L, -L, L +L, +L +L, +L, +L, +L, +L =head1 COPYRIGHT diff --git a/doc/man7/EVP_PKEY-EC.pod b/doc/man7/EVP_PKEY-EC.pod index 88d0ebdd..85e633ce 100644 --- a/doc/man7/EVP_PKEY-EC.pod +++ b/doc/man7/EVP_PKEY-EC.pod @@ -2,7 +2,9 @@ =head1 NAME -EVP_PKEY-EC - EVP_PKEY EC keytype and algorithm support +EVP_PKEY-EC, +EVP_KEYMGMT-EC +- EVP_PKEY EC keytype and algorithm support =head1 DESCRIPTION @@ -24,9 +26,8 @@ Enable Cofactor DH (ECC CDH) if this value is 1, otherwise it uses normal EC DH if the value is zero. The cofactor variant multiplies the shared secret by the EC curve's cofactor (note for some curves the cofactor is 1). -=for comment The following link should become L -See also L for the related +See also L for the related B parameter that can be set on a per-operation basis. @@ -38,6 +39,11 @@ The public key value in EC point format. The private key value. +=item "tls-encoded-pt" (B) + +Used for getting and setting the encoding of the EC public key used in key +exchange message for the TLS protocol. + =back =head1 EXAMPLES @@ -47,10 +53,68 @@ An B context can be obtained by calling: EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); +An B ECDSA or ECDH key can be generated with a "P-256" named group by +calling: + + EVP_PKEY *key = NULL; + OSSL_PARAM params[2]; + EVP_PKEY_CTX *gctx = + EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); + + EVP_PKEY_keygen_init(gctx); + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_NAME, + "P-256", 0); + params[1] = OSSL_PARAM_construct_end(); + EVP_PKEY_CTX_set_params(gctx, params); + + EVP_PKEY_gen(gctx, &key); + + EVP_PKEY_print_private(bio_out, key, 0, NULL); + ... + EVP_PKEY_free(key); + EVP_PKEY_CTX_free(gctx); + +An B EC CDH (Cofactor Diffie-Hellman) key can be generated with a +"K-571" named group by calling: + + int use_cdh = 1; + EVP_PKEY *key = NULL; + OSSL_PARAM params[3]; + EVP_PKEY_CTX *gctx = + EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); + + EVP_PKEY *key = NULL; + OSSL_PARAM params[3]; + EVP_PKEY_CTX *gctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL); + + EVP_PKEY_keygen_init(gctx); + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_EC_NAME, + "K-571", 0); + /* + * This curve has a cofactor that is not 1 - so setting CDH mode changes + * the behaviour. For many curves the cofactor is 1 - so setting this has + * no effect. + */ + params[1] = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, + &use_cdh); + params[2] = OSSL_PARAM_construct_end(); + EVP_PKEY_CTX_set_params(gctx, params); + + EVP_PKEY_gen(gctx, &key); + EVP_PKEY_print_private(bio_out, key, 0, NULL); + ... + EVP_PKEY_free(key); + EVP_PKEY_CTX_free(gctx); + =head1 SEE ALSO -L, L, L, -L, L +L, +L, +L, +L, +L =head1 COPYRIGHT diff --git a/doc/man7/EVP_PKEY-FFC.pod b/doc/man7/EVP_PKEY-FFC.pod new file mode 100644 index 00000000..e97a1c6b --- /dev/null +++ b/doc/man7/EVP_PKEY-FFC.pod @@ -0,0 +1,199 @@ +=pod + +=head1 NAME + +EVP_PKEY-FFC - EVP_PKEY DSA and DH shared FFC parameters. + +=head1 DESCRIPTION + +Finite field cryptography (FFC) is a method of implementing discrete logarithm +cryptography using finite field mathematics. DSA is an example of FFC and +Diffie-Hellman key establishment algorithms specified in SP800-56A can also be +implemented as FFC. + +The B and B keytypes are implemented in OpenSSL's default and FIPS +providers. +The implementations support the basic DSA and DH keys, containing the public +and private keys I and I as well as the three main domain parameters +I

, I and I. + +For B (and B that is not a named group) the FIPS186-4 standard +specifies that the values used for FFC parameter generation are also required +for parameter validation. +This means that optional FFC domain parameter values for I, I +and I may need to be stored for validation purposes. +For B the I and I can be stored in ASN1 data +(but the I is not). For B however, these fields are not stored in +the ASN1 data so they need to be stored externally if validation is required. + +=head2 FFC parameters + +In addition to the common parameters that all keytypes should support (see +L), the B and B keytype +implementations support the following. + +=over 4 + +=item "pub" (B) + +The public key value. + +=item "priv" (B) + +The private key value. + +=item "p" (B) + +A DSA or Diffie-Hellman prime "p" value. + +=item "q" (B) + +A DSA or Diffie-Hellman prime "q" value. + +=item "g" (B) + +A DSA or Diffie-Hellman generator "g" value. + +=item "seed" (B) + +An optional domain parameter I value used during generation and validation +of I

, I and canonical I. +For validation this needs to set the I that was produced during generation. + +=item "gindex" (B) + +Sets the index to use for canonical generation and verification of the generator +I. +Set this to a positive value from 0..FF to use this mode. This I can +then be reused during key validation to verify the value of I. If this value +is not set or is -1 then unverifiable generation of the generator I will be +used. + +=item "pcounter" (B) + +An optional domain parameter I value that is output during generation +of I

. This value must be saved if domain parameter validation is required. + +=item "hindex" (B) + +For unverifiable generation of the generator I this value is output during +generation of I. Its value is the first integer larger than one that +satisfies g = h^j mod p (where g != 1 and "j" is the cofactor). + +=item "j" (B) + +An optional informational cofactor parameter that should equal to (p - 1) / q. + +=back + +=head2 FFC key generation parameters + +The following key generation types are available for DSA and DH algorithms: + +=over 4 + +=item "type" (B) + +Sets the type of parameter generation. The shared valid values are: + +=over 4 + +=item "fips186_4" + +The current standard. This is the default value. + +=item "fips186_2" + +The old standard that should only be used for legacy purposes. + +=item "default" + +This is an alias to use the latest implemented standard. +It is currently set to "fips186_4". + +=back + +=item "pbits" (B) + +Sets the size (in bits) of the prime 'p'. + +=item "qbits" (B) + +Sets the size (in bits) of the prime 'q'. + +For "fips186_4" this can be either 224 or 256. +For "fips186_2" this has a size of 160. + +=item "digest" (B) + +Sets the Digest algorithm to be used as part of the Key Generation Function +associated with the given Key Generation I. +This must also be set for key validation. + +=item "properties" (B) + +Sets properties to be used upon look up of the implementation for the selected +Digest algorithm for the Key Generation Function associated with the given key +generation I. This may also be set for key validation. + +=item "seed" (B) + +For "fips186_4" or "fips186_2" generation this sets the I data to use +instead of generating a random seed internally. This should be used for +testing purposes only. This will either produce fixed values for the generated +parameters OR it will fail if the seed did not generate valid primes. + +=item "gindex" (B) + +=item "pcounter" (B) + +=item "hindex" (B) + +These types are described above. + +=back + +=head1 CONFORMING TO + +The following sections of SP800-56Ar3: + +=over 4 + +=item 5.5.1.1 FFC Domain Parameter Selection/Generation + +=back + +The following sections of FIPS 186-4: + +=over 4 + +=item A.1.1.2 Generation of Probable Primes p and q Using an Approved Hash Function. + +=item A.2.3 Generation of canonical generator g. + +=item A.2.1 Unverifiable Generation of the Generator g. + +=back + +=head1 SEE ALSO + +L, +L, +L, +L +L, +L, +L, +L, +L, + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_PKEY-RSA.pod b/doc/man7/EVP_PKEY-RSA.pod index c6533f2f..28f61e40 100644 --- a/doc/man7/EVP_PKEY-RSA.pod +++ b/doc/man7/EVP_PKEY-RSA.pod @@ -121,6 +121,13 @@ The value should be the number of primes for the generated B key. The default is 2. It isn't permitted to specify a larger number of primes than 10. Additionally, the number of primes is limited by the length of the key being generated so the maximum number could be less. +Some providers may only support a value of 2. + +=item "e" (B) + +The RSA "e" value. The value may be any odd number greater than or equal to +65537. The default value is 65537. +For legacy reasons a value of 3 is currently accepted but is deprecated. =back @@ -158,15 +165,17 @@ An B key can be generated with key generation parameters: unsigned int bits = 4096; OSSL_PARAM params[3]; EVP_PKEY *pkey = NULL; - EVP_PKEY_CTX *pctx = - EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); - params[0] = OSSL_PARAM_construct_uint("bits", bits); - params[1] = OSSL_PARAM_construct_uint("primes", primes); - params[2] = OSSL_PARAM_END; EVP_PKEY_keygen_init(pctx); + + params[0] = OSSL_PARAM_construct_uint("bits", &bits); + params[1] = OSSL_PARAM_construct_uint("primes", &primes); + params[2] = OSSL_PARAM_construct_end(); EVP_PKEY_CTX_set_params(pctx, params); + EVP_PKEY_gen(pctx, &pkey); + EVP_PKEY_print_private(bio_out, pkey, 0, NULL); EVP_PKEY_CTX_free(pctx); =head1 SEE ALSO diff --git a/doc/man7/EVP_PKEY-X25519.pod b/doc/man7/EVP_PKEY-X25519.pod index 58f7525f..ebeda8d8 100644 --- a/doc/man7/EVP_PKEY-X25519.pod +++ b/doc/man7/EVP_PKEY-X25519.pod @@ -15,6 +15,8 @@ private key I. In the FIPS provider they are non-approved algorithms and do not have the "fips=yes" property set. +No additional parameters can be set during key generation. + =head2 Common X25519, X448, ED25519 and ED448 parameters @@ -32,6 +34,11 @@ The public key value. The private key value. +=item "tls-encoded-pt" (B) + +Used for getting and setting the encoding of the public key used in a key exchange +message for the TLS protocol. + =back =head2 ED25519 and ED448 parameters @@ -50,6 +57,8 @@ The empty string, signifying that no digest may be specified. =item RFC 8032 +=item RFC 8410 + =back =head1 EXAMPLES diff --git a/doc/man7/EVP_SIGNATURE-DSA.pod b/doc/man7/EVP_SIGNATURE-DSA.pod new file mode 100644 index 00000000..11fe500c --- /dev/null +++ b/doc/man7/EVP_SIGNATURE-DSA.pod @@ -0,0 +1,58 @@ +=pod + +=head1 NAME + +EVP_SIGNATURE-DSA +- The B DSA signature implementation + +=head1 DESCRIPTION + +Support for computing DSA signatures. +See L for information related to DSA keys. + +=head2 Signature Parameters + +The following signature parameters can be set using EVP_PKEY_CTX_set_params(). +This may be called after EVP_PKEY_sign_init() or EVP_PKEY_verify_init(), +and before calling EVP_PKEY_sign() or EVP_PKEY_verify(). + +=over 4 + +=item "digest" (B) + +=item "properties" (B) + +The settable parameters are described in L. + +=back + +The following signature parameters can be retrieved using +EVP_PKEY_CTX_get_params(). + +=over 4 + +=item "algorithm-id" (B) + +=item "digest" (B) + +The gettable parameters are described in L. + +=back + +=head1 SEE ALSO + +L, +L, +L, +L, + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/EVP_SIGNATURE-ECDSA.pod b/doc/man7/EVP_SIGNATURE-ECDSA.pod new file mode 100644 index 00000000..04b80a11 --- /dev/null +++ b/doc/man7/EVP_SIGNATURE-ECDSA.pod @@ -0,0 +1,57 @@ +=pod + +=head1 NAME + +EVP_SIGNATURE-ECDSA - The EVP_PKEY ECDSA signature implementation. + +=head1 DESCRIPTION + +Support for computing ECDSA signatures. +See L for information related to EC keys. + +=head2 ECDSA Signature Parameters + +The following signature parameters can be set using EVP_PKEY_CTX_set_params(). +This may be called after EVP_PKEY_sign_init() or EVP_PKEY_verify_init(), +and before calling EVP_PKEY_sign() or EVP_PKEY_verify(). + +=over 4 + +=item "digest" (B) + +=item "properties" (B) + +These parameters are described in L. + +=back + +The following signature parameters can be retrieved using +EVP_PKEY_CTX_get_params(). + +=over 4 + +=item "algorithm-id" (B) + +=item "digest" (B) + +The parameters are described in L. + +=back + +=head1 SEE ALSO + +L, +L, +L, +L, + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/Ed25519.pod b/doc/man7/EVP_SIGNATURE-ED25519.pod similarity index 68% rename from doc/man7/Ed25519.pod rename to doc/man7/EVP_SIGNATURE-ED25519.pod index 912b607e..e3d9cd47 100644 --- a/doc/man7/Ed25519.pod +++ b/doc/man7/EVP_SIGNATURE-ED25519.pod @@ -2,6 +2,8 @@ =head1 NAME +EVP_SIGNATURE-ED25519, +EVP_SIGNATURE-ED448, Ed25519, Ed448 - EVP_PKEY Ed25519 and Ed448 support @@ -13,9 +15,10 @@ one-shot digest sign and digest verify using PureEdDSA and B or B be -specified when signing or verifying. +No additional parameters can be set during one-shot signing or verification. +In particular, because PureEdDSA is used, a digest must B be specified when +signing or verifying. +See L for information related to B and B keys. =head1 NOTES @@ -31,14 +34,6 @@ Applications wishing to sign certificates (or other structures such as CRLs or certificate requests) using Ed25519 or Ed448 can either use X509_sign() or X509_sign_ctx() in the usual way. -A context for the B algorithm can be obtained by calling: - - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL); - -For the B algorithm a context can be obtained by calling: - - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED448, NULL); - Ed25519 or Ed448 private keys can be set directly using L or loaded from a PKCS#8 private key file using L (or similar function). Completely new keys @@ -56,23 +51,29 @@ specified, then both Ed25519 and Ed448 are benchmarked. =head1 EXAMPLES -This example generates an B private key and writes it to standard -output in PEM format: +To sign a message using a ED25519 or ED448 key: - #include - #include - ... - EVP_PKEY *pkey = NULL; - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_ED25519, NULL); - EVP_PKEY_keygen_init(pctx); - EVP_PKEY_keygen(pctx, &pkey); - EVP_PKEY_CTX_free(pctx); - PEM_write_PrivateKey(stdout, pkey, NULL, NULL, 0, NULL, NULL); + void do_sign(EVP_PKEY *ed_key, unsigned char *msg, size_t msg_len) + { + size_t sig_len; + unsigned char *sig = NULL; + EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); + + EVP_DigestSignInit(md_ctx, NULL, NULL, NULL, ed_key); + /* Calculate the requires size for the signature by passing a NULL buffer */ + EVP_DigestSign(md_ctx, NULL, &sig_len, msg, msg_len); + sig = OPENSSL_zalloc(sig_len); + + EVP_DigestSign(md_ctx, sig, &sig_len, msg, msg_len); + ... + OPENSSL_free(sig); + EVP_MD_CTX_free(md_ctx); + } =head1 SEE ALSO -L, -L, +L +L, L, L, diff --git a/doc/man7/EVP_SIGNATURE-RSA.pod b/doc/man7/EVP_SIGNATURE-RSA.pod new file mode 100644 index 00000000..0cc3336b --- /dev/null +++ b/doc/man7/EVP_SIGNATURE-RSA.pod @@ -0,0 +1,112 @@ +=pod + +=head1 NAME + +EVP_SIGNATURE-RSA +- The EVP_PKEY RSA signature implementation + +=head1 DESCRIPTION + +Support for computing RSA signatures. +See L for information related to RSA keys. + +=head2 Signature Parameters + +The following signature parameters can be set using EVP_PKEY_CTX_set_params(). +This may be called after EVP_PKEY_sign_init() or EVP_PKEY_verify_init(), +and before calling EVP_PKEY_sign() or EVP_PKEY_verify(). + +=over 4 + +=item "digest" (B) + +=item "properties" (B) + +These common parameters are described in L. + +=item "pad-mode" (B) + +The type of padding to be used. Its value can be one of the following: + +=over 4 + +=item "none" (B) + +=item "pkcs1" (B) + +=item "sslv23" (B) + +=item "x931" (B) + +=item "pss" (B) + +=back + +=item "mgf1-digest" (B) + +The digest algorithm name to use for the maskGenAlgorithm used by "pss" mode. + +=item "mgf1-properties" (B) + +Sets the name of the property query associated with the "mgf1-digest" algorithm. +NULL is used if this optional value is not set. + +=item "pss-saltlen" (B) + +Set or get the "pss" mode minimum salt length. The value can either be a string +value representing a number or one of the following: + +=over 4 + +=item "digest" (B) + +Use the same length as the digest size. + +=item "max" (B) + +Use the maximum salt length. + +=item "auto" (B) + +Auto detect the salt length. + +=back + +=back + +The following signature parameters can be retrieved using +EVP_PKEY_CTX_get_params(). + +=over 4 + +=item "algorithm-id" (B) + +This common parameter is described in L. + +=item "digest" (B) + +=item "pad-mode" (B) + +=item "mgf1-digest" (B) + +These parameters are as described above. + +=back + +=head1 SEE ALSO + +L, +L, +L, +L, + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/OSSL_PROVIDER-FIPS.pod b/doc/man7/OSSL_PROVIDER-FIPS.pod index 92dab0e8..1da465f4 100644 --- a/doc/man7/OSSL_PROVIDER-FIPS.pod +++ b/doc/man7/OSSL_PROVIDER-FIPS.pod @@ -18,9 +18,9 @@ defined: =over 4 -"provider=default" +=item "provider=default" -"fips=yes" +=item "fips=yes" =back @@ -102,6 +102,16 @@ The OpenSSL FIPS provider supports these operations and algorithms: =item DH, see L +=item ECDH, see L + +=item X25519, see L + +This has the property "provider=fips,fips=no" + +=item X448, see L + +This has the property "provider=fips,fips=no" + =back =head2 Asymmetric Signature diff --git a/doc/man7/OSSL_PROVIDER-default.pod b/doc/man7/OSSL_PROVIDER-default.pod index acfd4d0e..91b02c5e 100644 --- a/doc/man7/OSSL_PROVIDER-default.pod +++ b/doc/man7/OSSL_PROVIDER-default.pod @@ -17,7 +17,7 @@ defined: =over 4 -"provider=default" +=item "provider=default" =back @@ -136,6 +136,8 @@ The OpenSSL default provider supports these operations and algorithms: =item KRB5KDF, see L +=item X963KDF, see L + =back =head2 Key Exchange diff --git a/doc/man7/OSSL_PROVIDER-legacy.pod b/doc/man7/OSSL_PROVIDER-legacy.pod index 27ed3080..db2d57ed 100644 --- a/doc/man7/OSSL_PROVIDER-legacy.pod +++ b/doc/man7/OSSL_PROVIDER-legacy.pod @@ -15,12 +15,12 @@ We can consider this the retirement home of cryptographic algorithms. =head2 Properties -The implementations in this provider specifically have these property +The implementations in this provider specifically has this property defined: =over 4 -"provider=legacy" +=item "provider=legacy" =back diff --git a/doc/man7/openssl-core_names.h.pod b/doc/man7/openssl-core_names.h.pod new file mode 100644 index 00000000..a11bf3fe --- /dev/null +++ b/doc/man7/openssl-core_names.h.pod @@ -0,0 +1,49 @@ +=pod + +=head1 NAME + +openssl/core_names.h - OpenSSL provider parameter names + +=head1 SYNOPSIS + + #include + +=head1 DESCRIPTION + +The F<< >> header defines a multitude of macros +for L names, algorithm names and other known names used +with OpenSSL's providers, made available for practical purposes only. + +Existing names are further described in the manuals for OpenSSL's +providers (see L) and the manuals for each algorithm they +provide (listed in those provider manuals). + +=head1 SEE ALSO + +L, L, +L + +=head1 HISTORY + +The macros described here were added in OpenSSL 3.0. + +=head1 CAVEATS + +I. +Providers that implement new algorithms are to be responsible for +their own parameter names. + +However, authors of provider that implement their own variants of +algorithms that OpenSSL providers support will want to pay attention +to the names provided in this header to work in a compatible manner. + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/openssl-core_numbers.h.pod b/doc/man7/openssl-core_numbers.h.pod new file mode 100644 index 00000000..d9bdcbc8 --- /dev/null +++ b/doc/man7/openssl-core_numbers.h.pod @@ -0,0 +1,56 @@ +=pod + +=head1 NAME + +openssl/core_numbers.h +- OpenSSL provider dispatch numbers and function types + +=head1 SYNOPSIS + + #include + +=head1 DESCRIPTION + +The F<< >> header defines all the operation +numbers, dispatch numbers and provider interface function types +currently available. + +The operation and dispatch numbers are represented with macros, which +are named as follows: + +=over 4 + +=item operation numbers + +These macros have the form C>. + +=item dipatch numbers + +These macros have the form C_I>, where +C> is the same as in the macro for the operation this +function belongs to. + +=back + +With every dispatch number, there is an associated function type. + +For further information, please see the L + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The types and macros described here were added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/provider-base.pod b/doc/man7/provider-base.pod index aefaa408..081be53a 100644 --- a/doc/man7/provider-base.pod +++ b/doc/man7/provider-base.pod @@ -234,22 +234,52 @@ useless without at least provider_query_operation(), and provider_gettable_params() is fairly useless if not accompanied by provider_get_params(). -=head2 Core parameters +=head2 Provider parameters -core_get_params() understands the following known parameters: +provider_get_params() can return the following provider parameters to the core: =over 4 -=item "openssl-version" +=item "name" (B) -This is a B type of parameter, pointing at the -OpenSSL libraries' full version string, i.e. the string expanded from -the macro B. +This points to a string that should give a unique name for the provider. -=item "provider-name" +=item "version" (B) -This is a B type of parameter, pointing at the -OpenSSL libraries' idea of what the calling provider is called. +This points to a string that is a version number associated with this provider. +OpenSSL in-built providers use OPENSSL_VERSION_STR, but this may be different +for any third party provider. This string is for informational purposes only. + +=item "buildinfo" (B) + +This points to a string that is a build information associated with this provider. +OpenSSL in-built providers use OPENSSL_FULL_VERSION_STR, but this may be +different for any third party provider. + +=back + +provider_gettable_params() should return the above parameters. + + +=head2 Core parameters + +core_get_params() can retrieve the following core parameters for each provider: + +=over 4 + +=item "openssl-version" (B) + +This points to the OpenSSL libraries' full version string, i.e. the string +expanded from the macro B. + +=item "provider-name" (B) + +This points to the OpenSSL libraries' idea of what the calling provider is named. + +=item "module-filename" (B) + +This points to a string containing the full filename of the providers +module file. =back diff --git a/doc/man7/provider-keyexch.pod b/doc/man7/provider-keyexch.pod index 1d34ded0..59cc2033 100644 --- a/doc/man7/provider-keyexch.pod +++ b/doc/man7/provider-keyexch.pod @@ -131,12 +131,12 @@ written to I<*secretlen>. OP_keyexch_set_ctx_params() sets key exchange parameters associated with the given provider side key exchange context I to I, -see L. +see L. Any parameter settings are additional to any that were previously set. OP_keyexch_get_ctx_params() gets key exchange parameters associated with the given provider side key exchange context I into I, -see L. +see L. OP_keyexch_settable_ctx_params() yields a constant B array that describes the settable parameters, i.e. parameters that can be used with @@ -152,15 +152,13 @@ See L for the use of B as parameter descriptor. Notice that not all settable parameters are also gettable, and vice versa. -=head2 Key Exchange Parameters +=head2 Common Key Exchange parameters See L for further details on the parameters structure used by the OP_keyexch_set_ctx_params() and OP_keyexch_get_ctx_params() functions. -Parameters currently recognised by built-in key exchange algorithms are as -follows. -Not all parameters are relevant to, or are understood by all key exchange -algorithms: +Common parameters currently recognised by built-in key exchange algorithms are +as follows. =over 4 @@ -168,63 +166,13 @@ algorithms: Sets the padding mode for the associated key exchange ctx. Setting a value of 1 will turn padding on. -Setting a vlue of 0 will turn padding off. +Setting a value of 0 will turn padding off. If padding is off then the derived shared secret may be smaller than the largest possible secret size. If padding is on then the derived shared secret will have its first bytes filled with 0s where necessary to make the shared secret the same size as the largest possible secret size. -=item "ecdh-cofactor-mode" (B) - -Sets/gets the ECDH mode of operation for the associated key exchange ctx. - -In the context of an Elliptic Curve Diffie-Hellman key exchange, this parameter -can be used to select between the plain Diffie-Hellman (DH) or Cofactor -Diffie-Hellman (CDH) variants of the key exchange algorithm. - -When setting, the value should be 1, 0 or -1, respectively forcing cofactor mode -on, off, or resetting it to the default for the private key associated with the -given key exchange ctx. - -When getting, the value should be either 1 or 0, respectively signaling if the -cofactor mode is on or off. - -See also L for the related -B parameter that can be set on a -per-key basis. - -=item "kdf-type" (B) - -Sets/gets the Key Derivation Function type to apply within the associated key -exchange ctx. - -=item "kdf-digest" (B) - -Sets/gets the Digest algorithm to be used as part of the Key Derivation Function -associated with the given key exchange ctx. - -=item "kdf-digest-props" (B) - -Sets properties to be used upon look up of the implementation for the selected -Digest algorithm for the Key Derivation Function associated with the given key -exchange ctx. - -=item "kdf-outlen" (B) - -Sets/gets the desired size for the output of the chosen Key Derivation Function -associated with the given key exchange ctx. - -=item "kdf-ukm" (B) - -Sets/gets User Key Material to be used as part of the selected Key Derivation -Function associated with the given key exchange ctx. - -=item "kdf-ukm-len" (B) - -Sets/gets the size of the User Key Material to be used as part of the selected -Key Derivation Function associated with the given key exchange ctx. - =back =head1 RETURN VALUES diff --git a/doc/man7/provider-signature.pod b/doc/man7/provider-signature.pod index 45d97e66..538c342e 100644 --- a/doc/man7/provider-signature.pod +++ b/doc/man7/provider-signature.pod @@ -303,7 +303,7 @@ initialised verification context is passed in the I parameter. The data to verified is in I which should be I bytes long. The signature to be verified is in I which is I bytes long. -=head2 Signature Parameters +=head2 Signature parameters See L for further details on the parameters structure used by the OP_signature_get_ctx_params() and OP_signature_set_ctx_params() functions. @@ -314,17 +314,20 @@ OP_signature_set_ctx_params() sets the signature parameters associated with the given provider side signature context I to I. Any parameter settings are additional to any that were previously set. -Parameters currently recognised by built-in signature algorithms are as +Common parameters currently recognised by built-in signature algorithms are as follows. -Not all parameters are relevant to, or are understood by all signature -algorithms: =over 4 =item "digest" (B) Get or sets the name of the digest algorithm used for the input to the signature -functions. +functions. It is required in order to calculate the "algorithm-id". + += item "properties" (B) + +Sets the name of the property query associated with the "digest" algorithm. +NULL is used if this optional value is not set. =item "digest-size" (B) @@ -358,7 +361,7 @@ i.e. parameters that can be used with OP_signature_get_ctx_params() and OP_signature_set_ctx_params() respectively. See L for the use of B as parameter descriptor. -=head2 MD Parameters +=head2 MD parameters See L for further details on the parameters structure used by the OP_signature_get_md_ctx_params() and OP_signature_set_md_ctx_params() diff --git a/doc/man7/proxy-certificates.pod b/doc/man7/proxy-certificates.pod index df5ee1b4..395fab86 100644 --- a/doc/man7/proxy-certificates.pod +++ b/doc/man7/proxy-certificates.pod @@ -57,24 +57,22 @@ See L for a discussion on this requirement. Creating proxy certificates can be done using the L command, with some extra extensions: - [ v3_proxy ] + [ proxy ] # A proxy certificate MUST NEVER be a CA certificate. - basicConstraints=CA:FALSE - + basicConstraints = CA:FALSE # Usual authority key ID - authorityKeyIdentifier=keyid,issuer:always - + authorityKeyIdentifier = keyid,issuer:always # The extension which marks this certificate as a proxy - proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB + proxyCertInfo = critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB It's also possible to specify the proxy extension in a separate section: - proxyCertInfo=critical,@proxy_ext + proxyCertInfo = critical,@proxy_ext [ proxy_ext ] - language=id-ppl-anyLanguage - pathlen=0 - policy=text:BC + language = id-ppl-anyLanguage + pathlen = 0 + policy = text:BC The policy value has a specific syntax, I:I, where the I determines what will be done with the string. The following @@ -99,12 +97,12 @@ colons between each byte (every second hex digit): indicates that the text of the policy should be taken from a file. The string is then a filename. This is useful for policies that are -large (more than a few lines, e.g. XML documents). +more than a few lines, such as XML or other markup. =back -I With a proxy extension, creating a proxy certificate is a matter of @@ -112,23 +110,23 @@ two commands: openssl req -new -config proxy.cnf \ -out proxy.req -keyout proxy.key \ - -subj "/DC=org/DC=openssl/DC=users/CN=proxy 1" + -subj "/DC=org/DC=openssl/DC=users/CN=proxy" openssl x509 -req -CAcreateserial -in proxy.req -out proxy.crt \ -CA user.crt -CAkey user.key -days 7 \ - -extfile proxy.cnf -extensions v3_proxy1 + -extfile proxy.cnf -extensions proxy You can also create a proxy certificate using another proxy -certificate as issuer (note: using a different configuration -section for the proxy extensions): +certificate as issuer. Note that this example uses a different +configuration section for the proxy extensions: openssl req -new -config proxy.cnf \ -out proxy2.req -keyout proxy2.key \ - -subj "/DC=org/DC=openssl/DC=users/CN=proxy 1/CN=proxy 2" + -subj "/DC=org/DC=openssl/DC=users/CN=proxy/CN=proxy 2" openssl x509 -req -CAcreateserial -in proxy2.req -out proxy2.crt \ -CA proxy.crt -CAkey proxy.key -days 7 \ - -extfile proxy.cnf -extensions v3_proxy2 + -extfile proxy.cnf -extensions proxy_2 =head2 Using proxy certs in applications @@ -353,7 +351,7 @@ L =head1 COPYRIGHT -Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/fuzz/cmp.c b/fuzz/cmp.c index 6883a286..100350eb 100644 --- a/fuzz/cmp.c +++ b/fuzz/cmp.c @@ -94,7 +94,7 @@ static void cmp_client_process_response(OSSL_CMP_CTX *ctx, OSSL_CMP_MSG *msg) OSSL_CMP_ITAV_free); break; default: - (void)ossl_cmp_msg_check_received(ctx, msg, allow_unprotected, 0); + (void)ossl_cmp_msg_check_update(ctx, msg, allow_unprotected, 0); break; } err: diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h index aaf091f8..d3683649 100644 --- a/include/crypto/asn1.h +++ b/include/crypto/asn1.h @@ -19,7 +19,7 @@ struct evp_pkey_asn1_method_st { unsigned long pkey_flags; char *pem_str; char *info; - int (*pub_decode) (EVP_PKEY *pk, X509_PUBKEY *pub); + int (*pub_decode) (EVP_PKEY *pk, const X509_PUBKEY *pub); int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk); int (*pub_cmp) (const EVP_PKEY *a, const EVP_PKEY *b); int (*pub_print) (BIO *out, const EVP_PKEY *pkey, int indent, diff --git a/include/crypto/cms.h b/include/crypto/cms.h index c630991d..67263fa8 100644 --- a/include/crypto/cms.h +++ b/include/crypto/cms.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,7 +7,15 @@ * https://www.openssl.org/source/license.html */ +#ifndef OPENSSL_NO_CMS + /* internal CMS-ESS related stuff */ int cms_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc); int cms_add1_signing_cert_v2(CMS_SignerInfo *si, ESS_SIGNING_CERT_V2 *sc); + +int cms_signerinfo_get_signing_cert_v2(CMS_SignerInfo *si, + ESS_SIGNING_CERT_V2 **psc); +int cms_signerinfo_get_signing_cert(CMS_SignerInfo *si, + ESS_SIGNING_CERT **psc); +#endif diff --git a/include/crypto/dh.h b/include/crypto/dh.h index 1ae2c2f0..f67b4e01 100644 --- a/include/crypto/dh.h +++ b/include/crypto/dh.h @@ -32,3 +32,6 @@ int dh_check_priv_key(const DH *dh, const BIGNUM *priv_key, int *ret); int dh_check_pairwise(DH *dh); const DH_METHOD *dh_get_method(const DH *dh); + +int dh_buf2key(DH *key, const unsigned char *buf, size_t len); +size_t dh_key2buf(const DH *dh, unsigned char **pbuf, size_t size, int alloc); diff --git a/include/crypto/ec.h b/include/crypto/ec.h index b4dd2f18..bccebb06 100644 --- a/include/crypto/ec.h +++ b/include/crypto/ec.h @@ -62,7 +62,7 @@ const unsigned char *ecdsa_algorithmidentifier_encoding(int md_nid, size_t *len) int ec_key_fromdata(EC_KEY *ecx, const OSSL_PARAM params[], int include_private); int ec_key_domparams_fromdata(EC_KEY *ecx, const OSSL_PARAM params[]); int ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]); -int ec_set_param_ecdh_cofactor_mode(EC_KEY *ec, const OSSL_PARAM *p); +int ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode); # endif /* OPENSSL_NO_EC */ #endif diff --git a/include/crypto/ess.h b/include/crypto/ess.h index ac6c5c61..6ae9a818 100644 --- a/include/crypto/ess.h +++ b/include/crypto/ess.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -24,6 +24,10 @@ ESS_SIGNING_CERT_V2 *ESS_SIGNING_CERT_V2_new_init(const EVP_MD *hash_alg, STACK_OF(X509) *certs, int issuer_needed); +/* Returns < 0 if certificate is not found, certificate index otherwise. */ +int ess_find_cert_v2(const STACK_OF(ESS_CERT_ID_V2) *cert_ids, const X509 *cert); +int ess_find_cert(const STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); + /*- * IssuerSerial ::= SEQUENCE { * issuer GeneralNames, diff --git a/include/crypto/evp.h b/include/crypto/evp.h index ee4b6221..d1756cf1 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -518,9 +518,25 @@ const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; } * (type != EVP_PKEY_NONE && pkey.ptr != NULL) ## legacy (libcrypto only) * || (keymgmt != NULL && keydata != NULL) ## provider side * - * The easiest way to detect a legacy key is: type != EVP_PKEY_NONE - * The easiest way to detect a provider side key is: keymgmt != NULL + * The easiest way to detect a legacy key is: + * + * keymgmt == NULL && type != EVP_PKEY_NONE + * + * The easiest way to detect a provider side key is: + * + * keymgmt != NULL */ +#define evp_pkey_is_blank(pk) \ + ((pk)->type == EVP_PKEY_NONE && (pk)->keymgmt == NULL) +#define evp_pkey_is_typed(pk) \ + ((pk)->type != EVP_PKEY_NONE || (pk)->keymgmt != NULL) +#define evp_pkey_is_assigned(pk) \ + ((pk)->pkey.ptr != NULL || (pk)->keydata != NULL) +#define evp_pkey_is_legacy(pk) \ + ((pk)->type != EVP_PKEY_NONE && (pk)->keymgmt == NULL) +#define evp_pkey_is_provided(pk) \ + ((pk)->keymgmt != NULL) + struct evp_pkey_st { /* == Legacy attributes == */ int type; diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h index 6f32ec42..5d7a6e51 100644 --- a/include/crypto/rsa.h +++ b/include/crypto/rsa.h @@ -69,6 +69,13 @@ int rsa_padding_check_PKCS1_type_2_TLS(OPENSSL_CTX *ctx, unsigned char *to, size_t tlen, const unsigned char *from, size_t flen, int client_version, int alt_version); +int rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(OPENSSL_CTX *libctx, + unsigned char *to, int tlen, + const unsigned char *from, + int flen, + const unsigned char *param, + int plen, const EVP_MD *md, + const EVP_MD *mgf1md); int rsa_validate_public(const RSA *key); int rsa_validate_private(const RSA *key); diff --git a/include/internal/core.h b/include/internal/core.h index ca043334..8823b3c7 100644 --- a/include/internal/core.h +++ b/include/internal/core.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -50,9 +50,13 @@ void *ossl_method_construct(OPENSSL_CTX *ctx, int operation_id, void ossl_algorithm_do_all(OPENSSL_CTX *libctx, int operation_id, OSSL_PROVIDER *provider, + int (*pre)(OSSL_PROVIDER *, int operation_id, + void *data, int *result), void (*fn)(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo, int no_store, void *data), + int (*post)(OSSL_PROVIDER *, int operation_id, + int no_store, void *data, int *result), void *data); #endif diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h index b479b58a..a4f18a5d 100644 --- a/include/internal/cryptlib.h +++ b/include/internal/cryptlib.h @@ -241,4 +241,8 @@ char *sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, const char *sep, size_t max_len); char *ipaddr_to_asc(unsigned char *p, int len); +char *openssl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep); +unsigned char *openssl_hexstr2buf_sep(const char *str, long *buflen, + const char sep); + #endif diff --git a/include/internal/ktls.h b/include/internal/ktls.h index 209dff16..093a6618 100644 --- a/include/internal/ktls.h +++ b/include/internal/ktls.h @@ -7,6 +7,19 @@ * https://www.openssl.org/source/license.html */ +#if defined(OPENSSL_SYS_LINUX) +# ifndef OPENSSL_NO_KTLS +# include +# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) +# define OPENSSL_NO_KTLS +# ifndef PEDANTIC +# warning "KTLS requires Kernel Headers >= 4.13.0" +# warning "Skipping Compilation of KTLS" +# endif +# endif +# endif +#endif + #ifndef OPENSSL_NO_KTLS # ifndef HEADER_INTERNAL_KTLS # define HEADER_INTERNAL_KTLS @@ -40,12 +53,12 @@ static ossl_inline int ktls_enable(int fd) * provided here. */ static ossl_inline int ktls_start(int fd, - struct tls_enable *tls_en, + void *tls_en, size_t len, int is_tx) { if (is_tx) return setsockopt(fd, IPPROTO_TCP, TCP_TXTLS_ENABLE, - tls_en, sizeof(*tls_en)) ? 0 : 1; + tls_en, len) ? 0 : 1; else return 0; } @@ -109,94 +122,57 @@ static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, # endif /* __FreeBSD__ */ # if defined(OPENSSL_SYS_LINUX) -# include - -# define K_MAJ 4 -# define K_MIN1 13 -# define K_MIN2 0 -# if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1, K_MIN2) +# include +# if LINUX_VERSION_CODE < KERNEL_VERSION(4, 17, 0) +# define OPENSSL_NO_KTLS_RX # ifndef PEDANTIC -# warning "KTLS requires Kernel Headers >= 4.13.0" -# warning "Skipping Compilation of KTLS" +# warning "KTLS requires Kernel Headers >= 4.17.0 for receiving" +# warning "Skipping Compilation of KTLS receive data path" # endif +# endif +# define OPENSSL_KTLS_AES_GCM_128 +# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0) +# define OPENSSL_KTLS_AES_GCM_256 +# define OPENSSL_KTLS_TLS13 +# if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0) +# define OPENSSL_KTLS_AES_CCM_128 +# endif +# endif -# define TLS_TX 1 +# include +# include +# include +# include "openssl/ssl3.h" +# include "openssl/tls1.h" +# include "openssl/evp.h" + +# ifndef SOL_TLS +# define SOL_TLS 282 +# endif + +# ifndef TCP_ULP +# define TCP_ULP 31 +# endif + +# ifndef TLS_RX # define TLS_RX 2 +# endif -# define TLS_CIPHER_AES_GCM_128 51 -# define TLS_CIPHER_AES_GCM_128_IV_SIZE 8 -# define TLS_CIPHER_AES_GCM_128_KEY_SIZE 16 -# define TLS_CIPHER_AES_GCM_128_SALT_SIZE 4 -# define TLS_CIPHER_AES_GCM_128_TAG_SIZE 16 -# define TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE 8 - -# define TLS_SET_RECORD_TYPE 1 - -struct tls_crypto_info { - unsigned short version; - unsigned short cipher_type; +struct tls_crypto_info_all { + union { +# ifdef OPENSSL_KTLS_AES_GCM_128 + struct tls12_crypto_info_aes_gcm_128 gcm128; +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + struct tls12_crypto_info_aes_gcm_256 gcm256; +# endif +# ifdef OPENSSL_KTLS_AES_CCM_128 + struct tls12_crypto_info_aes_ccm_128 ccm128; +# endif + }; + size_t tls_crypto_info_len; }; - -struct tls12_crypto_info_aes_gcm_128 { - struct tls_crypto_info info; - unsigned char iv[TLS_CIPHER_AES_GCM_128_IV_SIZE]; - unsigned char key[TLS_CIPHER_AES_GCM_128_KEY_SIZE]; - unsigned char salt[TLS_CIPHER_AES_GCM_128_SALT_SIZE]; - unsigned char rec_seq[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; -}; - -/* Dummy functions here */ -static ossl_inline int ktls_enable(int fd) -{ - return 0; -} - -static ossl_inline int ktls_start(int fd, - struct tls12_crypto_info_aes_gcm_128 - *crypto_info, size_t len, int is_tx) -{ - return 0; -} - -static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, - const void *data, size_t length) -{ - return -1; -} - -static ossl_inline int ktls_read_record(int fd, void *data, size_t length) -{ - return -1; -} - -static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags) -{ - return -1; -} - -# else /* KERNEL_VERSION */ - -# include -# include -# include -# include -# include "openssl/ssl3.h" -# include "openssl/tls1.h" -# include "openssl/evp.h" - -# ifndef SOL_TLS -# define SOL_TLS 282 -# endif - -# ifndef TCP_ULP -# define TCP_ULP 31 -# endif - -# ifndef TLS_RX -# define TLS_RX 2 -# endif - /* * When successful, this socket option doesn't change the behaviour of the * TCP socket, except changing the TCP setsockopt handler to enable the @@ -216,12 +192,11 @@ static ossl_inline int ktls_enable(int fd) * If successful, then data received using this socket will be decrypted, * authenticated and decapsulated using the crypto_info provided here. */ -static ossl_inline int ktls_start(int fd, - struct tls12_crypto_info_aes_gcm_128 - *crypto_info, size_t len, int is_tx) +static ossl_inline int ktls_start(int fd, void *crypto_info, + size_t len, int is_tx) { return setsockopt(fd, SOL_TLS, is_tx ? TLS_TX : TLS_RX, - crypto_info, sizeof(*crypto_info)) ? 0 : 1; + crypto_info, len) ? 0 : 1; } /* @@ -270,20 +245,15 @@ static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t s return sendfile(s, fd, &off, size); } -# define K_MIN1_RX 17 -# if LINUX_VERSION_CODE < KERNEL_VERSION(K_MAJ, K_MIN1_RX, K_MIN2) +# ifdef OPENSSL_NO_KTLS_RX -# ifndef PEDANTIC -# warning "KTLS requires Kernel Headers >= 4.17.0 for receiving" -# warning "Skipping Compilation of KTLS receive data path" -# endif static ossl_inline int ktls_read_record(int fd, void *data, size_t length) { return -1; } -# else +# else /* !defined(OPENSSL_NO_KTLS_RX) */ /* * Receive a TLS record using the crypto_info provided in ktls_start. @@ -338,8 +308,132 @@ static ossl_inline int ktls_read_record(int fd, void *data, size_t length) return ret; } -# endif -# endif +# endif /* OPENSSL_NO_KTLS_RX */ + +/* Function to check supported ciphers in Linux */ +static ossl_inline int ktls_check_supported_cipher(const EVP_CIPHER *c, + const EVP_CIPHER_CTX *dd) +{ + /* check that cipher is AES_GCM_128, AES_GCM_256, AES_CCM_128 */ + switch (EVP_CIPHER_nid(c)) + { +# ifdef OPENSSL_KTLS_AES_CCM_128 + case NID_aes_128_ccm: + if (EVP_CIPHER_CTX_tag_length(dd) != EVP_CCM_TLS_TAG_LEN) + return 0; # endif -# endif +# ifdef OPENSSL_KTLS_AES_GCM_128 + case NID_aes_128_gcm: +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + case NID_aes_256_gcm: +# endif + return 1; + default: + return 0; + } +} + +/* Function to configure kernel TLS structure */ +static ossl_inline int ktls_configure_crypto(const EVP_CIPHER *c, int tls_version, + EVP_CIPHER_CTX *dd, void *rl_sequence, + struct tls_crypto_info_all *crypto_info, + unsigned char **rec_seq, unsigned char *iv, + unsigned char *key) +{ + unsigned char geniv[12]; + unsigned char *iiv = iv; + + if (tls_version == TLS1_2_VERSION && + EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { + EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV, + EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN, + geniv); + iiv = geniv; + } + + memset(crypto_info, 0, sizeof(*crypto_info)); + switch (EVP_CIPHER_nid(c)) + { +# ifdef OPENSSL_KTLS_AES_GCM_128 + case NID_aes_128_gcm: + crypto_info->gcm128.info.cipher_type = TLS_CIPHER_AES_GCM_128; + crypto_info->gcm128.info.version = tls_version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm128); + memcpy(crypto_info->gcm128.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, + TLS_CIPHER_AES_GCM_128_IV_SIZE); + memcpy(crypto_info->gcm128.salt, iiv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); + memcpy(crypto_info->gcm128.key, key, EVP_CIPHER_key_length(c)); + memcpy(crypto_info->gcm128.rec_seq, rl_sequence, + TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->gcm128.rec_seq; + return 1; +# endif +# ifdef OPENSSL_KTLS_AES_GCM_256 + case NID_aes_256_gcm: + crypto_info->gcm256.info.cipher_type = TLS_CIPHER_AES_GCM_256; + crypto_info->gcm256.info.version = tls_version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->gcm256); + memcpy(crypto_info->gcm256.iv, iiv + EVP_GCM_TLS_FIXED_IV_LEN, + TLS_CIPHER_AES_GCM_256_IV_SIZE); + memcpy(crypto_info->gcm256.salt, iiv, TLS_CIPHER_AES_GCM_256_SALT_SIZE); + memcpy(crypto_info->gcm256.key, key, EVP_CIPHER_key_length(c)); + memcpy(crypto_info->gcm256.rec_seq, rl_sequence, + TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->gcm256.rec_seq; + return 1; +# endif +# ifdef OPENSSL_KTLS_AES_CCM_128 + case NID_aes_128_ccm: + crypto_info->ccm128.info.cipher_type = TLS_CIPHER_AES_CCM_128; + crypto_info->ccm128.info.version = tls_version; + crypto_info->tls_crypto_info_len = sizeof(crypto_info->ccm128); + memcpy(crypto_info->ccm128.iv, iiv + EVP_CCM_TLS_FIXED_IV_LEN, + TLS_CIPHER_AES_CCM_128_IV_SIZE); + memcpy(crypto_info->ccm128.salt, iiv, TLS_CIPHER_AES_CCM_128_SALT_SIZE); + memcpy(crypto_info->ccm128.key, key, EVP_CIPHER_key_length(c)); + memcpy(crypto_info->ccm128.rec_seq, rl_sequence, + TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); + if (rec_seq != NULL) + *rec_seq = crypto_info->ccm128.rec_seq; + return 1; +# endif + default: + return 0; + } + +} + +# endif /* OPENSSL_SYS_LINUX */ +# endif /* HEADER_INTERNAL_KTLS */ +#else /* defined(OPENSSL_NO_KTLS) */ +/* Dummy functions here */ +static ossl_inline int ktls_enable(int fd) +{ + return 0; +} + +static ossl_inline int ktls_start(int fd, void *crypto_info, + size_t len, int is_tx) +{ + return 0; +} + +static ossl_inline int ktls_send_ctrl_message(int fd, unsigned char record_type, + const void *data, size_t length) +{ + return -1; +} + +static ossl_inline int ktls_read_record(int fd, void *data, size_t length) +{ + return -1; +} + +static ossl_inline ossl_ssize_t ktls_sendfile(int s, int fd, off_t off, size_t size, int flags) +{ + return -1; +} #endif diff --git a/include/internal/provider.h b/include/internal/provider.h index e39a5eae..d7c0926a 100644 --- a/include/internal/provider.h +++ b/include/internal/provider.h @@ -64,6 +64,7 @@ const char *ossl_provider_name(const OSSL_PROVIDER *prov); const DSO *ossl_provider_dso(const OSSL_PROVIDER *prov); const char *ossl_provider_module_name(const OSSL_PROVIDER *prov); const char *ossl_provider_module_path(const OSSL_PROVIDER *prov); +void *ossl_provider_prov_ctx(const OSSL_PROVIDER *prov); OPENSSL_CTX *ossl_provider_library_context(const OSSL_PROVIDER *prov); /* Thin wrappers around calls to the provider */ @@ -74,6 +75,11 @@ const OSSL_ALGORITHM *ossl_provider_query_operation(const OSSL_PROVIDER *prov, int operation_id, int *no_cache); +/* Cache of bits to see if we already queried an operation */ +int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum); +int ossl_provider_test_operation_bit(OSSL_PROVIDER *provider, size_t bitnum, + int *result); + /* Configuration */ void ossl_provider_add_conf_module(void); diff --git a/include/openssl/bio.h b/include/openssl/bio.h index 19f9311c..52d042b0 100644 --- a/include/openssl/bio.h +++ b/include/openssl/bio.h @@ -662,10 +662,7 @@ int BIO_dgram_sctp_msg_waiting(BIO *b); # ifndef OPENSSL_NO_SOCK int BIO_sock_should_retry(int i); int BIO_sock_non_fatal_error(int error); -int BIO_socket_wait(int fd, int for_read, time_t max_time); # endif -int BIO_wait(BIO *bio, time_t max_time, unsigned int milliseconds); -int BIO_connect_retry(BIO *bio, int timeout); int BIO_fd_should_retry(int i); int BIO_fd_non_fatal_error(int error); diff --git a/include/openssl/bioerr.h b/include/openssl/bioerr.h index 7c51cceb..e1c3bcb5 100644 --- a/include/openssl/bioerr.h +++ b/include/openssl/bioerr.h @@ -92,7 +92,6 @@ int ERR_load_BIO_strings(void); # define BIO_R_BAD_FOPEN_MODE 101 # define BIO_R_BROKEN_PIPE 124 # define BIO_R_CONNECT_ERROR 103 -# define BIO_R_CONNECT_TIMEOUT 147 # define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 # define BIO_R_GETSOCKNAME_ERROR 132 # define BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS 133 @@ -110,8 +109,6 @@ int ERR_load_BIO_strings(void); # define BIO_R_NO_PORT_DEFINED 113 # define BIO_R_NO_SUCH_FILE 128 # define BIO_R_NULL_PARAMETER 115 -# define BIO_R_TRANSFER_ERROR 104 -# define BIO_R_TRANSFER_TIMEOUT 105 # define BIO_R_UNABLE_TO_BIND_SOCKET 117 # define BIO_R_UNABLE_TO_CREATE_SOCKET 118 # define BIO_R_UNABLE_TO_KEEPALIVE 137 diff --git a/include/openssl/cmp.h b/include/openssl/cmp.h index e06fba9b..6826c936 100644 --- a/include/openssl/cmp.h +++ b/include/openssl/cmp.h @@ -18,7 +18,6 @@ # include # include # include -# include /* explicit #includes not strictly needed since implied by the above: */ # include @@ -271,14 +270,17 @@ int OSSL_CMP_CTX_get_option(const OSSL_CMP_CTX *ctx, int opt); int OSSL_CMP_CTX_set_log_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_log_cb_t cb); # define OSSL_CMP_CTX_set_log_verbosity(ctx, level) \ OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_LOG_VERBOSITY, level) -void OSSL_CMP_CTX_print_errors(OSSL_CMP_CTX *ctx); +void OSSL_CMP_CTX_print_errors(const OSSL_CMP_CTX *ctx); /* message transfer: */ int OSSL_CMP_CTX_set1_serverPath(OSSL_CMP_CTX *ctx, const char *path); -int OSSL_CMP_CTX_set1_server(OSSL_CMP_CTX *ctx, const char *address); +int OSSL_CMP_CTX_set1_serverName(OSSL_CMP_CTX *ctx, const char *name); int OSSL_CMP_CTX_set_serverPort(OSSL_CMP_CTX *ctx, int port); -int OSSL_CMP_CTX_set1_proxy(OSSL_CMP_CTX *ctx, const char *name); -int OSSL_CMP_CTX_set1_no_proxy(OSSL_CMP_CTX *ctx, const char *names); -int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_HTTP_bio_cb_t cb); +# define OSSL_CMP_DEFAULT_PORT 80 +int OSSL_CMP_CTX_set1_proxyName(OSSL_CMP_CTX *ctx, const char *name); +int OSSL_CMP_CTX_set_proxyPort(OSSL_CMP_CTX *ctx, int port); +typedef BIO *(*OSSL_CMP_http_cb_t) (OSSL_CMP_CTX *ctx, BIO *hbio, + unsigned long detail); +int OSSL_CMP_CTX_set_http_cb(OSSL_CMP_CTX *ctx, OSSL_CMP_http_cb_t cb); int OSSL_CMP_CTX_set_http_cb_arg(OSSL_CMP_CTX *ctx, void *arg); void *OSSL_CMP_CTX_get_http_cb_arg(const OSSL_CMP_CTX *ctx); typedef OSSL_CMP_MSG *(*OSSL_CMP_transfer_cb_t) (OSSL_CMP_CTX *ctx, @@ -359,13 +361,9 @@ int i2d_OSSL_CMP_MSG_bio(BIO *bio, const OSSL_CMP_MSG *msg); /* from cmp_vfy.c */ int OSSL_CMP_validate_msg(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg); -int OSSL_CMP_validate_cert_path(OSSL_CMP_CTX *ctx, +int OSSL_CMP_validate_cert_path(const OSSL_CMP_CTX *ctx, X509_STORE *trusted_store, X509 *cert); -/* from cmp_http.c */ -OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, - const OSSL_CMP_MSG *req); - /* from cmp_server.c */ typedef struct ossl_cmp_srv_ctx_st OSSL_CMP_SRV_CTX; OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, diff --git a/include/openssl/cmp_util.h b/include/openssl/cmp_util.h index a243d7e7..2acd2df2 100644 --- a/include/openssl/cmp_util.h +++ b/include/openssl/cmp_util.h @@ -17,6 +17,7 @@ # include # include +# include # ifdef __cplusplus extern "C" { diff --git a/include/openssl/cmperr.h b/include/openssl/cmperr.h index 31fa43cd..d1ce2256 100644 --- a/include/openssl/cmperr.h +++ b/include/openssl/cmperr.h @@ -10,6 +10,7 @@ #ifndef OPENSSL_CMPERR_H # define OPENSSL_CMPERR_H +# pragma once # include # include @@ -68,6 +69,7 @@ int ERR_load_CMP_strings(void); # define CMP_R_ERROR_SETTING_CERTHASH 128 # define CMP_R_ERROR_UNEXPECTED_CERTCONF 160 # define CMP_R_ERROR_VALIDATING_PROTECTION 140 +# define CMP_R_ERROR_VALIDATING_SIGNATURE 171 # define CMP_R_FAILED_EXTRACTING_PUBKEY 141 # define CMP_R_FAILURE_OBTAINING_RANDOM 110 # define CMP_R_FAIL_INFO_OUT_OF_RANGE 129 diff --git a/include/openssl/cmserr.h b/include/openssl/cmserr.h index 6cff785c..97704bfa 100644 --- a/include/openssl/cmserr.h +++ b/include/openssl/cmserr.h @@ -109,6 +109,7 @@ int ERR_load_CMS_strings(void); # define CMS_F_CMS_SIGN 0 # define CMS_F_CMS_SIGNED_DATA_INIT 0 # define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN 0 +# define CMS_F_CMS_SIGNERINFO_GET_CHAIN 0 # define CMS_F_CMS_SIGNERINFO_SIGN 0 # define CMS_F_CMS_SIGNERINFO_VERIFY 0 # define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 0 @@ -118,6 +119,7 @@ int ERR_load_CMS_strings(void); # define CMS_F_CMS_STREAM 0 # define CMS_F_CMS_UNCOMPRESS 0 # define CMS_F_CMS_VERIFY 0 +# define CMS_F_ESS_CHECK_SIGNING_CERTS 0 # define CMS_F_KEK_UNWRAP_KEY 0 # endif @@ -147,6 +149,8 @@ int ERR_load_CMS_strings(void); # define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 # define CMS_R_ERROR_SETTING_KEY 115 # define CMS_R_ERROR_SETTING_RECIPIENTINFO 116 +# define CMS_R_ESS_NO_SIGNING_CERTID_ATTRIBUTE 182 +# define CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR 183 # define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 # define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176 # define CMS_R_INVALID_KEY_LENGTH 118 diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index 1bd12248..f04168e8 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -14,11 +14,15 @@ extern "C" { # endif +/* Well known parameter names that core passes to providers */ +#define OSSL_PROV_PARAM_CORE_VERSION "openssl-version" /* utf8_ptr */ +#define OSSL_PROV_PARAM_CORE_PROV_NAME "provider-name" /* utf8_ptr */ +#define OSSL_PROV_PARAM_CORE_MODULE_FILENAME "module-filename" /* utf8_ptr */ + /* Well known parameter names that Providers can define */ #define OSSL_PROV_PARAM_NAME "name" /* utf8_string */ #define OSSL_PROV_PARAM_VERSION "version" /* utf8_string */ #define OSSL_PROV_PARAM_BUILDINFO "buildinfo" /* utf8_string */ -#define OSSL_PROV_PARAM_MODULE_FILENAME "module-filename" /* octet_string */ /* Self test callback parameters */ #define OSSL_PROV_PARAM_SELF_TEST_PHASE "st-phase" /* utf8_string */ @@ -29,6 +33,8 @@ extern "C" { * Algorithm parameters * If "engine" or "properties" are specified, they should always be paired * with the algorithm type. + * Note these are common names that are shared by many types (such as kdf, mac, + * and pkey) e.g: see OSSL_MAC_PARAM_DIGEST below. */ #define OSSL_ALG_PARAM_DIGEST "digest" /* utf8_string */ #define OSSL_ALG_PARAM_CIPHER "cipher" /* utf8_string */ @@ -123,11 +129,16 @@ extern "C" { #define OSSL_MAC_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES /* utf8 string */ #define OSSL_MAC_PARAM_SIZE "size" /* size_t */ -/* Known MAC names (not a complete list) */ +/* Known MAC names */ +#define OSSL_MAC_NAME_BLAKE2BMAC "BLAKE2BMAC" +#define OSSL_MAC_NAME_BLAKE2SMAC "BLAKE2SMAC" #define OSSL_MAC_NAME_CMAC "CMAC" +#define OSSL_MAC_NAME_GMAC "GMAC" #define OSSL_MAC_NAME_HMAC "HMAC" #define OSSL_MAC_NAME_KMAC128 "KMAC128" #define OSSL_MAC_NAME_KMAC256 "KMAC256" +#define OSSL_MAC_NAME_POLY1305 "POLY1305" +#define OSSL_MAC_NAME_SIPHASH "SIPHASH" /* KDF / PRF parameters */ #define OSSL_KDF_PARAM_SECRET "secret" /* octet string */ @@ -179,12 +190,11 @@ extern "C" { #define OSSL_PKEY_PARAM_DEFAULT_DIGEST "default-digest" /* utf8 string */ #define OSSL_PKEY_PARAM_MANDATORY_DIGEST "mandatory-digest" /* utf8 string */ #define OSSL_PKEY_PARAM_PAD_MODE "pad-mode" -#define OSSL_PKEY_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST -#define OSSL_PKEY_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES #define OSSL_PKEY_PARAM_DIGEST_SIZE "digest-size" #define OSSL_PKEY_PARAM_MASKGENFUNC "mgf" #define OSSL_PKEY_PARAM_MGF1_DIGEST "mgf1-digest" #define OSSL_PKEY_PARAM_MGF1_PROPERTIES "mgf1-properties" +#define OSSL_PKEY_PARAM_TLS_ENCODED_PT "tls-encoded-pt" /* Diffie-Hellman/DSA public/private key */ #define OSSL_PKEY_PARAM_PUB_KEY "pub" @@ -194,13 +204,6 @@ extern "C" { #define OSSL_PKEY_PARAM_FFC_P "p" #define OSSL_PKEY_PARAM_FFC_G "g" #define OSSL_PKEY_PARAM_FFC_Q "q" -#define OSSL_PKEY_PARAM_FFC_GINDEX "gindex" -#define OSSL_PKEY_PARAM_FFC_PCOUNTER "pcounter" -#define OSSL_PKEY_PARAM_FFC_SEED "seed" -#define OSSL_PKEY_PARAM_FFC_COFACTOR "j" -#define OSSL_PKEY_PARAM_FFC_H "hindex" -#define OSSL_PKEY_PARAM_FFC_GROUP "group" - #define OSSL_PKEY_PARAM_FFC_GINDEX "gindex" #define OSSL_PKEY_PARAM_FFC_PCOUNTER "pcounter" #define OSSL_PKEY_PARAM_FFC_SEED "seed" @@ -208,8 +211,8 @@ extern "C" { #define OSSL_PKEY_PARAM_FFC_H "hindex" /* Diffie-Hellman params */ -#define OSSL_PKEY_PARAM_FFC_GROUP "group" -#define OSSL_PKEY_PARAM_FFC_GENERATOR "safeprime-generator" +#define OSSL_PKEY_PARAM_DH_GROUP "group" +#define OSSL_PKEY_PARAM_DH_GENERATOR "safeprime-generator" #define OSSL_PKEY_PARAM_DH_PRIV_LEN "priv_len" /* Elliptic Curve Domain Parameters */ @@ -270,6 +273,18 @@ extern "C" { #define OSSL_PKEY_PARAM_RSA_COEFFICIENT8 OSSL_PKEY_PARAM_RSA_COEFFICIENT"8" #define OSSL_PKEY_PARAM_RSA_COEFFICIENT9 OSSL_PKEY_PARAM_RSA_COEFFICIENT"9" +/* RSA padding modes */ +#define OSSL_PKEY_RSA_PAD_MODE_NONE "none" +#define OSSL_PKEY_RSA_PAD_MODE_PKCSV15 "pkcs1" +#define OSSL_PKEY_RSA_PAD_MODE_SSLV23 "sslv23" +#define OSSL_PKEY_RSA_PAD_MODE_OAEP "oaep" +#define OSSL_PKEY_RSA_PAD_MODE_X931 "x931" +#define OSSL_PKEY_RSA_PAD_MODE_PSS "pss" + +/* RSA pss padding salt length */ +#define OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST "digest" +#define OSSL_PKEY_RSA_PSS_SALT_LEN_MAX "max" +#define OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO "auto" /* Key generation parameters */ #define OSSL_PKEY_PARAM_RSA_BITS OSSL_PKEY_PARAM_BITS @@ -287,7 +302,6 @@ extern "C" { #define OSSL_PKEY_PARAM_FFC_DIGEST_PROPS OSSL_PKEY_PARAM_PROPERTIES /* Key Exchange parameters */ - #define OSSL_EXCHANGE_PARAM_PAD "pad" /* uint */ #define OSSL_EXCHANGE_PARAM_EC_ECDH_COFACTOR_MODE "ecdh-cofactor-mode" /* int */ #define OSSL_EXCHANGE_PARAM_KDF_TYPE "kdf-type" /* utf8_string */ diff --git a/include/openssl/crmf.h b/include/openssl/crmf.h index 28eb6825..d262a9b7 100644 --- a/include/openssl/crmf.h +++ b/include/openssl/crmf.h @@ -51,6 +51,7 @@ typedef struct ossl_crmf_poposigningkey_st OSSL_CRMF_POPOSIGNINGKEY; typedef struct ossl_crmf_certrequest_st OSSL_CRMF_CERTREQUEST; typedef struct ossl_crmf_certid_st OSSL_CRMF_CERTID; DECLARE_ASN1_FUNCTIONS(OSSL_CRMF_CERTID) +DECLARE_ASN1_DUP_FUNCTION(OSSL_CRMF_CERTID) DEFINE_OR_DECLARE_STACK_OF(OSSL_CRMF_CERTID) typedef struct ossl_crmf_pkipublicationinfo_st OSSL_CRMF_PKIPUBLICATIONINFO; diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index 3cca316c..58965de0 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -201,7 +201,7 @@ typedef void CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, int idx, long argl, void *argp); typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, - void *from_d, int idx, long argl, void *argp); + void **from_d, int idx, long argl, void *argp); __owur int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, diff --git a/include/openssl/dherr.h b/include/openssl/dherr.h index 0ebe5605..1b8fb171 100644 --- a/include/openssl/dherr.h +++ b/include/openssl/dherr.h @@ -62,6 +62,7 @@ int ERR_load_DH_strings(void); /* * DH reason codes. */ +# define DH_R_BAD_FFC_PARAMETERS 127 # define DH_R_BAD_GENERATOR 101 # define DH_R_BN_DECODE_ERROR 109 # define DH_R_BN_ERROR 106 diff --git a/include/openssl/dsaerr.h b/include/openssl/dsaerr.h index e2cf3098..271f24a2 100644 --- a/include/openssl/dsaerr.h +++ b/include/openssl/dsaerr.h @@ -57,6 +57,7 @@ int ERR_load_DSA_strings(void); /* * DSA reason codes. */ +# define DSA_R_BAD_FFC_PARAMETERS 114 # define DSA_R_BAD_Q_VALUE 102 # define DSA_R_BN_DECODE_ERROR 108 # define DSA_R_BN_ERROR 109 diff --git a/include/openssl/ec.h b/include/openssl/ec.h index 703fc1cd..90e109b6 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -47,7 +47,9 @@ typedef enum { POINT_CONVERSION_HYBRID = 6 } point_conversion_form_t; +# ifndef OPENSSL_NO_DEPRECATED_3_0 typedef struct ec_method_st EC_METHOD; +# endif typedef struct ec_group_st EC_GROUP; typedef struct ec_point_st EC_POINT; typedef struct ecpk_parameters_st ECPKPARAMETERS; @@ -61,33 +63,33 @@ typedef struct ec_parameters_st ECPARAMETERS; * optimized methods. * \return EC_METHOD object */ -const EC_METHOD *EC_GFp_simple_method(void); +DEPRECATEDIN_3_0(const EC_METHOD *EC_GFp_simple_method(void)) /** Returns GFp methods using montgomery multiplication. * \return EC_METHOD object */ -const EC_METHOD *EC_GFp_mont_method(void); +DEPRECATEDIN_3_0(const EC_METHOD *EC_GFp_mont_method(void)) /** Returns GFp methods using optimized methods for NIST recommended curves * \return EC_METHOD object */ -const EC_METHOD *EC_GFp_nist_method(void); +DEPRECATEDIN_3_0(const EC_METHOD *EC_GFp_nist_method(void)) # ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 /** Returns 64-bit optimized methods for nistp224 * \return EC_METHOD object */ -const EC_METHOD *EC_GFp_nistp224_method(void); +DEPRECATEDIN_3_0(const EC_METHOD *EC_GFp_nistp224_method(void)) /** Returns 64-bit optimized methods for nistp256 * \return EC_METHOD object */ -const EC_METHOD *EC_GFp_nistp256_method(void); +DEPRECATEDIN_3_0(const EC_METHOD *EC_GFp_nistp256_method(void)) /** Returns 64-bit optimized methods for nistp521 * \return EC_METHOD object */ -const EC_METHOD *EC_GFp_nistp521_method(void); +DEPRECATEDIN_3_0(const EC_METHOD *EC_GFp_nistp521_method(void)) # endif # ifndef OPENSSL_NO_EC2M @@ -98,7 +100,7 @@ const EC_METHOD *EC_GFp_nistp521_method(void); /** Returns the basic GF2m ec method * \return EC_METHOD object */ -const EC_METHOD *EC_GF2m_simple_method(void); +DEPRECATEDIN_3_0(const EC_METHOD *EC_GF2m_simple_method(void)) # endif @@ -108,20 +110,10 @@ const EC_METHOD *EC_GF2m_simple_method(void); /** * Creates a new EC_GROUP object - * \param libctx The associated library context or NULL for the default - * library context * \param meth EC_METHOD to use * \return newly created EC_GROUP object or NULL in case of an error. */ -EC_GROUP *EC_GROUP_new_ex(OPENSSL_CTX *libctx, const EC_METHOD *meth); - -/** - * Creates a new EC_GROUP object. Same as EC_GROUP_new_ex with NULL for the - * library context. - * \param meth EC_METHOD to use - * \return newly created EC_GROUP object or NULL in case of an error. - */ -EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); +DEPRECATEDIN_3_0(EC_GROUP *EC_GROUP_new(const EC_METHOD *meth)) /** Frees a EC_GROUP object * \param group EC_GROUP object to be freed. @@ -151,13 +143,13 @@ EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); * \param group EC_GROUP object * \return EC_METHOD used in this EC_GROUP object. */ -const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); +DEPRECATEDIN_3_0(const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group)) /** Returns the field type of the EC_METHOD. * \param meth EC_METHOD object * \return NID of the underlying field type OID. */ -int EC_METHOD_get_field_type(const EC_METHOD *meth); +DEPRECATEDIN_3_0(int EC_METHOD_get_field_type(const EC_METHOD *meth)) /** Sets the generator and its order/cofactor of a EC_GROUP object. * \param group EC_GROUP object @@ -235,6 +227,12 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group); */ const BIGNUM *EC_GROUP_get0_field(const EC_GROUP *group); +/** Returns the field type of the EC_GROUP. + * \param group EC_GROUP object + * \return NID of the underlying field type OID. + */ +int EC_GROUP_get_field_type(const EC_GROUP *group); + void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); int EC_GROUP_get_asn1_flag(const EC_GROUP *group); @@ -493,7 +491,7 @@ EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); * \param point EC_POINT object * \return the EC_METHOD used */ -const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); +DEPRECATEDIN_3_0(const EC_METHOD *EC_POINT_method_of(const EC_POINT *point)) /** Sets a point to infinity (neutral element) * \param group underlying EC_GROUP object @@ -761,9 +759,10 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); -int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); -int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, - EC_POINT *points[], BN_CTX *ctx); +DEPRECATEDIN_3_0(int EC_POINT_make_affine(const EC_GROUP *group, + EC_POINT *point, BN_CTX *ctx)) +DEPRECATEDIN_3_0(int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx)) /** Computes r = generator * n + sum_{i=0}^{num-1} p[i] * m[i] * \param group underlying EC_GROUP object @@ -797,13 +796,13 @@ int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, * \param ctx BN_CTX object (optional) * \return 1 on success and 0 if an error occurred */ -int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +DEPRECATEDIN_3_0(int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx)) /** Reports whether a precomputation has been done * \param group EC_GROUP object * \return 1 if a pre-computation has been done and 0 otherwise */ -int EC_GROUP_have_precompute_mult(const EC_GROUP *group); +DEPRECATEDIN_3_0(int EC_GROUP_have_precompute_mult(const EC_GROUP *group)) /********************************************************************/ /* ASN1 stuff */ @@ -991,7 +990,7 @@ void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); * \param ctx BN_CTX object (optional) * \return 1 on success and 0 if an error occurred. */ -int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); +DEPRECATEDIN_3_0(int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx)) /** Creates a new ec private (and optional a new public) key. * \param key EC_KEY object diff --git a/include/openssl/err.h b/include/openssl/err.h index aa8ffa97..9edaf1bb 100644 --- a/include/openssl/err.h +++ b/include/openssl/err.h @@ -113,7 +113,6 @@ struct err_state_st { # define ERR_LIB_PROV 57 # define ERR_LIB_CMP 58 # define ERR_LIB_OSSL_SERIALIZER 59 -# define ERR_LIB_HTTP 60 # define ERR_LIB_USER 128 @@ -141,7 +140,6 @@ struct err_state_st { # define EVPerr(f, r) ERR_raise_data(ERR_LIB_EVP, (r), NULL) # define FIPSerr(f, r) ERR_raise_data(ERR_LIB_FIPS, (r), NULL) # define HMACerr(f, r) ERR_raise_data(ERR_LIB_HMAC, (r), NULL) -# define HTTPerr(f, r) ERR_raise_data(ERR_LIB_HTTP, (r), NULL) # define KDFerr(f, r) ERR_raise_data(ERR_LIB_KDF, (r), NULL) # define OBJerr(f, r) ERR_raise_data(ERR_LIB_OBJ, (r), NULL) # define OCSPerr(f, r) ERR_raise_data(ERR_LIB_OCSP, (r), NULL) diff --git a/include/openssl/esserr.h b/include/openssl/esserr.h index 8befce5c..ff3c3d3d 100644 --- a/include/openssl/esserr.h +++ b/include/openssl/esserr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,6 +10,7 @@ #ifndef OPENSSL_ESSERR_H # define OPENSSL_ESSERR_H +# pragma once # include # include diff --git a/include/openssl/evp.h b/include/openssl/evp.h index c4ab7f0f..3f726a93 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -26,6 +26,8 @@ # include # include +# include + # define EVP_MAX_MD_SIZE 64/* longest known is SHA512 */ # define EVP_MAX_KEY_LENGTH 64 # define EVP_MAX_IV_LENGTH 16 @@ -72,6 +74,8 @@ # define EVP_PKEY_ED25519 NID_ED25519 # define EVP_PKEY_X448 NID_X448 # define EVP_PKEY_ED448 NID_ED448 +/* Special indicator that the object is uniquely provider side */ +# define EVP_PKEY_KEYMGMT -1 #ifdef __cplusplus extern "C" { @@ -153,6 +157,7 @@ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd, # define EVP_MD_CTRL_DIGALGID 0x1 # define EVP_MD_CTRL_MICALG 0x2 # define EVP_MD_CTRL_XOF_LEN 0x3 +# define EVP_MD_CTRL_TLSTREE 0x4 /* Minimum Algorithm specific ctrl value */ @@ -382,6 +387,8 @@ int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, # define EVP_CTRL_PROCESS_UNPROTECTED 0x28 /* Get the supplementary wrap cipher */ #define EVP_CTRL_GET_WRAP_CIPHER 0x29 +/* TLSTREE key diversification */ +#define EVP_CTRL_TLSTREE 0x2A /* Padding modes */ #define EVP_PADDING_PKCS7 1 @@ -1065,40 +1072,6 @@ void EVP_MD_do_all_provided(OPENSSL_CTX *libctx, void (*fn)(EVP_MD *md, void *arg), void *arg); -/* MAC stuff */ - -EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm, - const char *properties); -int EVP_MAC_up_ref(EVP_MAC *mac); -void EVP_MAC_free(EVP_MAC *mac); -int EVP_MAC_number(const EVP_MAC *mac); -int EVP_MAC_is_a(const EVP_MAC *mac, const char *name); -const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac); -int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]); - -EVP_MAC_CTX *EVP_MAC_CTX_new(EVP_MAC *mac); -void EVP_MAC_CTX_free(EVP_MAC_CTX *ctx); -EVP_MAC_CTX *EVP_MAC_CTX_dup(const EVP_MAC_CTX *src); -EVP_MAC *EVP_MAC_CTX_mac(EVP_MAC_CTX *ctx); -int EVP_MAC_CTX_get_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]); -int EVP_MAC_CTX_set_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]); - -size_t EVP_MAC_size(EVP_MAC_CTX *ctx); -int EVP_MAC_init(EVP_MAC_CTX *ctx); -int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen); -int EVP_MAC_final(EVP_MAC_CTX *ctx, - unsigned char *out, size_t *outl, size_t outsize); -const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac); -const OSSL_PARAM *EVP_MAC_gettable_ctx_params(const EVP_MAC *mac); -const OSSL_PARAM *EVP_MAC_settable_ctx_params(const EVP_MAC *mac); - -void EVP_MAC_do_all_provided(OPENSSL_CTX *libctx, - void (*fn)(EVP_MAC *mac, void *arg), - void *arg); -void EVP_MAC_names_do_all(const EVP_MAC *mac, - void (*fn)(const char *name, void *data), - void *data); - /* PKEY stuff */ DEPRECATEDIN_3_0(int EVP_PKEY_decrypt_old(unsigned char *dec_key, const unsigned char *enc_key, @@ -1187,9 +1160,15 @@ EVP_PKEY *d2i_KeyParams_bio(int type, EVP_PKEY **a, BIO *in); int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode); +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); +#endif +int EVP_PKEY_parameters_eq(const EVP_PKEY *a, const EVP_PKEY *b); +#ifndef OPENSSL_NO_DEPRECATED_3_0 int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); +#endif +int EVP_PKEY_eq(const EVP_PKEY *a, const EVP_PKEY *b); int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); @@ -1302,7 +1281,7 @@ void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth); void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, int (*pub_decode) (EVP_PKEY *pk, - X509_PUBKEY *pub), + const X509_PUBKEY *pub), int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk), int (*pub_cmp) (const EVP_PKEY *a, @@ -1463,6 +1442,10 @@ int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); */ # define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4 +/* Used by Chromium/QUIC */ +# define X25519_PRIVATE_KEY_LEN 32 +# define X25519_PUBLIC_VALUE_LEN 32 + const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, diff --git a/include/openssl/fips_names.h b/include/openssl/fips_names.h index aeb9670d..493ddb04 100644 --- a/include/openssl/fips_names.h +++ b/include/openssl/fips_names.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,7 +22,7 @@ extern "C" { * The calculated MAC of the module file (Used for FIPS Self Testing) * Type: OSSL_PARAM_UTF8_STRING */ -# define OSSL_PROV_FIPS_PARAM_MODULE_MAC "module-checksum" +# define OSSL_PROV_FIPS_PARAM_MODULE_MAC "module-mac" /* * A version number for the fips install process (Used for FIPS Self Testing) * Type: OSSL_PARAM_UTF8_STRING @@ -32,7 +32,7 @@ extern "C" { * The calculated MAC of the install status indicator (Used for FIPS Self Testing) * Type: OSSL_PARAM_UTF8_STRING */ -# define OSSL_PROV_FIPS_PARAM_INSTALL_MAC "install-checksum" +# define OSSL_PROV_FIPS_PARAM_INSTALL_MAC "install-mac" /* * The install status indicator (Used for FIPS Self Testing) * Type: OSSL_PARAM_UTF8_STRING diff --git a/include/openssl/http.h b/include/openssl/http.h deleted file mode 100644 index 45c8f11d..00000000 --- a/include/openssl/http.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. - * Copyright Siemens AG 2018-2020 - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_HTTP_H -# define OPENSSL_HTTP_H -# pragma once - -# include - -# include -# include -# include - - -# ifdef __cplusplus -extern "C" { -# endif - -typedef BIO *(*OSSL_HTTP_bio_cb_t)(BIO *bio, void *arg, int connect, int detail); - -# define OSSL_HTTP_NAME "http" -# define OSSL_HTTPS_NAME "https" -# define OSSL_HTTP_PREFIX OSSL_HTTP_NAME"://" -# define OSSL_HTTPS_PREFIX OSSL_HTTPS_NAME"://" -# define OSSL_HTTP_PORT "80" -# define OSSL_HTTPS_PORT "443" -# define OPENSSL_NO_PROXY "NO_PROXY" -# define OPENSSL_HTTP_PROXY "HTTP_PROXY" -# define OPENSSL_HTTPS_PROXY "HTTPS_PROXY" - -BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, - BIO *bio, BIO *rbio, - OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, - const STACK_OF(CONF_VALUE) *headers, - int maxline, unsigned long max_resp_len, int timeout, - const char *expected_content_type, int expect_asn1); -ASN1_VALUE *OSSL_HTTP_get_asn1(const char *url, - const char *proxy, const char *no_proxy, - BIO *bio, BIO *rbio, - OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, - const STACK_OF(CONF_VALUE) *headers, - int maxline, unsigned long max_resp_len, - int timeout, const char *expected_content_type, - const ASN1_ITEM *it); -ASN1_VALUE *OSSL_HTTP_post_asn1(const char *server, const char *port, - const char *path, int use_ssl, - const char *proxy, const char *no_proxy, - BIO *bio, BIO *rbio, - OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, - const STACK_OF(CONF_VALUE) *headers, - const char *content_type, - const ASN1_VALUE *req, const ASN1_ITEM *req_it, - int maxline, unsigned long max_resp_len, - int timeout, const char *expected_ct, - const ASN1_ITEM *rsp_it); -BIO *OSSL_HTTP_transfer(const char *server, const char *port, const char *path, - int use_ssl, const char *proxy, const char *no_proxy, - BIO *bio, BIO *rbio, - OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, - const STACK_OF(CONF_VALUE) *headers, - const char *content_type, BIO *req_mem, - int maxline, unsigned long max_resp_len, int timeout, - const char *expected_ct, int expect_asn1, - char **redirection_url); -int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port, - const char *proxyuser, const char *proxypass, - int timeout, BIO *bio_err, const char *prog); - -int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport, - char **ppath, int *pssl); - -# ifdef __cplusplus -} -# endif -#endif /* !defined(OPENSSL_HTTP_H) */ diff --git a/include/openssl/httperr.h b/include/openssl/httperr.h deleted file mode 100644 index e4acb1df..00000000 --- a/include/openssl/httperr.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_HTTPERR_H -# define OPENSSL_HTTPERR_H - -# include -# include - - -# ifdef __cplusplus -extern "C" -# endif -int ERR_load_HTTP_strings(void); - -/* - * HTTP function codes. - */ -# ifndef OPENSSL_NO_DEPRECATED_3_0 -# endif - -/* - * HTTP reason codes. - */ -# define HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN 108 -# define HTTP_R_CONNECT_FAILURE 100 -# define HTTP_R_ERROR_PARSING_ASN1_LENGTH 109 -# define HTTP_R_ERROR_PARSING_CONTENT_LENGTH 119 -# define HTTP_R_ERROR_PARSING_URL 101 -# define HTTP_R_ERROR_RECEIVING 103 -# define HTTP_R_ERROR_SENDING 102 -# define HTTP_R_INCONSISTENT_CONTENT_LENGTH 120 -# define HTTP_R_MAX_RESP_LEN_EXCEEDED 117 -# define HTTP_R_MISSING_ASN1_ENCODING 110 -# define HTTP_R_MISSING_CONTENT_TYPE 121 -# define HTTP_R_MISSING_REDIRECT_LOCATION 111 -# define HTTP_R_RECEIVED_ERROR 105 -# define HTTP_R_RECEIVED_WRONG_HTTP_VERSION 106 -# define HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP 112 -# define HTTP_R_REDIRECTION_NOT_ENABLED 116 -# define HTTP_R_RESPONSE_LINE_TOO_LONG 113 -# define HTTP_R_RESPONSE_PARSE_ERROR 104 -# define HTTP_R_SOCK_NOT_SUPPORTED 122 -# define HTTP_R_STATUS_CODE_UNSUPPORTED 114 -# define HTTP_R_TLS_NOT_ENABLED 107 -# define HTTP_R_TOO_MANY_REDIRECTIONS 115 -# define HTTP_R_UNEXPECTED_CONTENT_TYPE 118 - -#endif diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h index d8f81c9c..228214cd 100644 --- a/include/openssl/kdf.h +++ b/include/openssl/kdf.h @@ -30,20 +30,20 @@ void EVP_KDF_free(EVP_KDF *kdf); EVP_KDF *EVP_KDF_fetch(OPENSSL_CTX *libctx, const char *algorithm, const char *properties); -EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf); -void EVP_KDF_CTX_free(EVP_KDF_CTX *ctx); -EVP_KDF_CTX *EVP_KDF_CTX_dup(const EVP_KDF_CTX *src); +EVP_KDF_CTX *EVP_KDF_new_ctx(EVP_KDF *kdf); +void EVP_KDF_free_ctx(EVP_KDF_CTX *ctx); +EVP_KDF_CTX *EVP_KDF_dup_ctx(const EVP_KDF_CTX *src); int EVP_KDF_number(const EVP_KDF *kdf); int EVP_KDF_is_a(const EVP_KDF *kdf, const char *name); const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf); -const EVP_KDF *EVP_KDF_CTX_kdf(EVP_KDF_CTX *ctx); +const EVP_KDF *EVP_KDF_get_ctx_kdf(EVP_KDF_CTX *ctx); void EVP_KDF_reset(EVP_KDF_CTX *ctx); size_t EVP_KDF_size(EVP_KDF_CTX *ctx); int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen); int EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[]); -int EVP_KDF_CTX_get_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]); -int EVP_KDF_CTX_set_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]); +int EVP_KDF_get_ctx_params(EVP_KDF_CTX *ctx, OSSL_PARAM params[]); +int EVP_KDF_set_ctx_params(EVP_KDF_CTX *ctx, const OSSL_PARAM params[]); const OSSL_PARAM *EVP_KDF_gettable_params(const EVP_KDF *kdf); const OSSL_PARAM *EVP_KDF_gettable_ctx_params(const EVP_KDF *kdf); const OSSL_PARAM *EVP_KDF_settable_ctx_params(const EVP_KDF *kdf); diff --git a/include/openssl/lhash.h b/include/openssl/lhash.h index d3f064a8..5ad9b16a 100644 --- a/include/openssl/lhash.h +++ b/include/openssl/lhash.h @@ -230,6 +230,7 @@ DEFINE_LHASH_OF(OPENSSL_CSTRING); */ # ifdef __SUNPRO_C # pragma weak OPENSSL_LH_new +# pragma weak OPENSSL_LH_flush # pragma weak OPENSSL_LH_free # pragma weak OPENSSL_LH_insert # pragma weak OPENSSL_LH_delete diff --git a/include/openssl/mac.h b/include/openssl/mac.h new file mode 100644 index 00000000..ecfb2eca --- /dev/null +++ b/include/openssl/mac.h @@ -0,0 +1,59 @@ +/* + * Copyright 2019=-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* MAC stuff */ + +#ifndef OPENSSL_EVP_MAC_H +# define OPENSSL_EVP_MAC_H +# pragma once + +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +EVP_MAC *EVP_MAC_fetch(OPENSSL_CTX *libctx, const char *algorithm, + const char *properties); +int EVP_MAC_up_ref(EVP_MAC *mac); +void EVP_MAC_free(EVP_MAC *mac); +int EVP_MAC_number(const EVP_MAC *mac); +int EVP_MAC_is_a(const EVP_MAC *mac, const char *name); +const OSSL_PROVIDER *EVP_MAC_provider(const EVP_MAC *mac); +int EVP_MAC_get_params(EVP_MAC *mac, OSSL_PARAM params[]); + +EVP_MAC_CTX *EVP_MAC_new_ctx(EVP_MAC *mac); +void EVP_MAC_free_ctx(EVP_MAC_CTX *ctx); +EVP_MAC_CTX *EVP_MAC_dup_ctx(const EVP_MAC_CTX *src); +EVP_MAC *EVP_MAC_get_ctx_mac(EVP_MAC_CTX *ctx); +int EVP_MAC_get_ctx_params(EVP_MAC_CTX *ctx, OSSL_PARAM params[]); +int EVP_MAC_set_ctx_params(EVP_MAC_CTX *ctx, const OSSL_PARAM params[]); + +size_t EVP_MAC_size(EVP_MAC_CTX *ctx); +int EVP_MAC_init(EVP_MAC_CTX *ctx); +int EVP_MAC_update(EVP_MAC_CTX *ctx, const unsigned char *data, size_t datalen); +int EVP_MAC_final(EVP_MAC_CTX *ctx, + unsigned char *out, size_t *outl, size_t outsize); +const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac); +const OSSL_PARAM *EVP_MAC_gettable_ctx_params(const EVP_MAC *mac); +const OSSL_PARAM *EVP_MAC_settable_ctx_params(const EVP_MAC *mac); + +void EVP_MAC_do_all_provided(OPENSSL_CTX *libctx, + void (*fn)(EVP_MAC *mac, void *arg), + void *arg); +void EVP_MAC_names_do_all(const EVP_MAC *mac, + void (*fn)(const char *name, void *data), + void *data); + +# ifdef __cplusplus +} +# endif +#endif /* OPENSSL_EVP_MAC_H */ diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h index 27ea08d8..0af5a27c 100644 --- a/include/openssl/obj_mac.h +++ b/include/openssl/obj_mac.h @@ -4859,7 +4859,7 @@ #define SN_chacha20_poly1305_draft "ChaCha20-Poly1305-D" #define LN_chacha20_poly1305_draft "chacha20-poly1305-draft" -#define NID_chacha20_poly1305_draft 1218 +#define NID_chacha20_poly1305_draft 1219 #define SN_chacha20 "ChaCha20" #define LN_chacha20 "chacha20" @@ -5106,6 +5106,10 @@ #define LN_kx_gost "kx-gost" #define NID_kx_gost 1045 +#define SN_kx_gost18 "KxGOST18" +#define LN_kx_gost18 "kx-gost18" +#define NID_kx_gost18 1218 + #define SN_kx_any "KxANY" #define LN_kx_any "kx-any" #define NID_kx_any 1063 diff --git a/include/openssl/ocsp.h b/include/openssl/ocsp.h index d5ccff0e..70199dc6 100644 --- a/include/openssl/ocsp.h +++ b/include/openssl/ocsp.h @@ -1,5 +1,5 @@ /* - * Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -16,7 +16,7 @@ # define HEADER_OCSP_H # endif -# include +#include /* * These definitions are outside the OPENSSL_NO_OCSP guard because although for @@ -37,53 +37,30 @@ * privilegeWithdrawn (9), * aACompromise (10) } */ -# define OCSP_REVOKED_STATUS_NOSTATUS -1 -# define OCSP_REVOKED_STATUS_UNSPECIFIED 0 -# define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 -# define OCSP_REVOKED_STATUS_CACOMPROMISE 2 -# define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 -# define OCSP_REVOKED_STATUS_SUPERSEDED 4 -# define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 -# define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 -# define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 -# define OCSP_REVOKED_STATUS_PRIVILEGEWITHDRAWN 9 -# define OCSP_REVOKED_STATUS_AACOMPROMISE 10 - -/* - * These definitions are outside the OPENSSL_NO_OCSP guard because although for - * historical reasons they have OCSP_* names, they are used for the HTTP client. - */ -# include -/* The following functions are used only internally */ -OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *wbio, BIO *rbio, - int method_GET, int maxline, - unsigned long max_resp_len, int timeout, - const char *expected_content_type, - int expect_asn1); -void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); -int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, - const char *server, const char *port, const char *path); -int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, - const char *name, const char *value); -int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const char *content_type, - const ASN1_ITEM *it, ASN1_VALUE *req); -int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx); -ASN1_VALUE *OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it); -BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx); -void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len); -/* End of functions used only internally */ +# define OCSP_REVOKED_STATUS_NOSTATUS -1 +# define OCSP_REVOKED_STATUS_UNSPECIFIED 0 +# define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 +# define OCSP_REVOKED_STATUS_CACOMPROMISE 2 +# define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 +# define OCSP_REVOKED_STATUS_SUPERSEDED 4 +# define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 +# define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 +# define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 +# define OCSP_REVOKED_STATUS_PRIVILEGEWITHDRAWN 9 +# define OCSP_REVOKED_STATUS_AACOMPROMISE 10 # ifndef OPENSSL_NO_OCSP +# include # include # include # include # include -# ifdef __cplusplus +#ifdef __cplusplus extern "C" { -# endif +#endif /* Various flags and values */ @@ -182,10 +159,20 @@ DECLARE_ASN1_DUP_FUNCTION(OCSP_CERTID) OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req); OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, int maxline); +int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx); int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); - -/* TODO: remove this (documented but) meanwhile obsolete function? */ -int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, const OCSP_REQUEST *req); +OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline); +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); +void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len); +int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, + ASN1_VALUE *val); +int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, ASN1_VALUE **pval, + const ASN1_ITEM *it); +BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx); +int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path); +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value); OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, const X509 *subject, const X509 *issuer); @@ -247,7 +234,8 @@ int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags); -# define OCSP_parse_url OSSL_HTTP_parse_url /* for backward compatibility */ +int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, + int *pssl); int OCSP_id_issuer_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); int OCSP_id_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b); diff --git a/include/openssl/ocsperr.h b/include/openssl/ocsperr.h index f9ad3be0..99418567 100644 --- a/include/openssl/ocsperr.h +++ b/include/openssl/ocsperr.h @@ -40,9 +40,11 @@ int ERR_load_OCSP_strings(void); # define OCSP_F_OCSP_CHECK_ISSUER 0 # define OCSP_F_OCSP_CHECK_VALIDITY 0 # define OCSP_F_OCSP_MATCH_ISSUERID 0 +# define OCSP_F_OCSP_PARSE_URL 0 # define OCSP_F_OCSP_REQUEST_SIGN 0 # define OCSP_F_OCSP_REQUEST_VERIFY 0 # define OCSP_F_OCSP_RESPONSE_GET1_BASIC 0 +# define OCSP_F_PARSE_HTTP_LINE1 0 # endif /* @@ -52,6 +54,7 @@ int ERR_load_OCSP_strings(void); # define OCSP_R_DIGEST_ERR 102 # define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 # define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 +# define OCSP_R_ERROR_PARSING_URL 121 # define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 # define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 # define OCSP_R_NOT_BASIC_RESPONSE 104 @@ -63,6 +66,8 @@ int ERR_load_OCSP_strings(void); # define OCSP_R_REQUEST_NOT_SIGNED 128 # define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111 # define OCSP_R_ROOT_CA_NOT_TRUSTED 112 +# define OCSP_R_SERVER_RESPONSE_ERROR 114 +# define OCSP_R_SERVER_RESPONSE_PARSE_ERROR 115 # define OCSP_R_SIGNATURE_FAILURE 117 # define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 # define OCSP_R_STATUS_EXPIRED 125 diff --git a/include/openssl/provider.h b/include/openssl/provider.h index f297ea24..e9a14086 100644 --- a/include/openssl/provider.h +++ b/include/openssl/provider.h @@ -23,10 +23,18 @@ int OSSL_PROVIDER_set_default_search_path(OPENSSL_CTX *, const char *path); OSSL_PROVIDER *OSSL_PROVIDER_load(OPENSSL_CTX *, const char *name); int OSSL_PROVIDER_unload(OSSL_PROVIDER *prov); int OSSL_PROVIDER_available(OPENSSL_CTX *, const char *name); +int OSSL_PROVIDER_do_all(OPENSSL_CTX *ctx, + int (*cb)(OSSL_PROVIDER *provider, void *cbdata), + void *cbdata); const OSSL_PARAM *OSSL_PROVIDER_gettable_params(const OSSL_PROVIDER *prov); int OSSL_PROVIDER_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]); +const OSSL_ALGORITHM *OSSL_PROVIDER_query_operation(const OSSL_PROVIDER *prov, + int operation_id, + int *no_cache); +void *OSSL_PROVIDER_get0_provider_ctx(const OSSL_PROVIDER *prov); + /* Add a built in providers */ int OSSL_PROVIDER_add_builtin(OPENSSL_CTX *, const char *name, OSSL_provider_init_fn *init_fn); diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h index 45040e68..e1be1de1 100644 --- a/include/openssl/rsa.h +++ b/include/openssl/rsa.h @@ -39,7 +39,7 @@ extern "C" { # define OPENSSL_RSA_MAX_MODULUS_BITS 16384 # endif -# define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024 +# define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 2048 # ifndef OPENSSL_RSA_SMALL_MODULUS_BITS # define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 3572f74d..5e182726 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -87,6 +87,7 @@ extern "C" { # define SSL_TXT_kECDHEPSK "kECDHEPSK" # define SSL_TXT_kDHEPSK "kDHEPSK" # define SSL_TXT_kGOST "kGOST" +# define SSL_TXT_kGOST18 "kGOST18" # define SSL_TXT_kSRP "kSRP" # define SSL_TXT_aRSA "aRSA" @@ -138,6 +139,7 @@ extern "C" { # define SSL_TXT_ARIA128 "ARIA128" # define SSL_TXT_ARIA256 "ARIA256" # define SSL_TXT_GOST2012_GOST8912_GOST8912 "GOST2012-GOST8912-GOST8912" +# define SSL_TXT_CBC "CBC" # define SSL_TXT_MD5 "MD5" # define SSL_TXT_SHA1 "SHA1" @@ -325,14 +327,9 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); /* Allow initial connection to servers that don't support RI */ # define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004U -/* Reserved value (until OpenSSL 3.0.0) 0x00000008U */ # define SSL_OP_TLSEXT_PADDING 0x00000010U -/* Reserved value (until OpenSSL 3.0.0) 0x00000020U */ # define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040U -/* - * Reserved value (until OpenSSL 3.0.0) 0x00000080U - * Reserved value (until OpenSSL 3.0.0) 0x00000100U - */ +# define SSL_OP_IGNORE_UNEXPECTED_EOF 0x00000080U # define SSL_OP_DISABLE_TLSEXT_CA_NAMES 0x00000200U @@ -934,6 +931,8 @@ __owur int SSL_extension_supported(unsigned int ext_type); # define SSL_MAC_FLAG_READ_MAC_STREAM 1 # define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 +# define SSL_MAC_FLAG_READ_MAC_TLSTREE 4 +# define SSL_MAC_FLAG_WRITE_MAC_TLSTREE 8 /* * A callback for logging out TLS key material. This callback should log out @@ -2029,9 +2028,9 @@ __owur int SSL_CTX_set_default_verify_store(SSL_CTX *ctx); __owur int SSL_CTX_load_verify_file(SSL_CTX *ctx, const char *CAfile); __owur int SSL_CTX_load_verify_dir(SSL_CTX *ctx, const char *CApath); __owur int SSL_CTX_load_verify_store(SSL_CTX *ctx, const char *CAstore); -DEPRECATEDIN_3_0(__owur int SSL_CTX_load_verify_locations(SSL_CTX *ctx, +__owur int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, - const char *CApath)) + const char *CApath); # define SSL_get0_session SSL_get_session/* just peek at pointer */ __owur SSL_SESSION *SSL_get_session(const SSL *ssl); __owur SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ @@ -2170,7 +2169,7 @@ void SSL_CTX_set_record_padding_callback_arg(SSL_CTX *ctx, void *arg); void *SSL_CTX_get_record_padding_callback_arg(const SSL_CTX *ctx); int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size); -void SSL_set_record_padding_callback(SSL *ssl, +int SSL_set_record_padding_callback(SSL *ssl, size_t (*cb) (SSL *ssl, int type, size_t len, void *arg)); void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg); @@ -2481,6 +2480,51 @@ void SSL_set_allow_early_data_cb(SSL *s, const char *OSSL_default_cipher_list(void); const char *OSSL_default_ciphersuites(void); +# ifndef OPENSSL_NO_QUIC +/* + * QUIC integration - The QUIC interface matches BoringSSL + * + * ssl_encryption_level_t represents a specific QUIC encryption level used to + * transmit handshake messages. BoringSSL has this as an 'enum'. + */ +typedef enum ssl_encryption_level_t { + ssl_encryption_initial = 0, + ssl_encryption_early_data, + ssl_encryption_handshake, + ssl_encryption_application +} OSSL_ENCRYPTION_LEVEL; + +struct ssl_quic_method_st { + int (*set_encryption_secrets)(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, + const uint8_t *read_secret, + const uint8_t *write_secret, size_t secret_len); + int (*add_handshake_data)(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, + const uint8_t *data, size_t len); + int (*flush_flight)(SSL *ssl); + int (*send_alert)(SSL *ssl, enum ssl_encryption_level_t level, uint8_t alert); +}; + +__owur int SSL_CTX_set_quic_method(SSL_CTX *ctx, const SSL_QUIC_METHOD *quic_method); +__owur int SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method); +__owur int SSL_set_quic_transport_params(SSL *ssl, + const uint8_t *params, + size_t params_len); +void SSL_get_peer_quic_transport_params(const SSL *ssl, + const uint8_t **out_params, + size_t *out_params_len); +__owur size_t SSL_quic_max_handshake_flight_len(const SSL *ssl, OSSL_ENCRYPTION_LEVEL level); +__owur OSSL_ENCRYPTION_LEVEL SSL_quic_read_level(const SSL *ssl); +__owur OSSL_ENCRYPTION_LEVEL SSL_quic_write_level(const SSL *ssl); +__owur int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, + const uint8_t *data, size_t len); +__owur int SSL_process_quic_post_handshake(SSL *ssl); + +__owur int SSL_is_quic(SSL *ssl); + +# endif + +int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *c); + # ifdef __cplusplus } # endif diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h index 664ad238..9fc6b3ab 100644 --- a/include/openssl/ssl3.h +++ b/include/openssl/ssl3.h @@ -297,6 +297,9 @@ extern "C" { # define TLS1_FLAGS_STATELESS 0x0800 +/* Set if extended master secret extension required on renegotiation */ +# define TLS1_FLAGS_REQUIRED_EXTMS 0x1000 + # define SSL3_MT_HELLO_REQUEST 0 # define SSL3_MT_CLIENT_HELLO 1 # define SSL3_MT_SERVER_HELLO 2 diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h index 038b3a1a..7eb58521 100644 --- a/include/openssl/sslerr.h +++ b/include/openssl/sslerr.h @@ -97,6 +97,9 @@ int ERR_load_SSL_strings(void); # define SSL_F_PITEM_NEW 0 # define SSL_F_PQUEUE_NEW 0 # define SSL_F_PROCESS_KEY_SHARE_EXT 0 +# define SSL_F_QUIC_CHANGE_CIPHER_STATE 0 +# define SSL_F_QUIC_GET_MESSAGE 0 +# define SSL_F_QUIC_SET_ENCRYPTION_SECRETS 0 # define SSL_F_READ_STATE_MACHINE 0 # define SSL_F_SET_CLIENT_CIPHERSUITE 0 # define SSL_F_SRP_GENERATE_CLIENT_MASTER_SECRET 0 @@ -107,7 +110,9 @@ int ERR_load_SSL_strings(void); # define SSL_F_SSL3_CTRL 0 # define SSL_F_SSL3_CTX_CTRL 0 # define SSL_F_SSL3_DIGEST_CACHED_RECORDS 0 +# define SSL_F_SSL3_DISPATCH_ALERT 0 # define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 0 +# define SSL_F_SSL3_DO_WRITE 0 # define SSL_F_SSL3_ENC 0 # define SSL_F_SSL3_FINAL_FINISH_MAC 0 # define SSL_F_SSL3_FINISH_MAC 0 @@ -212,6 +217,8 @@ int ERR_load_SSL_strings(void); # define SSL_F_SSL_PEEK 0 # define SSL_F_SSL_PEEK_EX 0 # define SSL_F_SSL_PEEK_INTERNAL 0 +# define SSL_F_SSL_PROCESS_QUIC_POST_HANDSHAKE 0 +# define SSL_F_SSL_PROVIDE_QUIC_DATA 0 # define SSL_F_SSL_READ 0 # define SSL_F_SSL_READ_EARLY_DATA 0 # define SSL_F_SSL_READ_EX 0 @@ -262,6 +269,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_SSL_WRITE_EARLY_FINISH 0 # define SSL_F_SSL_WRITE_EX 0 # define SSL_F_SSL_WRITE_INTERNAL 0 +# define SSL_F_STATEM_FLUSH 0 # define SSL_F_STATE_MACHINE 0 # define SSL_F_TLS12_CHECK_PEER_SIGALG 0 # define SSL_F_TLS12_COPY_SIGALGS 0 @@ -298,6 +306,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_TLS_CONSTRUCT_CKE_DHE 0 # define SSL_F_TLS_CONSTRUCT_CKE_ECDHE 0 # define SSL_F_TLS_CONSTRUCT_CKE_GOST 0 +# define SSL_F_TLS_CONSTRUCT_CKE_GOST18 0 # define SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE 0 # define SSL_F_TLS_CONSTRUCT_CKE_RSA 0 # define SSL_F_TLS_CONSTRUCT_CKE_SRP 0 @@ -321,6 +330,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_TLS_CONSTRUCT_CTOS_POST_HANDSHAKE_AUTH 0 # define SSL_F_TLS_CONSTRUCT_CTOS_PSK 0 # define SSL_F_TLS_CONSTRUCT_CTOS_PSK_KEX_MODES 0 +# define SSL_F_TLS_CONSTRUCT_CTOS_QUIC_TRANSPORT_PARAMS 0 # define SSL_F_TLS_CONSTRUCT_CTOS_RENEGOTIATE 0 # define SSL_F_TLS_CONSTRUCT_CTOS_SCT 0 # define SSL_F_TLS_CONSTRUCT_CTOS_SERVER_NAME 0 @@ -360,6 +370,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_TLS_CONSTRUCT_STOC_MAXFRAGMENTLEN 0 # define SSL_F_TLS_CONSTRUCT_STOC_NEXT_PROTO_NEG 0 # define SSL_F_TLS_CONSTRUCT_STOC_PSK 0 +# define SSL_F_TLS_CONSTRUCT_STOC_QUIC_TRANSPORT_PARAMS 0 # define SSL_F_TLS_CONSTRUCT_STOC_RENEGOTIATE 0 # define SSL_F_TLS_CONSTRUCT_STOC_SERVER_NAME 0 # define SSL_F_TLS_CONSTRUCT_STOC_SESSION_TICKET 0 @@ -385,6 +396,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_TLS_PARSE_CTOS_POST_HANDSHAKE_AUTH 0 # define SSL_F_TLS_PARSE_CTOS_PSK 0 # define SSL_F_TLS_PARSE_CTOS_PSK_KEX_MODES 0 +# define SSL_F_TLS_PARSE_CTOS_QUIC_TRANSPORT_PARAMS 0 # define SSL_F_TLS_PARSE_CTOS_RENEGOTIATE 0 # define SSL_F_TLS_PARSE_CTOS_SERVER_NAME 0 # define SSL_F_TLS_PARSE_CTOS_SESSION_TICKET 0 @@ -403,6 +415,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_TLS_PARSE_STOC_MAXFRAGMENTLEN 0 # define SSL_F_TLS_PARSE_STOC_NPN 0 # define SSL_F_TLS_PARSE_STOC_PSK 0 +# define SSL_F_TLS_PARSE_STOC_QUIC_TRANSPORT_PARAMS 0 # define SSL_F_TLS_PARSE_STOC_RENEGOTIATE 0 # define SSL_F_TLS_PARSE_STOC_SCT 0 # define SSL_F_TLS_PARSE_STOC_SERVER_NAME 0 @@ -422,6 +435,7 @@ int ERR_load_SSL_strings(void); # define SSL_F_TLS_PROCESS_CKE_DHE 0 # define SSL_F_TLS_PROCESS_CKE_ECDHE 0 # define SSL_F_TLS_PROCESS_CKE_GOST 0 +# define SSL_F_TLS_PROCESS_CKE_GOST18 0 # define SSL_F_TLS_PROCESS_CKE_PSK_PREAMBLE 0 # define SSL_F_TLS_PROCESS_CKE_RSA 0 # define SSL_F_TLS_PROCESS_CKE_SRP 0 @@ -569,6 +583,7 @@ int ERR_load_SSL_strings(void); # define SSL_R_INCONSISTENT_EARLY_DATA_SNI 231 # define SSL_R_INCONSISTENT_EXTMS 104 # define SSL_R_INSUFFICIENT_SECURITY 241 +# define SSL_R_INTERNAL_ERROR 296 # define SSL_R_INVALID_ALERT 205 # define SSL_R_INVALID_CCS_MESSAGE 260 # define SSL_R_INVALID_CERTIFICATE_OR_ALG 238 @@ -606,8 +621,8 @@ int ERR_load_SSL_strings(void); # define SSL_R_MISSING_TMP_DH_KEY 171 # define SSL_R_MISSING_TMP_ECDH_KEY 311 # define SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA 293 -# define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 296 -# define SSL_R_NESTED_GROUP 297 +# define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 297 +# define SSL_R_NESTED_GROUP 299 # define SSL_R_NOT_ON_RECORD_BOUNDARY 182 # define SSL_R_NOT_REPLACING_CERTIFICATE 289 # define SSL_R_NOT_SERVER 284 @@ -739,9 +754,9 @@ int ERR_load_SSL_strings(void); # define SSL_R_UNEXPECTED_CCS_MESSAGE 262 # define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178 # define SSL_R_UNEXPECTED_EOF_WHILE_READING 294 -# define SSL_R_UNEXPECTED_GROUP_CLOSE 299 +# define SSL_R_UNEXPECTED_GROUP_CLOSE 305 # define SSL_R_UNEXPECTED_MESSAGE 244 -# define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 305 +# define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 310 # define SSL_R_UNEXPECTED_RECORD 245 # define SSL_R_UNINITIALIZED 276 # define SSL_R_UNKNOWN_ALERT_TYPE 246 @@ -769,6 +784,7 @@ int ERR_load_SSL_strings(void); # define SSL_R_WRONG_CERTIFICATE_TYPE 383 # define SSL_R_WRONG_CIPHER_RETURNED 261 # define SSL_R_WRONG_CURVE 378 +# define SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED 313 # define SSL_R_WRONG_SIGNATURE_LENGTH 264 # define SSL_R_WRONG_SIGNATURE_SIZE 265 # define SSL_R_WRONG_SIGNATURE_TYPE 370 diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h index 52f47708..55ab0ad6 100644 --- a/include/openssl/tls1.h +++ b/include/openssl/tls1.h @@ -153,6 +153,9 @@ extern "C" { /* Temporary extension type */ # define TLSEXT_TYPE_renegotiate 0xff01 +/* ExtensionType value from draft-ietf-quic-tls-13 */ +# define TLSEXT_TYPE_quic_transport_parameters 0xffa5 + # ifndef OPENSSL_NO_NEXTPROTONEG /* This is not an IANA defined extension number */ # define TLSEXT_TYPE_next_proto_neg 13172 diff --git a/include/openssl/types.h b/include/openssl/types.h index 27f90a7b..6541bcd5 100644 --- a/include/openssl/types.h +++ b/include/openssl/types.h @@ -186,7 +186,7 @@ typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; typedef struct crypto_ex_data_st CRYPTO_EX_DATA; -typedef struct ossl_http_req_ctx_st OCSP_REQ_CTX; /* backward compatibility */ +typedef struct ocsp_req_ctx_st OCSP_REQ_CTX; typedef struct ocsp_response_st OCSP_RESPONSE; typedef struct ocsp_responder_id_st OCSP_RESPID; @@ -214,6 +214,8 @@ typedef struct ossl_serializer_ctx_st OSSL_SERIALIZER_CTX; typedef struct ossl_self_test_st OSSL_SELF_TEST; +typedef struct ssl_quic_method_st SSL_QUIC_METHOD; + #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \ defined(INTMAX_MAX) && defined(UINTMAX_MAX) typedef intmax_t ossl_intmax_t; diff --git a/include/openssl/x509.h b/include/openssl/x509.h index d709c53c..2d05a920 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -365,10 +365,16 @@ int X509_signature_print(BIO *bp, const X509_ALGOR *alg, int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); +# ifndef OPENSSL_NO_OCSP +int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert); +# endif int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); +# ifndef OPENSSL_NO_OCSP +int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl); +# endif int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); int X509_pubkey_digest(const X509 *data, const EVP_MD *type, @@ -383,13 +389,6 @@ int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, unsigned char *md, unsigned int *len); -# if !defined(OPENSSL_NO_SOCK) -X509 *X509_load_http(const char *url, BIO *bio, BIO *rbio, int timeout); -# define X509_http_nbio(url) X509_load_http(url, NULL, NULL, 0) -X509_CRL *X509_CRL_load_http(const char *url, BIO *bio, BIO *rbio, int timeout); -# define X509_CRL_http_nbio(url) X509_CRL_load_http(url, NULL, NULL, 0) -# endif - # ifndef OPENSSL_NO_STDIO X509 *d2i_X509_fp(FILE *fp, X509 **x509); int i2d_X509_fp(FILE *fp, const X509 *x509); @@ -519,8 +518,8 @@ DECLARE_ASN1_FUNCTIONS(X509_VAL) DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); -EVP_PKEY *X509_PUBKEY_get0(X509_PUBKEY *key); -EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); +EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key); +EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key); int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain); long X509_get_pathlen(X509 *x); DECLARE_ASN1_ENCODE_FUNCTIONS_only(EVP_PKEY, PUBKEY) @@ -1052,7 +1051,8 @@ int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, unsigned char *penc, int penclen); int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen, - X509_ALGOR **pa, X509_PUBKEY *pub); + X509_ALGOR **pa, const X509_PUBKEY *pub); +int X509_PUBKEY_eq(const X509_PUBKEY *a, const X509_PUBKEY *b); int X509_check_trust(X509 *x, int id, int flags); int X509_TRUST_get_count(void); diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h index 92aed083..fda13502 100644 --- a/include/openssl/x509_vfy.h +++ b/include/openssl/x509_vfy.h @@ -510,9 +510,9 @@ int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); int X509_STORE_load_file(X509_STORE *ctx, const char *file); int X509_STORE_load_path(X509_STORE *ctx, const char *path); int X509_STORE_load_store(X509_STORE *ctx, const char *store); -DEPRECATEDIN_3_0(int X509_STORE_load_locations(X509_STORE *ctx, +int X509_STORE_load_locations(X509_STORE *ctx, const char *file, - const char *dir)) + const char *dir); int X509_STORE_set_default_paths(X509_STORE *ctx); #define X509_STORE_CTX_get_ex_new_index(l, p, newf, dupf, freef) \ diff --git a/include/openssl/x509err.h b/include/openssl/x509err.h index 34cd706a..19743b59 100644 --- a/include/openssl/x509err.h +++ b/include/openssl/x509err.h @@ -28,6 +28,7 @@ int ERR_load_X509_strings(void); # define X509_F_ADD_CERT_DIR 0 # define X509_F_BUILD_CHAIN 0 # define X509_F_BY_FILE_CTRL 0 +# define X509_F_CACHE_OBJECTS 0 # define X509_F_CHECK_NAME_CONSTRAINTS 0 # define X509_F_CHECK_POLICY 0 # define X509_F_COMMON_VERIFY_SM2 0 @@ -68,6 +69,7 @@ int ERR_load_X509_strings(void); # define X509_F_X509_OBJECT_NEW 0 # define X509_F_X509_PRINT_EX_FP 0 # define X509_F_X509_PUBKEY_DECODE 0 +# define X509_F_X509_PUBKEY_GET 0 # define X509_F_X509_PUBKEY_GET0 0 # define X509_F_X509_PUBKEY_SET 0 # define X509_F_X509_REQ_CHECK_PRIVATE_KEY 0 @@ -101,8 +103,8 @@ int ERR_load_X509_strings(void); # define X509_R_BAD_X509_FILETYPE 100 # define X509_R_BASE64_DECODE_ERROR 118 # define X509_R_CANT_CHECK_DH_KEY 114 -# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 # define X509_R_CERTIFICATE_VERIFICATION_FAILED 139 +# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 # define X509_R_CRL_ALREADY_DELTA 127 # define X509_R_CRL_VERIFY_FAILURE 131 # define X509_R_IDP_MISMATCH 128 diff --git a/providers/common/bio_prov.c b/providers/common/bio_prov.c index 2bfd14b5..4ddfa0c4 100644 --- a/providers/common/bio_prov.c +++ b/providers/common/bio_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/common/der/DIGESTS.asn1 b/providers/common/der/DIGESTS.asn1 index afed3721..bd955df8 100644 --- a/providers/common/der/DIGESTS.asn1 +++ b/providers/common/der/DIGESTS.asn1 @@ -1,5 +1,22 @@ -- ------------------------------------------------------------------- --- Taken from https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration +-- From https://tools.ietf.org/html/rfc4055#section-2.1 + +id-sha1 OBJECT IDENTIFIER ::= { iso(1) + identified-organization(3) oiw(14) + secsig(3) algorithms(2) 26 } + +-- ------------------------------------------------------------------- +-- From https://tools.ietf.org/html/rfc5480#appendix-A +-- (OIDs for MD2 and MD5 are allowed only in EMSA-PKCS1-v1_5) + +id-md2 OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 } + +id-md5 OBJECT IDENTIFIER ::= { + iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 } + +-- ------------------------------------------------------------------- +-- From https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration id-sha256 OBJECT IDENTIFIER ::= { hashAlgs 1 } id-sha384 OBJECT IDENTIFIER ::= { hashAlgs 2 } diff --git a/providers/common/der/RSA.asn1 b/providers/common/der/RSA.asn1 index d0c54d71..6ba99daa 100644 --- a/providers/common/der/RSA.asn1 +++ b/providers/common/der/RSA.asn1 @@ -52,25 +52,6 @@ sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 } sha512-224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 15 } sha512-256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 16 } --- --- This OID really belongs in a module with the secsig OIDs. --- -id-sha1 OBJECT IDENTIFIER ::= { - iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) - 26 -} - --- --- OIDs for MD2 and MD5, allowed only in EMSA-PKCS1-v1_5. --- -id-md2 OBJECT IDENTIFIER ::= { - iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 2 -} - -id-md5 OBJECT IDENTIFIER ::= { - iso(1) member-body(2) us(840) rsadsi(113549) digestAlgorithm(2) 5 -} - -- -- When id-mgf1 is used in an AlgorithmIdentifier, the parameters -- MUST be present and MUST be a HashAlgorithm, for example, sha1. diff --git a/providers/common/der/build.info b/providers/common/der/build.info index 837fe73f..7bb1d0dc 100644 --- a/providers/common/der/build.info +++ b/providers/common/der/build.info @@ -1,32 +1,64 @@ -$FIPSABLE=der_rsa.c der_dsa.c der_ec.c der_digests.c +#----- Digests +$DER_DIGESTS_H=../include/prov/der_digests.h +$DER_DIGESTS_GEN=der_digests_gen.c -SOURCE[../../libfips.a]=$FIPSABLE -SOURCE[../../libnonfips.a]=$FIPSABLE +GENERATE[$DER_DIGESTS_GEN]=der_digests_gen.c.in +DEPEND[$DER_DIGESTS_GEN]=oids_to_c.pm -GENERATE[der_rsa.c]=der_rsa.c.in -DEPEND[der_rsa.c]=oids_to_c.pm +DEPEND[${DER_DIGESTS_GEN/.c/.o}]=$DER_DIGESTS_H +GENERATE[$DER_DIGESTS_H]=der_digests.h.in +DEPEND[$DER_DIGESTS_H]=oids_to_c.pm -DEPEND[der_rsa.o]=../include/prov/der_rsa.h ../include/prov/der_digests.h -GENERATE[../include/prov/der_rsa.h]=der_rsa.h.in -DEPEND[../include/prov/der_rsa.h]=oids_to_c.pm +#----- RSA +$DER_RSA_H=../include/prov/der_rsa.h +$DER_RSA_GEN=der_rsa_gen.c +$DER_RSA_AUX=der_rsa_key.c der_rsa_sig.c +$DER_RSA_COMMON=$DER_RSA_GEN der_rsa_sig.c +$DER_RSA_FIPSABLE=der_rsa_key.c -GENERATE[der_dsa.c]=der_dsa.c.in -DEPEND[der_dsa.c]=oids_to_c.pm +GENERATE[$DER_RSA_GEN]=der_rsa_gen.c.in +DEPEND[$DER_RSA_GEN]=oids_to_c.pm -DEPEND[der_dsa.o]=../include/prov/der_dsa.h -GENERATE[../include/prov/der_dsa.h]=der_dsa.h.in -DEPEND[../include/prov/der_dsa.h]=oids_to_c.pm +DEPEND[${DER_RSA_AUX/.c/.o}]=$DER_RSA_H $DER_DIGESTS_H +DEPEND[${DER_RSA_GEN/.c/.o}]=$DER_RSA_H +GENERATE[$DER_RSA_H]=der_rsa.h.in +DEPEND[$DER_RSA_H]=oids_to_c.pm -GENERATE[der_ec.c]=der_ec.c.in -DEPEND[der_ec.c]=oids_to_c.pm +#----- DSA +$DER_DSA_H=../include/prov/der_dsa.h +$DER_DSA_GEN=der_dsa_gen.c +$DER_DSA_AUX=der_dsa_key.c der_dsa_sig.c -DEPEND[der_ec.o]=../include/prov/der_ec.h -GENERATE[../include/prov/der_ec.h]=der_ec.h.in -DEPEND[../include/prov/der_ec.h]=oids_to_c.pm +GENERATE[$DER_DSA_GEN]=der_dsa_gen.c.in +DEPEND[$DER_DSA_GEN]=oids_to_c.pm -GENERATE[der_digests.c]=der_digests.c.in -DEPEND[der_digests.c]=oids_to_c.pm +DEPEND[${DER_DSA_AUX/.c/.o}]=$DER_DSA_H $DER_DIGESTS_H +DEPEND[${DER_DSA_GEN/.c/.o}]=$DER_DSA_H +GENERATE[$DER_DSA_H]=der_dsa.h.in +DEPEND[$DER_DSA_H]=oids_to_c.pm -DEPEND[der_digests.o]=../include/prov/der_digests.h -GENERATE[../include/prov/der_digests.h]=der_digests.h.in -DEPEND[../include/prov/der_digests.h]=oids_to_c.pm +#----- EC +$DER_EC_H=../include/prov/der_ec.h +$DER_EC_GEN=der_ec_gen.c +$DER_EC_AUX=der_ec_key.c der_ec_sig.c + +GENERATE[$DER_EC_GEN]=der_ec_gen.c.in +DEPEND[$DER_EC_GEN]=oids_to_c.pm + +DEPEND[${DER_EC_AUX/.c/.o}]=$DER_EC_H $DER_DIGESTS_H +DEPEND[${DER_EC_GEN/.c/.o}]=$DER_EC_H +GENERATE[$DER_EC_H]=der_ec.h.in +DEPEND[$DER_EC_H]=oids_to_c.pm + +#----- Conclusion + +# TODO(3.0) $COMMON should go to libcommon.a, but this currently leads +# to linking conflicts, so we add it to libfips.a and libnonfips.a for +# the moment being +$COMMON=\ + $DER_RSA_COMMON \ + $DER_DSA_GEN $DER_DSA_AUX \ + $DER_EC_GEN $DER_EC_AUX \ + $DER_DIGESTS_GEN +SOURCE[../../libfips.a]=$COMMON $DER_RSA_FIPSABLE +SOURCE[../../libnonfips.a]=$COMMON $DER_RSA_FIPSABLE diff --git a/providers/common/der/der_digests.c.in b/providers/common/der/der_digests_gen.c.in similarity index 100% rename from providers/common/der/der_digests.c.in rename to providers/common/der/der_digests_gen.c.in diff --git a/providers/common/der/der_dsa.h.in b/providers/common/der/der_dsa.h.in index d9e7bf20..e9a8718f 100644 --- a/providers/common/der/der_dsa.h.in +++ b/providers/common/der/der_dsa.h.in @@ -16,6 +16,8 @@ filter => \&oids_to_c::filter_to_H }); -} +/* Subject Public Key Info */ int DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa); -int DER_w_algorithmIdentifier_DSA_with(WPACKET *pkt, int tag, - DSA *dsa, int mdnid); +/* Signature */ +int DER_w_algorithmIdentifier_DSA_with_MD(WPACKET *pkt, int tag, + DSA *dsa, int mdnid); diff --git a/providers/common/der/der_dsa_gen.c.in b/providers/common/der/der_dsa_gen.c.in new file mode 100644 index 00000000..95f1f5cd --- /dev/null +++ b/providers/common/der/der_dsa_gen.c.in @@ -0,0 +1,17 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "prov/der_dsa.h" + +/* Well known OIDs precompiled */ +{- + $OUT = oids_to_c::process_leaves('providers/common/der/DSA.asn1', + { dir => $config{sourcedir}, + filter => \&oids_to_c::filter_to_C }); +-} diff --git a/providers/common/der/der_dsa_key.c b/providers/common/der/der_dsa_key.c new file mode 100644 index 00000000..6118b275 --- /dev/null +++ b/providers/common/der/der_dsa_key.c @@ -0,0 +1,20 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/packet.h" +#include "prov/der_dsa.h" + +int DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa) +{ + return DER_w_begin_sequence(pkt, tag) + /* No parameters (yet?) */ + && DER_w_precompiled(pkt, -1, der_oid_id_dsa, sizeof(der_oid_id_dsa)) + && DER_w_end_sequence(pkt, tag); +} diff --git a/providers/common/der/der_dsa.c.in b/providers/common/der/der_dsa_sig.c similarity index 65% rename from providers/common/der/der_dsa.c.in rename to providers/common/der/der_dsa_sig.c index 28c0ba8c..c96a617d 100644 --- a/providers/common/der/der_dsa.c.in +++ b/providers/common/der/der_dsa_sig.c @@ -7,33 +7,18 @@ * https://www.openssl.org/source/license.html */ -#include #include +#include "internal/packet.h" #include "prov/der_dsa.h" -/* Well known OIDs precompiled */ -{- - $OUT = oids_to_c::process_leaves('providers/common/der/DSA.asn1', - { dir => $config{sourcedir}, - filter => \&oids_to_c::filter_to_C }); --} - -int DER_w_algorithmIdentifier_DSA(WPACKET *pkt, int tag, DSA *dsa) -{ - return DER_w_begin_sequence(pkt, tag) - /* No parameters (yet?) */ - && DER_w_precompiled(pkt, -1, der_oid_id_dsa, sizeof(der_oid_id_dsa)) - && DER_w_end_sequence(pkt, tag); -} - #define MD_CASE(name) \ case NID_##name: \ precompiled = der_oid_id_dsa_with_##name; \ precompiled_sz = sizeof(der_oid_id_dsa_with_##name); \ break; -int DER_w_algorithmIdentifier_DSA_with(WPACKET *pkt, int tag, - DSA *dsa, int mdnid) +int DER_w_algorithmIdentifier_DSA_with_MD(WPACKET *pkt, int tag, + DSA *dsa, int mdnid) { const unsigned char *precompiled = NULL; size_t precompiled_sz = 0; diff --git a/providers/common/der/der_ec.h.in b/providers/common/der/der_ec.h.in index 24f153cd..86a754e4 100644 --- a/providers/common/der/der_ec.h.in +++ b/providers/common/der/der_ec.h.in @@ -16,6 +16,8 @@ filter => \&oids_to_c::filter_to_H }); -} +/* Subject Public Key Info */ int DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec); -int DER_w_algorithmIdentifier_ECDSA_with(WPACKET *pkt, int cont, - EC_KEY *ec, int mdnid); +/* Signature */ +int DER_w_algorithmIdentifier_ECDSA_with_MD(WPACKET *pkt, int cont, + EC_KEY *ec, int mdnid); diff --git a/providers/common/der/der_ec_gen.c.in b/providers/common/der/der_ec_gen.c.in new file mode 100644 index 00000000..40acf9a3 --- /dev/null +++ b/providers/common/der/der_ec_gen.c.in @@ -0,0 +1,17 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "prov/der_ec.h" + +/* Well known OIDs precompiled */ +{- + $OUT = oids_to_c::process_leaves('providers/common/der/EC.asn1', + { dir => $config{sourcedir}, + filter => \&oids_to_c::filter_to_C }); +-} diff --git a/providers/common/der/der_ec_key.c b/providers/common/der/der_ec_key.c new file mode 100644 index 00000000..058596a9 --- /dev/null +++ b/providers/common/der/der_ec_key.c @@ -0,0 +1,21 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/packet.h" +#include "prov/der_ec.h" + +int DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec) +{ + return DER_w_begin_sequence(pkt, cont) + /* No parameters (yet?) */ + && DER_w_precompiled(pkt, -1, der_oid_id_ecPublicKey, + sizeof(der_oid_id_ecPublicKey)) + && DER_w_end_sequence(pkt, cont); +} diff --git a/providers/common/der/der_ec.c.in b/providers/common/der/der_ec_sig.c similarity index 69% rename from providers/common/der/der_ec.c.in rename to providers/common/der/der_ec_sig.c index a617651e..687ec49c 100644 --- a/providers/common/der/der_ec.c.in +++ b/providers/common/der/der_ec_sig.c @@ -7,26 +7,10 @@ * https://www.openssl.org/source/license.html */ -#include #include +#include "internal/packet.h" #include "prov/der_ec.h" -/* Well known OIDs precompiled */ -{- - $OUT = oids_to_c::process_leaves('providers/common/der/EC.asn1', - { dir => $config{sourcedir}, - filter => \&oids_to_c::filter_to_C }); --} - -int DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec) -{ - return DER_w_begin_sequence(pkt, cont) - /* No parameters (yet?) */ - && DER_w_precompiled(pkt, -1, der_oid_id_ecPublicKey, - sizeof(der_oid_id_ecPublicKey)) - && DER_w_end_sequence(pkt, cont); -} - /* Aliases so we can have a uniform MD_CASE */ #define der_oid_id_ecdsa_with_sha1 der_oid_ecdsa_with_SHA1 #define der_oid_id_ecdsa_with_sha224 der_oid_ecdsa_with_SHA224 @@ -40,8 +24,8 @@ int DER_w_algorithmIdentifier_EC(WPACKET *pkt, int cont, EC_KEY *ec) precompiled_sz = sizeof(der_oid_id_ecdsa_with_##name); \ break; -int DER_w_algorithmIdentifier_ECDSA_with(WPACKET *pkt, int cont, - EC_KEY *ec, int mdnid) +int DER_w_algorithmIdentifier_ECDSA_with_MD(WPACKET *pkt, int cont, + EC_KEY *ec, int mdnid) { const unsigned char *precompiled = NULL; size_t precompiled_sz = 0; diff --git a/providers/common/der/der_rsa.h.in b/providers/common/der/der_rsa.h.in index 53f62278..c744fc25 100644 --- a/providers/common/der/der_rsa.h.in +++ b/providers/common/der/der_rsa.h.in @@ -13,14 +13,16 @@ /* Well known OIDs precompiled */ {- $OUT = oids_to_c::process_leaves('providers/common/der/NIST.asn1', - 'providers/common/der/DIGESTS.asn1', 'providers/common/der/RSA.asn1', { dir => $config{sourcedir}, filter => \&oids_to_c::filter_to_H }); -} +/* PSS parameters */ int DER_w_RSASSA_PSS_params(WPACKET *pkt, int tag, const RSA_PSS_PARAMS_30 *pss); +/* Subject Public Key Info */ int DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa); -int DER_w_algorithmIdentifier_RSA_with(WPACKET *pkt, int tag, - RSA *rsa, int mdnid); +/* Signature */ +int DER_w_algorithmIdentifier_MDWithRSAEncryption(WPACKET *pkt, int tag, + RSA *rsa, int mdnid); diff --git a/providers/common/der/der_rsa_gen.c.in b/providers/common/der/der_rsa_gen.c.in new file mode 100644 index 00000000..0d1ca0b1 --- /dev/null +++ b/providers/common/der/der_rsa_gen.c.in @@ -0,0 +1,18 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "prov/der_rsa.h" + +/* Well known OIDs precompiled */ +{- + $OUT = oids_to_c::process_leaves('providers/common/der/NIST.asn1', + 'providers/common/der/RSA.asn1', + { dir => $config{sourcedir}, + filter => \&oids_to_c::filter_to_C }); +-} diff --git a/providers/common/der/der_rsa.c.in b/providers/common/der/der_rsa_key.c similarity index 86% rename from providers/common/der/der_rsa.c.in rename to providers/common/der/der_rsa_key.c index 30e945cf..bd2de4a6 100644 --- a/providers/common/der/der_rsa.c.in +++ b/providers/common/der/der_rsa_key.c @@ -7,21 +7,11 @@ * https://www.openssl.org/source/license.html */ -#include #include #include "internal/cryptlib.h" #include "prov/der_rsa.h" #include "prov/der_digests.h" -/* Well known OIDs precompiled */ -{- - $OUT = oids_to_c::process_leaves('providers/common/der/NIST.asn1', - 'providers/common/der/DIGESTS.asn1', - 'providers/common/der/RSA.asn1', - { dir => $config{sourcedir}, - filter => \&oids_to_c::filter_to_C }); --} - /* More complex pre-compiled sequences. TODO(3.0) refactor? */ /*- * From https://tools.ietf.org/html/rfc8017#appendix-A.2.1 @@ -382,54 +372,3 @@ int DER_w_algorithmIdentifier_RSA(WPACKET *pkt, int tag, RSA *rsa) && DER_w_precompiled(pkt, -1, rsa_oid, rsa_oid_sz) && DER_w_end_sequence(pkt, tag); } - -/* Aliases so we can have a uniform MD_with_RSA_CASE */ -#define der_oid_sha3_224WithRSAEncryption \ - der_oid_id_rsassa_pkcs1_v1_5_with_sha3_224 -#define der_oid_sha3_256WithRSAEncryption \ - der_oid_id_rsassa_pkcs1_v1_5_with_sha3_256 -#define der_oid_sha3_384WithRSAEncryption \ - der_oid_id_rsassa_pkcs1_v1_5_with_sha3_384 -#define der_oid_sha3_512WithRSAEncryption \ - der_oid_id_rsassa_pkcs1_v1_5_with_sha3_512 - -#define MD_with_RSA_CASE(name, var) \ - case NID_##name: \ - var = der_oid_##name##WithRSAEncryption; \ - var##_sz = sizeof(der_oid_##name##WithRSAEncryption); \ - break; - -int DER_w_algorithmIdentifier_RSA_with(WPACKET *pkt, int tag, - RSA *rsa, int mdnid) -{ - const unsigned char *precompiled = NULL; - size_t precompiled_sz = 0; - - switch (mdnid) { -#ifndef FIPS_MODULE - MD_with_RSA_CASE(md2, precompiled); - MD_with_RSA_CASE(md5, precompiled); - MD_with_RSA_CASE(md4, precompiled); - MD_with_RSA_CASE(ripemd160, precompiled); -/* TODO(3.0) Decide what to do about mdc2 and md5_sha1 */ -#endif - MD_with_RSA_CASE(sha1, precompiled); - MD_with_RSA_CASE(sha224, precompiled); - MD_with_RSA_CASE(sha256, precompiled); - MD_with_RSA_CASE(sha384, precompiled); - MD_with_RSA_CASE(sha512, precompiled); - MD_with_RSA_CASE(sha512_224, precompiled); - MD_with_RSA_CASE(sha512_256, precompiled); - MD_with_RSA_CASE(sha3_224, precompiled); - MD_with_RSA_CASE(sha3_256, precompiled); - MD_with_RSA_CASE(sha3_384, precompiled); - MD_with_RSA_CASE(sha3_512, precompiled); - default: - return 0; - } - - return DER_w_begin_sequence(pkt, tag) - /* No parameters (yet?) */ - && DER_w_precompiled(pkt, -1, precompiled, precompiled_sz) - && DER_w_end_sequence(pkt, tag); -} diff --git a/providers/common/der/der_rsa_sig.c b/providers/common/der/der_rsa_sig.c new file mode 100644 index 00000000..a1ab263d --- /dev/null +++ b/providers/common/der/der_rsa_sig.c @@ -0,0 +1,64 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/packet.h" +#include "prov/der_rsa.h" +#include "prov/der_digests.h" + +/* Aliases so we can have a uniform MD_with_RSA_CASE */ +#define der_oid_sha3_224WithRSAEncryption \ + der_oid_id_rsassa_pkcs1_v1_5_with_sha3_224 +#define der_oid_sha3_256WithRSAEncryption \ + der_oid_id_rsassa_pkcs1_v1_5_with_sha3_256 +#define der_oid_sha3_384WithRSAEncryption \ + der_oid_id_rsassa_pkcs1_v1_5_with_sha3_384 +#define der_oid_sha3_512WithRSAEncryption \ + der_oid_id_rsassa_pkcs1_v1_5_with_sha3_512 + +#define MD_with_RSA_CASE(name, var) \ + case NID_##name: \ + var = der_oid_##name##WithRSAEncryption; \ + var##_sz = sizeof(der_oid_##name##WithRSAEncryption); \ + break; + +int DER_w_algorithmIdentifier_MDWithRSAEncryption(WPACKET *pkt, int tag, + RSA *rsa, int mdnid) +{ + const unsigned char *precompiled = NULL; + size_t precompiled_sz = 0; + + switch (mdnid) { +#ifndef FIPS_MODULE + MD_with_RSA_CASE(md2, precompiled); + MD_with_RSA_CASE(md5, precompiled); + MD_with_RSA_CASE(md4, precompiled); + MD_with_RSA_CASE(ripemd160, precompiled); +/* TODO(3.0) Decide what to do about mdc2 and md5_sha1 */ +#endif + MD_with_RSA_CASE(sha1, precompiled); + MD_with_RSA_CASE(sha224, precompiled); + MD_with_RSA_CASE(sha256, precompiled); + MD_with_RSA_CASE(sha384, precompiled); + MD_with_RSA_CASE(sha512, precompiled); + MD_with_RSA_CASE(sha512_224, precompiled); + MD_with_RSA_CASE(sha512_256, precompiled); + MD_with_RSA_CASE(sha3_224, precompiled); + MD_with_RSA_CASE(sha3_256, precompiled); + MD_with_RSA_CASE(sha3_384, precompiled); + MD_with_RSA_CASE(sha3_512, precompiled); + default: + return 0; + } + + return DER_w_begin_sequence(pkt, tag) + /* No parameters (yet?) */ + && DER_w_precompiled(pkt, -1, precompiled, precompiled_sz) + && DER_w_end_sequence(pkt, tag); +} diff --git a/providers/common/der/oids_to_c.pm b/providers/common/der/oids_to_c.pm index 64e6c07d..dee32631 100644 --- a/providers/common/der/oids_to_c.pm +++ b/providers/common/der/oids_to_c.pm @@ -28,12 +28,19 @@ use Data::Dumper; sub filter_to_H { my ($name, $comment) = @{ shift() }; my @oid_nums = @_; + my $oid_size = scalar @oid_nums; + (my $C_comment = $comment) =~ s|^| * |msg; + $C_comment = "\n/*\n${C_comment}\n */" if $C_comment ne ''; (my $C_name = $name) =~ s|-|_|g; my $C_bytes_size = 2 + scalar @_; + my $C_bytes = join(', ', map { sprintf("0x%02X", $_) } @oid_nums ); return <<"_____"; -extern const unsigned char der_oid_${C_name}[$C_bytes_size]; +$C_comment +#define DER_OID_V_${C_name} DER_P_OBJECT, $oid_size, ${C_bytes} +#define DER_OID_SZ_${C_name} ${C_bytes_size} +extern const unsigned char der_oid_${C_name}[DER_OID_SZ_${C_name}]; _____ } @@ -48,12 +55,9 @@ sub filter_to_C { $C_comment = "\n/*\n${C_comment}\n */" if $C_comment ne ''; (my $C_name = $name) =~ s|-|_|g; my $C_bytes_size = 2 + $oid_size; - my $C_bytes = join(', ', map { sprintf("0x%02X", $_) } @oid_nums ); return <<"_____"; $C_comment -#define DER_OID_V_${C_name} DER_P_OBJECT, $oid_size, ${C_bytes} -#define DER_OID_SZ_${C_name} ${C_bytes_size} const unsigned char der_oid_${C_name}[DER_OID_SZ_${C_name}] = { DER_OID_V_${C_name} }; diff --git a/providers/common/include/prov/bio.h b/providers/common/include/prov/bio.h index 732dc06f..c63f6b5d 100644 --- a/providers/common/include/prov/bio.h +++ b/providers/common/include/prov/bio.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/common/provider_util.c b/providers/common/provider_util.c index 270609e9..b5511dbd 100644 --- a/providers/common/provider_util.c +++ b/providers/common/provider_util.c @@ -189,8 +189,8 @@ int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx, if (macname != NULL) { EVP_MAC *mac = EVP_MAC_fetch(libctx, macname, properties); - EVP_MAC_CTX_free(*macctx); - *macctx = mac == NULL ? NULL : EVP_MAC_CTX_new(mac); + EVP_MAC_free_ctx(*macctx); + *macctx = mac == NULL ? NULL : EVP_MAC_new_ctx(mac); /* The context holds on to the MAC */ EVP_MAC_free(mac); if (*macctx == NULL) @@ -241,10 +241,10 @@ int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx, #endif *mp = OSSL_PARAM_construct_end(); - if (EVP_MAC_CTX_set_params(*macctx, mac_params)) + if (EVP_MAC_set_ctx_params(*macctx, mac_params)) return 1; - EVP_MAC_CTX_free(*macctx); + EVP_MAC_free_ctx(*macctx); *macctx = NULL; return 0; } diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 1c4f3fdf..0484a54f 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -113,11 +113,12 @@ static const OSSL_PARAM fips_param_types[] = { /* * Parameters to retrieve from the core provider - required for self testing. * NOTE: inside core_get_params() these will be loaded from config items - * stored inside prov->parameters (except for OSSL_PROV_PARAM_MODULE_FILENAME). + * stored inside prov->parameters (except for + * OSSL_PROV_PARAM_CORE_MODULE_FILENAME). */ static OSSL_PARAM core_params[] = { - OSSL_PARAM_utf8_ptr(OSSL_PROV_PARAM_MODULE_FILENAME, + OSSL_PARAM_utf8_ptr(OSSL_PROV_PARAM_CORE_MODULE_FILENAME, selftest_params.module_filename, sizeof(selftest_params.module_filename)), OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_MODULE_MAC, @@ -376,8 +377,17 @@ static const OSSL_ALGORITHM fips_digests[] = { { "SHA3-384", "provider=fips,fips=yes", sha3_384_functions }, { "SHA3-512", "provider=fips,fips=yes", sha3_512_functions }, - /* Non-FIPS algorithm to support oneshot_hash in the Ed448 code */ - { "SHAKE-256:SHAKE256", "provider=fips,fips=no", shake_256_functions }, + { "SHAKE-128:SHAKE128", "provider=fips,fips=yes", shake_128_functions }, + { "SHAKE-256:SHAKE256", "provider=fips,fips=yes", shake_256_functions }, + + /* + * KECCAK-KMAC-128 and KECCAK-KMAC-256 as hashes are mostly useful for + * KMAC128 and KMAC256. + */ + { "KECCAK-KMAC-128:KECCAK-KMAC128", "provider=fips,fips=yes", + keccak_kmac_128_functions }, + { "KECCAK-KMAC-256:KECCAK-KMAC256", "provider=fips,fips=yes", + keccak_kmac_256_functions }, { NULL, NULL, NULL } }; @@ -389,6 +399,18 @@ static const OSSL_ALGORITHM_CAPABLE fips_ciphers[] = { ALG("AES-256-CBC", aes256cbc_functions), ALG("AES-192-CBC", aes192cbc_functions), ALG("AES-128-CBC", aes128cbc_functions), + ALG("AES-256-OFB", aes256ofb_functions), + ALG("AES-192-OFB", aes192ofb_functions), + ALG("AES-128-OFB", aes128ofb_functions), + ALG("AES-256-CFB", aes256cfb_functions), + ALG("AES-192-CFB", aes192cfb_functions), + ALG("AES-128-CFB", aes128cfb_functions), + ALG("AES-256-CFB1", aes256cfb1_functions), + ALG("AES-192-CFB1", aes192cfb1_functions), + ALG("AES-128-CFB1", aes128cfb1_functions), + ALG("AES-256-CFB8", aes256cfb8_functions), + ALG("AES-192-CFB8", aes192cfb8_functions), + ALG("AES-128-CFB8", aes128cfb8_functions), ALG("AES-256-CTR", aes256ctr_functions), ALG("AES-192-CTR", aes192ctr_functions), ALG("AES-128-CTR", aes128ctr_functions), @@ -426,8 +448,13 @@ static const OSSL_ALGORITHM_CAPABLE fips_ciphers[] = { static OSSL_ALGORITHM exported_fips_ciphers[OSSL_NELEM(fips_ciphers)]; static const OSSL_ALGORITHM fips_macs[] = { +#ifndef OPENSSL_NO_CMAC + { "CMAC", "provider=fips,fips=yes", cmac_functions }, +#endif { "GMAC", "provider=fips,fips=yes", gmac_functions }, { "HMAC", "provider=fips,fips=yes", hmac_functions }, + { "KMAC-128:KMAC128", "provider=fips,fips=yes", kmac128_functions }, + { "KMAC-256:KMAC256", "provider=fips,fips=yes", kmac256_functions }, { NULL, NULL, NULL } }; @@ -435,7 +462,10 @@ static const OSSL_ALGORITHM fips_kdfs[] = { { "HKDF", "provider=fips,fips=yes", kdf_hkdf_functions }, { "SSKDF", "provider=fips,fips=yes", kdf_sskdf_functions }, { "PBKDF2", "provider=fips,fips=yes", kdf_pbkdf2_functions }, + { "SSHKDF", "provider=fips,fips=yes", kdf_sshkdf_functions }, + { "X963KDF", "provider=fips,fips=yes", kdf_x963_kdf_functions }, { "TLS1-PRF", "provider=fips,fips=yes", kdf_tls1_prf_functions }, + { "KBKDF", "provider=fips,fips=yes", kdf_kbkdf_functions }, { NULL, NULL, NULL } }; @@ -477,7 +507,8 @@ static const OSSL_ALGORITHM fips_keymgmt[] = { { "DSA", "provider=fips,fips=yes", dsa_keymgmt_functions }, #endif { "RSA:rsaEncryption", "provider=fips,fips=yes", rsa_keymgmt_functions }, - { "RSA-PSS:RSASSA-PSS", "provider=default", rsapss_keymgmt_functions }, + { "RSA-PSS:RSASSA-PSS", "provider=fips,fips=yes", + rsapss_keymgmt_functions }, #ifndef OPENSSL_NO_EC { "EC:id-ecPublicKey", "provider=fips,fips=yes", ec_keymgmt_functions }, { "X25519", "provider=fips,fips=no", x25519_keymgmt_functions }, diff --git a/providers/fips/self_test.c b/providers/fips/self_test.c index b767e8f3..4619fede 100644 --- a/providers/fips/self_test.c +++ b/providers/fips/self_test.c @@ -146,7 +146,7 @@ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_BIO_read_ex_fn read_ex_cb, OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC); mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL); - ctx = EVP_MAC_CTX_new(mac); + ctx = EVP_MAC_new_ctx(mac); if (mac == NULL || ctx == NULL) goto err; @@ -156,7 +156,7 @@ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_BIO_read_ex_fn read_ex_cb, sizeof(fixed_key)); *p = OSSL_PARAM_construct_end(); - if (EVP_MAC_CTX_set_params(ctx, params) <= 0 + if (EVP_MAC_set_ctx_params(ctx, params) <= 0 || !EVP_MAC_init(ctx)) goto err; @@ -177,7 +177,7 @@ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_BIO_read_ex_fn read_ex_cb, ret = 1; err: OSSL_SELF_TEST_onend(ev, ret); - EVP_MAC_CTX_free(ctx); + EVP_MAC_free_ctx(ctx); EVP_MAC_free(mac); return ret; } diff --git a/providers/fips/self_test_kats.c b/providers/fips/self_test_kats.c index 5ef4474a..6b75f12e 100644 --- a/providers/fips/self_test_kats.c +++ b/providers/fips/self_test_kats.c @@ -204,7 +204,7 @@ static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st, if (kdf == NULL) goto err; - ctx = EVP_KDF_CTX_new(kdf); + ctx = EVP_KDF_new_ctx(kdf); if (ctx == NULL) goto err; @@ -216,7 +216,7 @@ static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st, params = OSSL_PARAM_BLD_to_param(bld); if (params == NULL) goto err; - if (!EVP_KDF_CTX_set_params(ctx, params)) + if (!EVP_KDF_set_ctx_params(ctx, params)) goto err; if (t->expected_len > sizeof(out)) @@ -232,7 +232,7 @@ static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st, ret = 1; err: EVP_KDF_free(kdf); - EVP_KDF_CTX_free(ctx); + EVP_KDF_free_ctx(ctx); BN_CTX_free(bnctx); OSSL_PARAM_BLD_free_params(params); OSSL_PARAM_BLD_free(bld); diff --git a/providers/implementations/asymciphers/rsa_enc.c b/providers/implementations/asymciphers/rsa_enc.c index dde63852..585cab41 100644 --- a/providers/implementations/asymciphers/rsa_enc.c +++ b/providers/implementations/asymciphers/rsa_enc.c @@ -38,13 +38,12 @@ static OSSL_OP_asym_cipher_set_ctx_params_fn rsa_set_ctx_params; static OSSL_OP_asym_cipher_settable_ctx_params_fn rsa_settable_ctx_params; static OSSL_ITEM padding_item[] = { - { RSA_PKCS1_PADDING, "pkcs1" }, - { RSA_SSLV23_PADDING, "sslv23" }, - { RSA_NO_PADDING, "none" }, - { RSA_PKCS1_OAEP_PADDING, "oaep" }, /* Correct spelling first */ + { RSA_PKCS1_PADDING, OSSL_PKEY_RSA_PAD_MODE_PKCSV15 }, + { RSA_SSLV23_PADDING, OSSL_PKEY_RSA_PAD_MODE_SSLV23 }, + { RSA_NO_PADDING, OSSL_PKEY_RSA_PAD_MODE_NONE }, + { RSA_PKCS1_OAEP_PADDING, OSSL_PKEY_RSA_PAD_MODE_OAEP }, /* Correct spelling first */ { RSA_PKCS1_OAEP_PADDING, "oeap" }, - { RSA_X931_PADDING, "x931" }, - { RSA_PKCS1_PSS_PADDING, "pss" }, + { RSA_X931_PADDING, OSSL_PKEY_RSA_PAD_MODE_X931 }, { 0, NULL } }; @@ -133,11 +132,13 @@ static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, PROVerr(0, ERR_R_INTERNAL_ERROR); return 0; } - ret = RSA_padding_add_PKCS1_OAEP_mgf1(tbuf, rsasize, in, inlen, - prsactx->oaep_label, - prsactx->oaep_labellen, - prsactx->oaep_md, - prsactx->mgf1_md); + ret = + rsa_padding_add_PKCS1_OAEP_mgf1_with_libctx(prsactx->libctx, tbuf, + rsasize, in, inlen, + prsactx->oaep_label, + prsactx->oaep_labellen, + prsactx->oaep_md, + prsactx->mgf1_md); if (!ret) { OPENSSL_free(tbuf); @@ -252,6 +253,7 @@ static void rsa_freectx(void *vprsactx) EVP_MD_free(prsactx->oaep_md); EVP_MD_free(prsactx->mgf1_md); + OPENSSL_free(prsactx->oaep_label); OPENSSL_free(prsactx); } diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c index bbf622c3..8f6437b6 100644 --- a/providers/implementations/kdfs/hkdf.c +++ b/providers/implementations/kdfs/hkdf.c @@ -29,7 +29,7 @@ #include "prov/provider_util.h" #include "e_os.h" -#define HKDF_MAXBUF 1024 +#define HKDF_MAXBUF 2048 static OSSL_OP_kdf_newctx_fn kdf_hkdf_new; static OSSL_OP_kdf_freectx_fn kdf_hkdf_free; diff --git a/providers/implementations/kdfs/kbkdf.c b/providers/implementations/kdfs/kbkdf.c index acc7d7f4..12bf711e 100644 --- a/providers/implementations/kdfs/kbkdf.c +++ b/providers/implementations/kdfs/kbkdf.c @@ -123,7 +123,7 @@ static void kbkdf_reset(void *vctx) { KBKDF *ctx = (KBKDF *)vctx; - EVP_MAC_CTX_free(ctx->ctx_init); + EVP_MAC_free_ctx(ctx->ctx_init); OPENSSL_clear_free(ctx->context, ctx->context_len); OPENSSL_clear_free(ctx->label, ctx->label_len); OPENSSL_clear_free(ctx->ki, ctx->ki_len); @@ -151,7 +151,7 @@ static int derive(EVP_MAC_CTX *ctx_init, kbkdf_mode mode, unsigned char *iv, for (counter = 1; written < ko_len; counter++) { i = be32(counter); - ctx = EVP_MAC_CTX_dup(ctx_init); + ctx = EVP_MAC_dup_ctx(ctx_init); if (ctx == NULL) goto done; @@ -172,13 +172,13 @@ static int derive(EVP_MAC_CTX *ctx_init, kbkdf_mode mode, unsigned char *iv, written += h; k_i_len = h; - EVP_MAC_CTX_free(ctx); + EVP_MAC_free_ctx(ctx); ctx = NULL; } ret = 1; done: - EVP_MAC_CTX_free(ctx); + EVP_MAC_free_ctx(ctx); return ret; } @@ -247,9 +247,9 @@ static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) NULL, NULL, libctx)) return 0; else if (ctx->ctx_init != NULL - && !EVP_MAC_is_a(EVP_MAC_CTX_mac(ctx->ctx_init), + && !EVP_MAC_is_a(EVP_MAC_get_ctx_mac(ctx->ctx_init), OSSL_MAC_NAME_HMAC) - && !EVP_MAC_is_a(EVP_MAC_CTX_mac(ctx->ctx_init), + && !EVP_MAC_is_a(EVP_MAC_get_ctx_mac(ctx->ctx_init), OSSL_MAC_NAME_CMAC)) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MAC); return 0; @@ -288,7 +288,7 @@ static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) ctx->ki, ctx->ki_len); mparams[1] = OSSL_PARAM_construct_end(); - if (!EVP_MAC_CTX_set_params(ctx->ctx_init, mparams) + if (!EVP_MAC_set_ctx_params(ctx->ctx_init, mparams) || !EVP_MAC_init(ctx->ctx_init)) return 0; } diff --git a/providers/implementations/kdfs/sskdf.c b/providers/implementations/kdfs/sskdf.c index 2c4600d2..023395b1 100644 --- a/providers/implementations/kdfs/sskdf.c +++ b/providers/implementations/kdfs/sskdf.c @@ -168,7 +168,7 @@ static int kmac_init(EVP_MAC_CTX *ctx, const unsigned char *custom, (void *)custom, custom_len); params[1] = OSSL_PARAM_construct_end(); - if (!EVP_MAC_CTX_set_params(ctx, params)) + if (!EVP_MAC_set_ctx_params(ctx, params)) return 0; /* By default only do one iteration if kmac_out_len is not specified */ @@ -186,7 +186,7 @@ static int kmac_init(EVP_MAC_CTX *ctx, const unsigned char *custom, params[0] = OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &kmac_out_len); - if (EVP_MAC_CTX_set_params(ctx, params) <= 0) + if (EVP_MAC_set_ctx_params(ctx, params) <= 0) return 0; /* @@ -233,7 +233,7 @@ static int SSKDF_mac_kdm(EVP_MAC_CTX *ctx_init, (void *)salt, salt_len); *p = OSSL_PARAM_construct_end(); - if (!EVP_MAC_CTX_set_params(ctx_init, params)) + if (!EVP_MAC_set_ctx_params(ctx_init, params)) goto end; if (!kmac_init(ctx_init, kmac_custom, kmac_custom_len, kmac_out_len, @@ -256,7 +256,7 @@ static int SSKDF_mac_kdm(EVP_MAC_CTX *ctx_init, c[2] = (unsigned char)((counter >> 8) & 0xff); c[3] = (unsigned char)(counter & 0xff); - ctx = EVP_MAC_CTX_dup(ctx_init); + ctx = EVP_MAC_dup_ctx(ctx_init); if (!(ctx != NULL && EVP_MAC_update(ctx, c, sizeof(c)) && EVP_MAC_update(ctx, z, z_len) @@ -275,7 +275,7 @@ static int SSKDF_mac_kdm(EVP_MAC_CTX *ctx_init, memcpy(out, mac, len); break; } - EVP_MAC_CTX_free(ctx); + EVP_MAC_free_ctx(ctx); ctx = NULL; } ret = 1; @@ -285,7 +285,7 @@ end: else OPENSSL_cleanse(mac_buf, sizeof(mac_buf)); - EVP_MAC_CTX_free(ctx); + EVP_MAC_free_ctx(ctx); return ret; } @@ -303,7 +303,7 @@ static void sskdf_reset(void *vctx) { KDF_SSKDF *ctx = (KDF_SSKDF *)vctx; - EVP_MAC_CTX_free(ctx->macctx); + EVP_MAC_free_ctx(ctx->macctx); ossl_prov_digest_reset(&ctx->digest); OPENSSL_clear_free(ctx->secret, ctx->secret_len); OPENSSL_clear_free(ctx->info, ctx->info_len); @@ -360,7 +360,7 @@ static int sskdf_derive(void *vctx, unsigned char *key, size_t keylen) const unsigned char *custom = NULL; size_t custom_len = 0; int default_salt_len; - EVP_MAC *mac = EVP_MAC_CTX_mac(ctx->macctx); + EVP_MAC *mac = EVP_MAC_get_ctx_mac(ctx->macctx); /* * TODO(3.0) investigate the necessity to have all these controls. diff --git a/providers/implementations/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c index 84d712af..1b47247c 100644 --- a/providers/implementations/kdfs/tls1_prf.c +++ b/providers/implementations/kdfs/tls1_prf.c @@ -116,8 +116,8 @@ static void kdf_tls1_prf_reset(void *vctx) { TLS1_PRF *ctx = (TLS1_PRF *)vctx; - EVP_MAC_CTX_free(ctx->P_hash); - EVP_MAC_CTX_free(ctx->P_sha1); + EVP_MAC_free_ctx(ctx->P_hash); + EVP_MAC_free_ctx(ctx->P_sha1); OPENSSL_clear_free(ctx->sec, ctx->seclen); OPENSSL_cleanse(ctx->seed, ctx->seedlen); memset(ctx, 0, sizeof(*ctx)); @@ -163,7 +163,7 @@ static int kdf_tls1_prf_set_ctx_params(void *vctx, const OSSL_PARAM params[]) NULL, SN_sha1, libctx)) return 0; } else { - EVP_MAC_CTX_free(ctx->P_sha1); + EVP_MAC_free_ctx(ctx->P_sha1); if (!ossl_prov_macctx_load_from_params(&ctx->P_hash, params, OSSL_MAC_NAME_HMAC, NULL, NULL, libctx)) @@ -280,7 +280,7 @@ static int tls1_prf_P_hash(EVP_MAC_CTX *ctx_init, *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, (void *)sec, sec_len); *p = OSSL_PARAM_construct_end(); - if (!EVP_MAC_CTX_set_params(ctx_init, params)) + if (!EVP_MAC_set_ctx_params(ctx_init, params)) goto err; if (!EVP_MAC_init(ctx_init)) goto err; @@ -288,7 +288,7 @@ static int tls1_prf_P_hash(EVP_MAC_CTX *ctx_init, if (chunk == 0) goto err; /* A(0) = seed */ - ctx_Ai = EVP_MAC_CTX_dup(ctx_init); + ctx_Ai = EVP_MAC_dup_ctx(ctx_init); if (ctx_Ai == NULL) goto err; if (seed != NULL && !EVP_MAC_update(ctx_Ai, seed, seed_len)) @@ -298,18 +298,18 @@ static int tls1_prf_P_hash(EVP_MAC_CTX *ctx_init, /* calc: A(i) = HMAC_(secret, A(i-1)) */ if (!EVP_MAC_final(ctx_Ai, Ai, &Ai_len, sizeof(Ai))) goto err; - EVP_MAC_CTX_free(ctx_Ai); + EVP_MAC_free_ctx(ctx_Ai); ctx_Ai = NULL; /* calc next chunk: HMAC_(secret, A(i) + seed) */ - ctx = EVP_MAC_CTX_dup(ctx_init); + ctx = EVP_MAC_dup_ctx(ctx_init); if (ctx == NULL) goto err; if (!EVP_MAC_update(ctx, Ai, Ai_len)) goto err; /* save state for calculating next A(i) value */ if (olen > chunk) { - ctx_Ai = EVP_MAC_CTX_dup(ctx); + ctx_Ai = EVP_MAC_dup_ctx(ctx); if (ctx_Ai == NULL) goto err; } @@ -324,15 +324,15 @@ static int tls1_prf_P_hash(EVP_MAC_CTX *ctx_init, } if (!EVP_MAC_final(ctx, out, NULL, olen)) goto err; - EVP_MAC_CTX_free(ctx); + EVP_MAC_free_ctx(ctx); ctx = NULL; out += chunk; olen -= chunk; } ret = 1; err: - EVP_MAC_CTX_free(ctx); - EVP_MAC_CTX_free(ctx_Ai); + EVP_MAC_free_ctx(ctx); + EVP_MAC_free_ctx(ctx_Ai); OPENSSL_cleanse(Ai, sizeof(Ai)); return ret; } diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c index a551a72d..0dd1796d 100644 --- a/providers/implementations/keymgmt/dh_kmgmt.c +++ b/providers/implementations/keymgmt/dh_kmgmt.c @@ -36,6 +36,8 @@ static OSSL_OP_keymgmt_gen_fn dh_gen; static OSSL_OP_keymgmt_gen_cleanup_fn dh_gen_cleanup; static OSSL_OP_keymgmt_get_params_fn dh_get_params; static OSSL_OP_keymgmt_gettable_params_fn dh_gettable_params; +static OSSL_OP_keymgmt_set_params_fn dh_set_params; +static OSSL_OP_keymgmt_settable_params_fn dh_settable_params; static OSSL_OP_keymgmt_has_fn dh_has; static OSSL_OP_keymgmt_match_fn dh_match; static OSSL_OP_keymgmt_validate_fn dh_validate; @@ -235,8 +237,8 @@ err: OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL), \ OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL), \ OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL), \ - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_GROUP, NULL, 0), \ - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0) + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0), \ + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DH_GROUP, NULL, 0) # define DH_IMEXPORTABLE_PUBLIC_KEY \ OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0) # define DH_IMEXPORTABLE_PRIVATE_KEY \ @@ -298,6 +300,15 @@ static ossl_inline int dh_get_params(void *key, OSSL_PARAM params[]) if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL && !OSSL_PARAM_set_int(p, DH_size(dh))) return 0; + if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL) { + if (p->data_type != OSSL_PARAM_OCTET_STRING) + return 0; + p->return_size = dh_key2buf(dh, (unsigned char **)&p->data, + p->data_size, 0); + if (p->return_size == 0) + return 0; + } + return ffc_params_todata(dh_get0_params(dh), NULL, params) && dh_key_todata(dh, NULL, params); } @@ -306,6 +317,7 @@ static const OSSL_PARAM dh_params[] = { OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0), DH_IMEXPORTABLE_PARAMETERS, DH_IMEXPORTABLE_PUBLIC_KEY, DH_IMEXPORTABLE_PRIVATE_KEY, @@ -317,6 +329,30 @@ static const OSSL_PARAM *dh_gettable_params(void) return dh_params; } +static const OSSL_PARAM dh_known_settable_params[] = { + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *dh_settable_params(void) +{ + return dh_known_settable_params; +} + +static int dh_set_params(void *key, const OSSL_PARAM params[]) +{ + DH *dh = key; + const OSSL_PARAM *p; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT); + if (p != NULL + && (p->data_type != OSSL_PARAM_OCTET_STRING + || !dh_buf2key(dh, p->data, p->data_size))) + return 0; + + return 1; +} + static int dh_validate_public(DH *dh) { const BIGNUM *pub_key = NULL; @@ -427,7 +463,7 @@ static int dh_gen_set_params(void *genctx, const OSSL_PARAM params[]) return 0; } } - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GROUP); + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_GROUP); if (p != NULL) { if (p->data_type != OSSL_PARAM_UTF8_STRING || ((gctx->group_nid = ffc_named_group_to_uid(p->data)) == NID_undef)) { @@ -436,7 +472,7 @@ static int dh_gen_set_params(void *genctx, const OSSL_PARAM params[]) } gctx->gen_type = DH_PARAMGEN_TYPE_GROUP; } - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GENERATOR); + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_GENERATOR); if (p != NULL && !OSSL_PARAM_get_int(p, &gctx->generator)) return 0; p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_GINDEX); @@ -486,7 +522,9 @@ static int dh_gen_set_params(void *genctx, const OSSL_PARAM params[]) static const OSSL_PARAM *dh_gen_settable_params(void *provctx) { static OSSL_PARAM settable[] = { - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_GROUP, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DH_GROUP, NULL, 0), + OSSL_PARAM_int(OSSL_PKEY_PARAM_DH_PRIV_LEN, NULL), + OSSL_PARAM_int(OSSL_PKEY_PARAM_DH_GENERATOR, NULL), OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_TYPE, NULL, 0), OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_PBITS, NULL), OSSL_PARAM_size_t(OSSL_PKEY_PARAM_FFC_QBITS, NULL), @@ -494,10 +532,8 @@ static const OSSL_PARAM *dh_gen_settable_params(void *provctx) OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_DIGEST_PROPS, NULL, 0), OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL), OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0), - OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GENERATOR, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL), - OSSL_PARAM_int(OSSL_PKEY_PARAM_DH_PRIV_LEN, NULL), OSSL_PARAM_END }; return settable; @@ -621,6 +657,8 @@ const OSSL_DISPATCH dh_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))dh_freedata }, { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))dh_get_params }, { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))dh_gettable_params }, + { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))dh_set_params }, + { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))dh_settable_params }, { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))dh_has }, { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))dh_match }, { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))dh_validate }, diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c index de54b9a3..af8361fb 100644 --- a/providers/implementations/keymgmt/dsa_kmgmt.c +++ b/providers/implementations/keymgmt/dsa_kmgmt.c @@ -213,7 +213,6 @@ err: OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_GINDEX, NULL), \ OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_PCOUNTER, NULL), \ OSSL_PARAM_int(OSSL_PKEY_PARAM_FFC_H, NULL), \ - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_FFC_GROUP, NULL, 0), \ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_FFC_SEED, NULL, 0) # define DSA_IMEXPORTABLE_PUBLIC_KEY \ OSSL_PARAM_BN(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0) diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c index a48b2795..7e322073 100644 --- a/providers/implementations/keymgmt/ec_kmgmt.c +++ b/providers/implementations/keymgmt/ec_kmgmt.c @@ -504,6 +504,20 @@ int ec_get_params(void *key, OSSL_PARAM params[]) if (!OSSL_PARAM_set_int(p, ecdh_cofactor_mode)) return 0; } + if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL) { + BN_CTX *ctx = BN_CTX_new_ex(ec_key_get_libctx(key)); + + if (ctx == NULL) + return 0; + p->return_size = EC_POINT_point2oct(EC_KEY_get0_group(key), + EC_KEY_get0_public_key(key), + POINT_CONVERSION_UNCOMPRESSED, + p->data, p->return_size, ctx); + BN_CTX_free(ctx); + if (p->return_size == 0) + return 0; + } + ret = domparams_to_params(eck, NULL, params) && key_to_params(eck, NULL, params, 1, &pub_key) && otherparams_to_params(eck, NULL, params); @@ -515,6 +529,7 @@ static const OSSL_PARAM ec_known_gettable_params[] = { OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0), EC_IMEXPORTABLE_DOM_PARAMETERS, EC_IMEXPORTABLE_PUBLIC_KEY, EC_IMEXPORTABLE_PRIVATE_KEY, @@ -530,6 +545,7 @@ const OSSL_PARAM *ec_gettable_params(void) static const OSSL_PARAM ec_known_settable_params[] = { OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0), OSSL_PARAM_END }; @@ -545,11 +561,21 @@ int ec_set_params(void *key, const OSSL_PARAM params[]) EC_KEY *eck = key; const OSSL_PARAM *p; - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH); - if (p != NULL && !ec_set_param_ecdh_cofactor_mode(eck, p)) - return 0; + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT); + if (p != NULL) { + BN_CTX *ctx = BN_CTX_new_ex(ec_key_get_libctx(key)); + int ret = 1; - return 1; + if (ctx == NULL + || p->data_type != OSSL_PARAM_OCTET_STRING + || !EC_KEY_oct2key(key, p->data, p->data_size, ctx)) + ret = 0; + BN_CTX_free(ctx); + if (!ret) + return 0; + } + + return ec_key_otherparams_fromdata(eck, params); } static @@ -583,9 +609,9 @@ int ec_validate(void *keydata, int selection) struct ec_gen_ctx { OPENSSL_CTX *libctx; - EC_GROUP *gen_group; int selection; + int ecdh_mode; }; static void *ec_gen_init(void *provctx, int selection) @@ -600,6 +626,7 @@ static void *ec_gen_init(void *provctx, int selection) gctx->libctx = libctx; gctx->gen_group = NULL; gctx->selection = selection; + gctx->ecdh_mode = 0; } return gctx; } @@ -636,6 +663,11 @@ static int ec_gen_set_params(void *genctx, const OSSL_PARAM params[]) struct ec_gen_ctx *gctx = genctx; const OSSL_PARAM *p; + if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH)) + != NULL) { + if (!OSSL_PARAM_get_int(p, &gctx->ecdh_mode)) + return 0; + } if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_NAME)) != NULL) { const char *curve_name = NULL; @@ -670,7 +702,8 @@ static int ec_gen_set_params(void *genctx, const OSSL_PARAM params[]) static const OSSL_PARAM *ec_gen_settable_params(void *provctx) { static OSSL_PARAM settable[] = { - { OSSL_PKEY_PARAM_EC_NAME, OSSL_PARAM_UTF8_STRING, NULL, 0, 0 }, + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_NAME, NULL, 0), + OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), OSSL_PARAM_END }; @@ -705,6 +738,9 @@ static void *ec_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) ret = ret && EC_KEY_generate_key(ec); + if (gctx->ecdh_mode != -1) + ret = ret && ec_set_ecdh_cofactor_mode(ec, gctx->ecdh_mode); + if (ret) return ec; diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c index e2b613e5..e5c7e8bf 100644 --- a/providers/implementations/keymgmt/ecx_kmgmt.c +++ b/providers/implementations/keymgmt/ecx_kmgmt.c @@ -46,6 +46,14 @@ static OSSL_OP_keymgmt_gettable_params_fn x25519_gettable_params; static OSSL_OP_keymgmt_gettable_params_fn x448_gettable_params; static OSSL_OP_keymgmt_gettable_params_fn ed25519_gettable_params; static OSSL_OP_keymgmt_gettable_params_fn ed448_gettable_params; +static OSSL_OP_keymgmt_set_params_fn x25519_set_params; +static OSSL_OP_keymgmt_set_params_fn x448_set_params; +static OSSL_OP_keymgmt_set_params_fn ed25519_set_params; +static OSSL_OP_keymgmt_set_params_fn ed448_set_params; +static OSSL_OP_keymgmt_settable_params_fn x25519_settable_params; +static OSSL_OP_keymgmt_settable_params_fn x448_settable_params; +static OSSL_OP_keymgmt_settable_params_fn ed25519_settable_params; +static OSSL_OP_keymgmt_settable_params_fn ed448_settable_params; static OSSL_OP_keymgmt_has_fn ecx_has; static OSSL_OP_keymgmt_match_fn ecx_match; static OSSL_OP_keymgmt_import_fn ecx_import; @@ -93,8 +101,11 @@ static int ecx_has(void *keydata, int selection) int ok = 0; if (key != NULL) { - if ((selection & ECX_POSSIBLE_SELECTIONS) != 0) - ok = 1; + /* + * ECX keys always have all the parameters they need (i.e. none). + * Therefore we always return with 1, if asked about parameters. + */ + ok = 1; if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) ok = ok && key->haspubkey; @@ -233,6 +244,13 @@ static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits, if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL && !OSSL_PARAM_set_int(p, size)) return 0; + if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL + && (ecx->type == ECX_KEY_TYPE_X25519 + || ecx->type == ECX_KEY_TYPE_X448)) { + if (!OSSL_PARAM_set_octet_string(p, ecx->pubkey, ecx->keylen)) + return 0; + } + return key_to_params(ecx, NULL, params); } @@ -273,16 +291,17 @@ static int ed448_get_params(void *key, OSSL_PARAM params[]) && ed_get_params(key, params); } -static const OSSL_PARAM ecx_params[] = { +static const OSSL_PARAM ecx_gettable_params[] = { OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0), ECX_KEY_TYPES(), OSSL_PARAM_END }; -static const OSSL_PARAM ed_params[] = { +static const OSSL_PARAM ed_gettable_params[] = { OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), @@ -292,22 +311,92 @@ static const OSSL_PARAM ed_params[] = { static const OSSL_PARAM *x25519_gettable_params(void) { - return ecx_params; + return ecx_gettable_params; } static const OSSL_PARAM *x448_gettable_params(void) { - return ecx_params; + return ecx_gettable_params; } static const OSSL_PARAM *ed25519_gettable_params(void) { - return ed_params; + return ed_gettable_params; } static const OSSL_PARAM *ed448_gettable_params(void) { - return ed_params; + return ed_gettable_params; +} + +static int ecx_set_params(void *key, const OSSL_PARAM params[]) +{ + ECX_KEY *ecxkey = key; + const OSSL_PARAM *p; + + p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT); + if (p != NULL) { + void *buf = ecxkey->pubkey; + + if (p->data_size != ecxkey->keylen + || !OSSL_PARAM_get_octet_string(p, &buf, sizeof(ecxkey->pubkey), + NULL)) + return 0; + OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen); + ecxkey->privkey = NULL; + ecxkey->haspubkey = 1; + } + + return 1; +} + +static int x25519_set_params(void *key, const OSSL_PARAM params[]) +{ + return ecx_set_params(key, params); +} + +static int x448_set_params(void *key, const OSSL_PARAM params[]) +{ + return ecx_set_params(key, params); +} + +static int ed25519_set_params(void *key, const OSSL_PARAM params[]) +{ + return 1; +} + +static int ed448_set_params(void *key, const OSSL_PARAM params[]) +{ + return 1; +} + +static const OSSL_PARAM ecx_settable_params[] = { + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM ed_settable_params[] = { + OSSL_PARAM_END +}; + +static const OSSL_PARAM *x25519_settable_params(void) +{ + return ecx_settable_params; +} + +static const OSSL_PARAM *x448_settable_params(void) +{ + return ecx_settable_params; +} + +static const OSSL_PARAM *ed25519_settable_params(void) +{ + return ed_settable_params; +} + +static const OSSL_PARAM *ed448_settable_params(void) +{ + return ed_settable_params; } static void *ecx_gen_init(void *provctx, int selection, ECX_KEY_TYPE type) @@ -450,6 +539,8 @@ static void ecx_gen_cleanup(void *genctx) { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_key_free }, \ { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \ { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \ + { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \ + { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \ { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \ { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \ { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \ diff --git a/providers/implementations/keymgmt/rsa_kmgmt.c b/providers/implementations/keymgmt/rsa_kmgmt.c index 53982e7d..68c02a4b 100644 --- a/providers/implementations/keymgmt/rsa_kmgmt.c +++ b/providers/implementations/keymgmt/rsa_kmgmt.c @@ -405,8 +405,8 @@ static void *gen_init(void *provctx, int selection, int rsa_type) } else { gctx->nbits = 2048; gctx->primes = RSA_DEFAULT_PRIME_NUM; + gctx->rsa_type = rsa_type; } - gctx->rsa_type = rsa_type; } return gctx; } @@ -490,6 +490,9 @@ static void *rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) RSA *rsa = NULL, *rsa_tmp = NULL; BN_GENCB *gencb = NULL; + if (gctx == NULL) + return NULL; + switch (gctx->rsa_type) { case RSA_FLAG_TYPE_RSA: /* For plain RSA keys, PSS parameters must not be set */ @@ -507,8 +510,7 @@ static void *rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) return NULL; } - if (gctx == NULL - || (rsa_tmp = rsa_new_with_ctx(gctx->libctx)) == NULL) + if ((rsa_tmp = rsa_new_with_ctx(gctx->libctx)) == NULL) return NULL; gctx->cb = osslcb; diff --git a/providers/implementations/serializers/serializer_rsa.c b/providers/implementations/serializers/serializer_rsa.c index 1bca05fb..71ca84c8 100644 --- a/providers/implementations/serializers/serializer_rsa.c +++ b/providers/implementations/serializers/serializer_rsa.c @@ -209,9 +209,9 @@ int ossl_prov_prepare_rsa_params(const void *rsa, int nid, break; } if (!DER_w_RSASSA_PSS_params(&pkt, -1, pss) - || !WPACKET_finish(&pkt)) + || !WPACKET_finish(&pkt) + || !WPACKET_get_total_written(&pkt, &str_sz)) goto err; - WPACKET_get_total_written(&pkt, &str_sz); WPACKET_cleanup(&pkt); /* diff --git a/providers/implementations/signature/dsa.c b/providers/implementations/signature/dsa.c index bfab2248..de6aac67 100644 --- a/providers/implementations/signature/dsa.c +++ b/providers/implementations/signature/dsa.c @@ -177,7 +177,8 @@ static int dsa_setup_md(PROV_DSA_CTX *ctx, */ ctx->aid_len = 0; if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) - && DER_w_algorithmIdentifier_DSA_with(&pkt, -1, ctx->dsa, md_nid) + && DER_w_algorithmIdentifier_DSA_with_MD(&pkt, -1, ctx->dsa, + md_nid) && WPACKET_finish(&pkt)) { WPACKET_get_total_written(&pkt, &ctx->aid_len); ctx->aid = WPACKET_get_curr(&pkt); @@ -445,6 +446,7 @@ static int dsa_set_ctx_params(void *vpdsactx, const OSSL_PARAM params[]) static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), OSSL_PARAM_END }; diff --git a/providers/implementations/signature/ecdsa.c b/providers/implementations/signature/ecdsa.c index 267950d5..d96f597a 100644 --- a/providers/implementations/signature/ecdsa.c +++ b/providers/implementations/signature/ecdsa.c @@ -238,7 +238,7 @@ static int ecdsa_digest_signverify_init(void *vctx, const char *mdname, */ ctx->aid_len = 0; if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) - && DER_w_algorithmIdentifier_ECDSA_with(&pkt, -1, ctx->ec, md_nid) + && DER_w_algorithmIdentifier_ECDSA_with_MD(&pkt, -1, ctx->ec, md_nid) && WPACKET_finish(&pkt)) { WPACKET_get_total_written(&pkt, &ctx->aid_len); ctx->aid = WPACKET_get_curr(&pkt); diff --git a/providers/implementations/signature/eddsa.c b/providers/implementations/signature/eddsa.c index 4ecc5266..35a69504 100644 --- a/providers/implementations/signature/eddsa.c +++ b/providers/implementations/signature/eddsa.c @@ -56,7 +56,7 @@ static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname, PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; ECX_KEY *edkey = (ECX_KEY *)vedkey; - if (mdname != NULL) { + if (mdname != NULL && mdname[0] != '\0') { PROVerr(0, PROV_R_INVALID_DIGEST); return 0; } diff --git a/providers/implementations/signature/rsa.c b/providers/implementations/signature/rsa.c index 4dc3a898..81611bb4 100644 --- a/providers/implementations/signature/rsa.c +++ b/providers/implementations/signature/rsa.c @@ -55,13 +55,11 @@ static OSSL_OP_signature_set_ctx_md_params_fn rsa_set_ctx_md_params; static OSSL_OP_signature_settable_ctx_md_params_fn rsa_settable_ctx_md_params; static OSSL_ITEM padding_item[] = { - { RSA_PKCS1_PADDING, "pkcs1" }, - { RSA_SSLV23_PADDING, "sslv23" }, - { RSA_NO_PADDING, "none" }, - { RSA_PKCS1_OAEP_PADDING, "oaep" }, /* Correct spelling first */ - { RSA_PKCS1_OAEP_PADDING, "oeap" }, - { RSA_X931_PADDING, "x931" }, - { RSA_PKCS1_PSS_PADDING, "pss" }, + { RSA_PKCS1_PADDING, OSSL_PKEY_RSA_PAD_MODE_PKCSV15 }, + { RSA_SSLV23_PADDING, OSSL_PKEY_RSA_PAD_MODE_SSLV23 }, + { RSA_NO_PADDING, OSSL_PKEY_RSA_PAD_MODE_NONE }, + { RSA_X931_PADDING, OSSL_PKEY_RSA_PAD_MODE_X931 }, + { RSA_PKCS1_PSS_PADDING, OSSL_PKEY_RSA_PAD_MODE_PSS }, { 0, NULL } }; @@ -227,17 +225,22 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); int md_nid = rsa_get_md_nid(md); WPACKET pkt; + size_t mdname_len = strlen(mdname); if (md == NULL || md_nid == NID_undef || !rsa_check_padding(md_nid, ctx->pad_mode) - || !rsa_check_parameters(md, ctx)) { + || !rsa_check_parameters(md, ctx) + || mdname_len >= sizeof(ctx->mdname)) { if (md == NULL) ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, "%s could not be fetched", mdname); if (md_nid == NID_undef) ERR_raise_data(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED, "digest=%s", mdname); + if (mdname_len >= sizeof(ctx->mdname)) + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, + "%s exceeds name buffer length", mdname); EVP_MD_free(md); return 0; } @@ -254,7 +257,8 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, */ ctx->aid_len = 0; if (WPACKET_init_der(&pkt, ctx->aid_buf, sizeof(ctx->aid_buf)) - && DER_w_algorithmIdentifier_RSA_with(&pkt, -1, ctx->rsa, md_nid) + && DER_w_algorithmIdentifier_MDWithRSAEncryption(&pkt, -1, ctx->rsa, + md_nid) && WPACKET_finish(&pkt)) { WPACKET_get_total_written(&pkt, &ctx->aid_len); ctx->aid = WPACKET_get_curr(&pkt); @@ -273,6 +277,8 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, static int rsa_setup_mgf1_md(PROV_RSA_CTX *ctx, const char *mdname, const char *mdprops) { + size_t len; + if (mdprops == NULL) mdprops = ctx->propq; @@ -284,7 +290,12 @@ static int rsa_setup_mgf1_md(PROV_RSA_CTX *ctx, const char *mdname, "%s could not be fetched", mdname); return 0; } - OPENSSL_strlcpy(ctx->mgf1_mdname, mdname, sizeof(ctx->mgf1_mdname)); + len = OPENSSL_strlcpy(ctx->mgf1_mdname, mdname, sizeof(ctx->mgf1_mdname)); + if (len >= sizeof(ctx->mgf1_mdname)) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, + "%s exceeds name buffer length", mdname); + return 0; + } return 1; } @@ -320,6 +331,7 @@ static int rsa_signature_init(void *vprsactx, void *vrsa, int operation) int mgf1md_nid = rsa_pss_params_30_maskgenhashalg(pss); int min_saltlen = rsa_pss_params_30_saltlen(pss); const char *mdname, *mgf1mdname; + size_t len; mdname = rsa_oaeppss_nid2name(md_nid); mgf1mdname = rsa_oaeppss_nid2name(mgf1md_nid); @@ -336,9 +348,20 @@ static int rsa_signature_init(void *vprsactx, void *vrsa, int operation) return 0; } - strncpy(prsactx->mdname, mdname, sizeof(prsactx->mdname)); - strncpy(prsactx->mgf1_mdname, mgf1mdname, - sizeof(prsactx->mgf1_mdname)); + len = OPENSSL_strlcpy(prsactx->mdname, mdname, + sizeof(prsactx->mdname)); + if (len >= sizeof(prsactx->mdname)) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, + "hash algorithm name too long"); + return 0; + } + len = OPENSSL_strlcpy(prsactx->mgf1_mdname, mgf1mdname, + sizeof(prsactx->mgf1_mdname)); + if (len >= sizeof(prsactx->mgf1_mdname)) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, + "MGF1 hash algorithm name too long"); + return 0; + } prsactx->saltlen = min_saltlen; return rsa_setup_md(prsactx, mdname, prsactx->propq) @@ -914,25 +937,32 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) if (!OSSL_PARAM_set_int(p, prsactx->saltlen)) return 0; } else if (p->data_type == OSSL_PARAM_UTF8_STRING) { + const char *value = NULL; + switch (prsactx->saltlen) { case RSA_PSS_SALTLEN_DIGEST: - if (!OSSL_PARAM_set_utf8_string(p, "digest")) - return 0; + value = OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST; break; case RSA_PSS_SALTLEN_MAX: - if (!OSSL_PARAM_set_utf8_string(p, "max")) - return 0; + value = OSSL_PKEY_RSA_PSS_SALT_LEN_MAX; break; case RSA_PSS_SALTLEN_AUTO: - if (!OSSL_PARAM_set_utf8_string(p, "auto")) - return 0; + value = OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO; break; default: - if (BIO_snprintf(p->data, p->data_size, "%d", prsactx->saltlen) - <= 0) - return 0; - break; + { + int len = BIO_snprintf(p->data, p->data_size, "%d", + prsactx->saltlen); + + if (len <= 0) + return 0; + p->return_size = len; + break; + } } + if (value != NULL + && !OSSL_PARAM_set_utf8_string(p, value)) + return 0; } } @@ -1092,11 +1122,11 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) return 0; break; case OSSL_PARAM_UTF8_STRING: - if (strcmp(p->data, "digest") == 0) + if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_DIGEST) == 0) saltlen = RSA_PSS_SALTLEN_DIGEST; - else if (strcmp(p->data, "max") == 0) + else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_MAX) == 0) saltlen = RSA_PSS_SALTLEN_MAX; - else if (strcmp(p->data, "auto") == 0) + else if (strcmp(p->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO) == 0) saltlen = RSA_PSS_SALTLEN_AUTO; else saltlen = atoi(p->data); diff --git a/ssl/build.info b/ssl/build.info index 5d70dec6..dd38492c 100644 --- a/ssl/build.info +++ b/ssl/build.info @@ -27,5 +27,6 @@ SOURCE[../libssl]=\ ssl_asn1.c ssl_txt.c ssl_init.c ssl_conf.c ssl_mcnf.c \ bio_ssl.c ssl_err.c tls_srp.c t1_trce.c ssl_utst.c \ record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \ - statem/statem.c record/ssl3_record_tls13.c + statem/statem.c record/ssl3_record_tls13.c \ + ssl_quic.c statem/statem_quic.c DEFINE[../libssl]=$AESDEF diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index bceac720..fac3506b 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -303,8 +303,13 @@ int ssl3_read_n(SSL *s, size_t n, size_t max, int extend, int clearold, if (ret <= 0 && !BIO_should_retry(s->rbio) && BIO_eof(s->rbio)) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_READ_N, - SSL_R_UNEXPECTED_EOF_WHILE_READING); + if (s->options & SSL_OP_IGNORE_UNEXPECTED_EOF) { + SSL_set_shutdown(s, SSL_RECEIVED_SHUTDOWN); + s->s3.warn_alert = SSL_AD_CLOSE_NOTIFY; + } else { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_SSL3_READ_N, + SSL_R_UNEXPECTED_EOF_WHILE_READING); + } } } else { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_READ_N, @@ -940,6 +945,7 @@ int do_ssl3_write(SSL *s, int type, const unsigned char *buf, } if (SSL_TREAT_AS_TLS13(s) + && !BIO_get_ktls_send(s->wbio) && s->enc_write_ctx != NULL && (s->statem.enc_write_state != ENC_WRITE_STATE_WRITE_PLAIN_ALERTS || type != SSL3_RT_ALERT)) { diff --git a/ssl/record/ssl3_record.c b/ssl/record/ssl3_record.c index 8125df68..0a0889b4 100644 --- a/ssl/record/ssl3_record.c +++ b/ssl/record/ssl3_record.c @@ -977,6 +977,8 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) unsigned char padval; int imac_size; const EVP_CIPHER *enc; + int tlstree_enc = sending ? (s->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE) + : (s->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE); if (n_recs == 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, @@ -1156,6 +1158,27 @@ int tls1_enc(SSL *s, SSL3_RECORD *recs, size_t n_recs, int sending) } } + if (!SSL_IS_DTLS(s) && tlstree_enc) { + unsigned char *seq; + int decrement_seq = 0; + + /* + * When sending, seq is incremented after MAC calculation. + * So if we are in ETM mode, we use seq 'as is' in the ctrl-function. + * Otherwise we have to decrease it in the implementation + */ + if (sending && !SSL_WRITE_ETM(s)) + decrement_seq = 1; + + seq = sending ? RECORD_LAYER_get_write_sequence(&s->rlayer) + : RECORD_LAYER_get_read_sequence(&s->rlayer); + if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_TLSTREE, decrement_seq, seq) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS1_ENC, + ERR_R_INTERNAL_ERROR); + return -1; + } + } + /* TODO(size_t): Convert this call */ tmpr = EVP_Cipher(ds, recs[0].data, recs[0].input, (unsigned int)reclen[0]); @@ -1319,8 +1342,10 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) int i; EVP_MD_CTX *hmac = NULL, *mac_ctx; unsigned char header[13]; - int stream_mac = (sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) - : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM)); + int stream_mac = sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) + : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM); + int tlstree_mac = sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_TLSTREE) + : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_TLSTREE); int t; if (sending) { @@ -1348,6 +1373,11 @@ int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending) mac_ctx = hmac; } + if (!SSL_IS_DTLS(ssl) && tlstree_mac && EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_TLSTREE, 0, seq) <= 0) { + EVP_MD_CTX_free(hmac); + return 0; + } + if (SSL_IS_DTLS(ssl)) { unsigned char dtlsseq[8], *p = dtlsseq; diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 75e3ea87..279abaa9 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -17,7 +17,7 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) { - EVP_MD *md5; + EVP_MD *md5, *sha1; EVP_MD_CTX *m5; EVP_MD_CTX *s1; unsigned char buf[16], smd[SHA_DIGEST_LENGTH]; @@ -30,9 +30,10 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) #endif k = 0; md5 = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_MD5, "-fips"); + sha1 = EVP_MD_fetch(NULL, OSSL_DIGEST_NAME_SHA1, "-fips"); m5 = EVP_MD_CTX_new(); s1 = EVP_MD_CTX_new(); - if (md5 == NULL || m5 == NULL || s1 == NULL) { + if (md5 == NULL || sha1 == NULL || m5 == NULL || s1 == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_MALLOC_FAILURE); goto err; @@ -49,7 +50,7 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) for (j = 0; j < k; j++) buf[j] = c; c++; - if (!EVP_DigestInit_ex(s1, EVP_sha1(), NULL) + if (!EVP_DigestInit_ex(s1, sha1, NULL) || !EVP_DigestUpdate(s1, buf, k) || !EVP_DigestUpdate(s1, s->session->master_key, s->session->master_key_length) @@ -87,6 +88,7 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) EVP_MD_CTX_free(m5); EVP_MD_CTX_free(s1); EVP_MD_free(md5); + EVP_MD_free(sha1); return ret; } diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 70802a45..76b188f2 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -2741,6 +2741,38 @@ static SSL_CIPHER ssl3_ciphers[] = { 0, 0, }, + { + 1, + "GOST2012-KUZNYECHIK-KUZNYECHIKOMAC", + NULL, + 0x0300C100, + SSL_kGOST18, + SSL_aGOST12, + SSL_KUZNYECHIK, + SSL_KUZNYECHIKOMAC, + TLS1_2_VERSION, TLS1_2_VERSION, + 0, 0, + SSL_HIGH, + SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_TLSTREE, + 256, + 256, + }, + { + 1, + "GOST2012-MAGMA-MAGMAOMAC", + NULL, + 0x0300C101, + SSL_kGOST18, + SSL_aGOST12, + SSL_MAGMA, + SSL_MAGMAOMAC, + TLS1_2_VERSION, TLS1_2_VERSION, + 0, 0, + SSL_HIGH, + SSL_HANDSHAKE_MAC_GOST12_256 | TLS1_PRF_GOST12_256 | TLS1_TLSTREE, + 256, + 256, + }, #endif /* OPENSSL_NO_GOST */ #ifndef OPENSSL_NO_IDEA @@ -4427,11 +4459,17 @@ int ssl3_get_req_cert_type(SSL *s, WPACKET *pkt) #ifndef OPENSSL_NO_GOST if (s->version >= TLS1_VERSION && (alg_k & SSL_kGOST)) - return WPACKET_put_bytes_u8(pkt, TLS_CT_GOST01_SIGN) - && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_SIGN) - && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_512_SIGN) - && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_LEGACY_SIGN) - && WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_LEGACY_512_SIGN); + if (!WPACKET_put_bytes_u8(pkt, TLS_CT_GOST01_SIGN) + || !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_SIGN) + || !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_512_SIGN) + || !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_LEGACY_SIGN) + || !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_LEGACY_512_SIGN)) + return 0; + + if (s->version >= TLS1_2_VERSION && (alg_k & SSL_kGOST18)) + if (!WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_SIGN) + || !WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_IANA_512_SIGN)) + return 0; #endif if ((s->version == SSL3_VERSION) && (alg_k & SSL_kDHE)) { diff --git a/ssl/s3_msg.c b/ssl/s3_msg.c index 7c021c17..812c9cca 100644 --- a/ssl/s3_msg.c +++ b/ssl/s3_msg.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -79,6 +79,16 @@ int ssl3_dispatch_alert(SSL *s) s->s3.alert_dispatch = 0; alertlen = 2; +#ifndef OPENSSL_NO_QUIC + if (SSL_IS_QUIC(s)) { + if (!s->quic_method->send_alert(s, s->quic_write_level, + s->s3.send_alert[1])) { + SSLerr(SSL_F_SSL3_DISPATCH_ALERT, SSL_R_INTERNAL_ERROR); + return 0; + } + i = 1; + } else +#endif i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3.send_alert[0], &alertlen, 1, 0, &written); if (i <= 0) { diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 44225752..20e59d02 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -47,8 +47,10 @@ DEFINE_STACK_OF_CONST(SSL_CIPHER) #define SSL_ENC_CHACHA_IDX 19 #define SSL_ENC_ARIA128GCM_IDX 20 #define SSL_ENC_ARIA256GCM_IDX 21 -#define SSL_ENC_CHACHA20_D_IDX 22 -#define SSL_ENC_NUM_IDX 23 +#define SSL_ENC_MAGMA_IDX 22 +#define SSL_ENC_KUZNYECHIK_IDX 23 +#define SSL_ENC_CHACHA20_D_IDX 24 +#define SSL_ENC_NUM_IDX 25 /* NB: make sure indices in these tables match values above */ @@ -81,7 +83,9 @@ static const ssl_cipher_table ssl_cipher_table_cipher[SSL_ENC_NUM_IDX] = { {SSL_CHACHA20POLY1305, NID_chacha20_poly1305}, /* SSL_ENC_CHACHA_IDX 19 */ {SSL_ARIA128GCM, NID_aria_128_gcm}, /* SSL_ENC_ARIA128GCM_IDX 20 */ {SSL_ARIA256GCM, NID_aria_256_gcm}, /* SSL_ENC_ARIA256GCM_IDX 21 */ - {SSL_CHACHA20POLY1305_D, NID_chacha20_poly1305_draft}, /* SSL_ENC_CHACHA20POLY1305_IDX 22 */ + {SSL_MAGMA, NID_magma_ctr_acpkm}, /* SSL_ENC_MAGMA_IDX 22 */ + {SSL_KUZNYECHIK, NID_kuznyechik_ctr_acpkm}, /* SSL_ENC_KUZNYECHIK_IDX 23 */ + {SSL_CHACHA20POLY1305_D, NID_chacha20_poly1305_draft}, /* SSL_ENC_CHACHA20POLY1305_IDX 24 */ }; static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX]; @@ -116,7 +120,9 @@ static const ssl_cipher_table ssl_cipher_table_mac[SSL_MD_NUM_IDX] = { {SSL_GOST12_512, NID_id_GostR3411_2012_512}, /* SSL_MD_GOST12_512_IDX 8 */ {0, NID_md5_sha1}, /* SSL_MD_MD5_SHA1_IDX 9 */ {0, NID_sha224}, /* SSL_MD_SHA224_IDX 10 */ - {0, NID_sha512} /* SSL_MD_SHA512_IDX 11 */ + {0, NID_sha512}, /* SSL_MD_SHA512_IDX 11 */ + {SSL_MAGMAOMAC, NID_magma_mac}, /* sSL_MD_MAGMAOMAC_IDX */ + {SSL_KUZNYECHIKOMAC, NID_kuznyechik_mac} /* SSL_MD_KUZNYECHIKOMAC_IDX */ }; static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { @@ -134,6 +140,7 @@ static const ssl_cipher_table ssl_cipher_table_kx[] = { {SSL_kPSK, NID_kx_psk}, {SSL_kSRP, NID_kx_srp}, {SSL_kGOST, NID_kx_gost}, + {SSL_kGOST18, NID_kx_gost18}, {SSL_kANY, NID_kx_any} }; @@ -177,8 +184,8 @@ static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef, /* GOST2012_512 */ EVP_PKEY_HMAC, - /* MD5/SHA1, SHA224, SHA512 */ - NID_undef, NID_undef, NID_undef + /* MD5/SHA1, SHA224, SHA512, MAGMAOMAC, KUZNYECHIKOMAC */ + NID_undef, NID_undef, NID_undef, NID_undef, NID_undef }; static size_t ssl_mac_secret_size[SSL_MD_NUM_IDX]; @@ -235,6 +242,7 @@ static const SSL_CIPHER cipher_aliases[] = { {0, SSL_TXT_kDHEPSK, NULL, 0, SSL_kDHEPSK}, {0, SSL_TXT_kSRP, NULL, 0, SSL_kSRP}, {0, SSL_TXT_kGOST, NULL, 0, SSL_kGOST}, + {0, SSL_TXT_kGOST18, NULL, 0, SSL_kGOST18}, /* server authentication aliases */ {0, SSL_TXT_aRSA, NULL, 0, 0, SSL_aRSA}, @@ -268,7 +276,8 @@ static const SSL_CIPHER cipher_aliases[] = { {0, SSL_TXT_IDEA, NULL, 0, 0, 0, SSL_IDEA}, {0, SSL_TXT_SEED, NULL, 0, 0, 0, SSL_SEED}, {0, SSL_TXT_eNULL, NULL, 0, 0, 0, SSL_eNULL}, - {0, SSL_TXT_GOST, NULL, 0, 0, 0, SSL_eGOST2814789CNT | SSL_eGOST2814789CNT12}, + {0, SSL_TXT_GOST, NULL, 0, 0, 0, + SSL_eGOST2814789CNT | SSL_eGOST2814789CNT12 | SSL_MAGMA | SSL_KUZNYECHIK}, {0, SSL_TXT_AES128, NULL, 0, 0, 0, SSL_AES128 | SSL_AES128GCM | SSL_AES128CCM | SSL_AES128CCM8}, {0, SSL_TXT_AES256, NULL, 0, 0, 0, @@ -283,13 +292,13 @@ static const SSL_CIPHER cipher_aliases[] = { {0, SSL_TXT_CAMELLIA, NULL, 0, 0, 0, SSL_CAMELLIA}, {0, SSL_TXT_CHACHA20, NULL, 0, 0, 0, SSL_CHACHA20}, {0, SSL_TXT_CHACHA20_D, NULL, 0, 0, 0, SSL_CHACHA20POLY1305_D}, - {0, SSL_TXT_GOST2012_GOST8912_GOST8912, NULL, 0, 0, 0, SSL_eGOST2814789CNT12}, {0, SSL_TXT_ARIA, NULL, 0, 0, 0, SSL_ARIA}, {0, SSL_TXT_ARIA_GCM, NULL, 0, 0, 0, SSL_ARIA128GCM | SSL_ARIA256GCM}, {0, SSL_TXT_ARIA128, NULL, 0, 0, 0, SSL_ARIA128GCM}, {0, SSL_TXT_ARIA256, NULL, 0, 0, 0, SSL_ARIA256GCM}, + {0, SSL_TXT_CBC, NULL, 0, 0, 0, SSL_CBC}, /* MAC aliases */ {0, SSL_TXT_MD5, NULL, 0, 0, 0, 0, SSL_MD5}, @@ -430,24 +439,38 @@ int ssl_load_ciphers(void) * Check for presence of GOST 34.10 algorithms, and if they are not * present, disable appropriate auth and key exchange */ - ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac"); + ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id(SN_id_Gost28147_89_MAC); if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32; else disabled_mac_mask |= SSL_GOST89MAC; ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX] = - get_optional_pkey_id("gost-mac-12"); + get_optional_pkey_id(SN_gost_mac_12); if (ssl_mac_pkey_id[SSL_MD_GOST89MAC12_IDX]) ssl_mac_secret_size[SSL_MD_GOST89MAC12_IDX] = 32; else disabled_mac_mask |= SSL_GOST89MAC12; - if (!get_optional_pkey_id("gost2001")) + ssl_mac_pkey_id[SSL_MD_MAGMAOMAC_IDX] = + get_optional_pkey_id(SN_magma_mac); + if (ssl_mac_pkey_id[SSL_MD_MAGMAOMAC_IDX]) + ssl_mac_secret_size[SSL_MD_MAGMAOMAC_IDX] = 32; + else + disabled_mac_mask |= SSL_MAGMAOMAC; + + ssl_mac_pkey_id[SSL_MD_KUZNYECHIKOMAC_IDX] = + get_optional_pkey_id(SN_kuznyechik_mac); + if (ssl_mac_pkey_id[SSL_MD_KUZNYECHIKOMAC_IDX]) + ssl_mac_secret_size[SSL_MD_KUZNYECHIKOMAC_IDX] = 32; + else + disabled_mac_mask |= SSL_KUZNYECHIKOMAC; + + if (!get_optional_pkey_id(SN_id_GostR3410_2001)) disabled_auth_mask |= SSL_aGOST01 | SSL_aGOST12; - if (!get_optional_pkey_id("gost2012_256")) + if (!get_optional_pkey_id(SN_id_GostR3410_2012_256)) disabled_auth_mask |= SSL_aGOST12; - if (!get_optional_pkey_id("gost2012_512")) + if (!get_optional_pkey_id(SN_id_GostR3410_2012_512)) disabled_auth_mask |= SSL_aGOST12; /* * Disable GOST key exchange if no GOST signature algs are available * @@ -456,6 +479,9 @@ int ssl_load_ciphers(void) (SSL_aGOST01 | SSL_aGOST12)) disabled_mkey_mask |= SSL_kGOST; + if ((disabled_auth_mask & SSL_aGOST12) == SSL_aGOST12) + disabled_mkey_mask |= SSL_kGOST18; + return 1; } @@ -1778,6 +1804,9 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_kGOST: kx = "GOST"; break; + case SSL_kGOST18: + kx = "GOST18"; + break; case SSL_kANY: kx = "any"; break; @@ -1881,6 +1910,12 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) case SSL_eGOST2814789CNT12: enc = "GOST89(256)"; break; + case SSL_MAGMA: + enc = "MAGMA"; + break; + case SSL_KUZNYECHIK: + enc = "KUZNYECHIK"; + break; case SSL_CHACHA20POLY1305: enc = "CHACHA20/POLY1305(256)"; break; @@ -2276,3 +2311,35 @@ const char *OSSL_default_ciphersuites(void) #endif "TLS_AES_128_GCM_SHA256"; } + +int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *c) +{ + switch (c->algorithm2 & (0xFF << TLS1_PRF_DGST_SHIFT)) { + default: + break; + case TLS1_PRF_SHA1_MD5: /* TLS1_PRF */ + return NID_md5_sha1; + case TLS1_PRF_SHA256: + return NID_sha256; + case TLS1_PRF_SHA384: + return NID_sha384; + case TLS1_PRF_GOST94: + return NID_id_GostR3411_94_prf; + case TLS1_PRF_GOST12_256: + return NID_id_GostR3411_2012_256; + case TLS1_PRF_GOST12_512: + return NID_id_GostR3411_2012_512; + } + /* TLSv1.3 ciphers don't specify separate PRF */ + switch (c->algorithm2 & SSL_HANDSHAKE_MAC_MASK) { + default: + break; + case SSL_HANDSHAKE_MAC_MD5_SHA1: /* SSL_HANDSHAKE_MAC_DEFAULT */ + return NID_md5_sha1; + case SSL_HANDSHAKE_MAC_SHA256: + return NID_sha256; + case SSL_HANDSHAKE_MAC_SHA384: + return NID_sha384; + } + return NID_undef; +} diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 64f7577a..c4844d77 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -195,6 +195,7 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_EXTMS), "inconsistent extms"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INSUFFICIENT_SECURITY), "insufficient security"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INTERNAL_ERROR), "internal error"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_ALERT), "invalid alert"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CCS_MESSAGE), "invalid ccs message"}, @@ -543,6 +544,8 @@ static const ERR_STRING_DATA SSL_str_reasons[] = { {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_CIPHER_RETURNED), "wrong cipher returned"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_CURVE), "wrong curve"}, + {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED), + "wrong encryption level received"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"}, {ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_SIGNATURE_SIZE), diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 655a0276..f53013b6 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -852,6 +852,10 @@ SSL *SSL_new(SSL_CTX *ctx) s->job = NULL; +#ifndef OPENSSL_NO_QUIC + s->quic_method = ctx->quic_method; +#endif + #ifndef OPENSSL_NO_CT if (!SSL_set_ct_validation_callback(s, ctx->ct_validation_callback, ctx->ct_validation_callback_arg)) @@ -1287,6 +1291,18 @@ void SSL_free(SSL *s) OPENSSL_free(s->pha_context); EVP_MD_CTX_free(s->pha_dgst); +#ifndef OPENSSL_NO_QUIC + OPENSSL_free(s->ext.quic_transport_params); + OPENSSL_free(s->ext.peer_quic_transport_params); + while (s->quic_input_data_head != NULL) { + QUIC_DATA *qd; + + qd = s->quic_input_data_head; + s->quic_input_data_head = qd->next; + OPENSSL_free(qd); + } +#endif + sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free); sk_X509_NAME_pop_free(s->client_ca_names, X509_NAME_free); @@ -1863,6 +1879,12 @@ static int ssl_io_intern(void *vargs) int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes) { +#ifndef OPENSSL_NO_QUIC + if (SSL_IS_QUIC(s)) { + SSLerr(SSL_F_SSL_READ_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } +#endif if (s->handshake_func == NULL) { SSLerr(SSL_F_SSL_READ_INTERNAL, SSL_R_UNINITIALIZED); return -1; @@ -1995,6 +2017,12 @@ int SSL_get_early_data_status(const SSL *s) static int ssl_peek_internal(SSL *s, void *buf, size_t num, size_t *readbytes) { +#ifndef OPENSSL_NO_QUIC + if (SSL_IS_QUIC(s)) { + SSLerr(SSL_F_SSL_PEEK_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } +#endif if (s->handshake_func == NULL) { SSLerr(SSL_F_SSL_PEEK_INTERNAL, SSL_R_UNINITIALIZED); return -1; @@ -2055,6 +2083,12 @@ int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *readbytes) int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written) { +#ifndef OPENSSL_NO_QUIC + if (SSL_IS_QUIC(s)) { + SSLerr(SSL_F_SSL_WRITE_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } +#endif if (s->handshake_func == NULL) { SSLerr(SSL_F_SSL_WRITE_INTERNAL, SSL_R_UNINITIALIZED); return -1; @@ -3544,11 +3578,11 @@ void ssl_set_masks(SSL *s) #ifndef OPENSSL_NO_GOST if (ssl_has_cert(s, SSL_PKEY_GOST12_512)) { - mask_k |= SSL_kGOST; + mask_k |= SSL_kGOST | SSL_kGOST18; mask_a |= SSL_aGOST12; } if (ssl_has_cert(s, SSL_PKEY_GOST12_256)) { - mask_k |= SSL_kGOST; + mask_k |= SSL_kGOST | SSL_kGOST18; mask_a |= SSL_aGOST12; } if (ssl_has_cert(s, SSL_PKEY_GOST01)) { @@ -3782,6 +3816,11 @@ int SSL_get_error(const SSL *s, int i) } if (SSL_want_read(s)) { +#ifndef OPENSSL_NO_QUIC + if (SSL_IS_QUIC(s)) { + return SSL_ERROR_WANT_READ; + } +#endif bio = SSL_get_rbio(s); if (BIO_should_read(bio)) return SSL_ERROR_WANT_READ; @@ -4162,7 +4201,7 @@ EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) { - if ((s->session != NULL) && (s->session->cipher != NULL)) + if (s->session != NULL) return s->session->cipher; return NULL; } @@ -4390,7 +4429,6 @@ int SSL_CTX_load_verify_store(SSL_CTX *ctx, const char *CAstore) return X509_STORE_load_store(ctx->cert_store, CAstore); } -#ifndef OPENSSL_NO_DEPRECATED_3_0 int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath) { @@ -4402,7 +4440,6 @@ int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, return 0; return 1; } -#endif void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)) @@ -4692,11 +4729,18 @@ int SSL_CTX_set_block_padding(SSL_CTX *ctx, size_t block_size) return 1; } -void SSL_set_record_padding_callback(SSL *ssl, +int SSL_set_record_padding_callback(SSL *ssl, size_t (*cb) (SSL *ssl, int type, size_t len, void *arg)) { - ssl->record_padding_cb = cb; + BIO *b; + + b = SSL_get_wbio(ssl); + if (b == NULL || !BIO_get_ktls_send(b)) { + ssl->record_padding_cb = cb; + return 1; + } + return 0; } void SSL_set_record_padding_callback_arg(SSL *ssl, void *arg) diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 888503da..45577b4e 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -180,6 +180,8 @@ # define SSL_kRSAPSK 0x00000040U # define SSL_kECDHEPSK 0x00000080U # define SSL_kDHEPSK 0x00000100U +/* GOST KDF key exchange, draft-smyshlyaev-tls12-gost-suites */ +# define SSL_kGOST18 0x00000200U /* all PSK */ @@ -234,7 +236,9 @@ # define SSL_CHACHA20POLY1305 0x00080000U # define SSL_ARIA128GCM 0x00100000U # define SSL_ARIA256GCM 0x00200000U -# define SSL_CHACHA20POLY1305_D 0x00400000U +# define SSL_MAGMA 0x00400000U +# define SSL_KUZNYECHIK 0x00800000U +# define SSL_CHACHA20POLY1305_D 0x01000000U # define SSL_AESGCM (SSL_AES128GCM | SSL_AES256GCM) # define SSL_AESCCM (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8) @@ -243,6 +247,9 @@ # define SSL_CHACHA20 (SSL_CHACHA20POLY1305 | SSL_CHACHA20POLY1305_D) # define SSL_ARIAGCM (SSL_ARIA128GCM | SSL_ARIA256GCM) # define SSL_ARIA (SSL_ARIAGCM) +# define SSL_CBC (SSL_DES | SSL_3DES | SSL_RC2 | SSL_IDEA \ + | SSL_AES128 | SSL_AES256 | SSL_CAMELLIA128 \ + | SSL_CAMELLIA256 | SSL_SEED) /* Bits for algorithm_mac (symmetric authentication) */ @@ -257,6 +264,8 @@ # define SSL_GOST12_256 0x00000080U # define SSL_GOST89MAC12 0x00000100U # define SSL_GOST12_512 0x00000200U +# define SSL_MAGMAOMAC 0x00000400U +# define SSL_KUZNYECHIKOMAC 0x00000800U /* * When adding new digest in the ssl_ciph.c and increment SSL_MD_NUM_IDX make @@ -275,7 +284,9 @@ # define SSL_MD_MD5_SHA1_IDX 9 # define SSL_MD_SHA224_IDX 10 # define SSL_MD_SHA512_IDX 11 -# define SSL_MAX_DIGEST 12 +# define SSL_MD_MAGMAOMAC_IDX 12 +# define SSL_MD_KUZNYECHIKOMAC_IDX 13 +# define SSL_MAX_DIGEST 14 /* Bits for algorithm2 (handshake digests and other extra flags) */ @@ -304,6 +315,11 @@ * goes into algorithm2) */ # define TLS1_STREAM_MAC 0x10000 +/* + * TLSTREE cipher/mac key derivation from draft-smyshlyaev-tls12-gost-suites + * (currently this also goes into algorithm2) + */ +# define TLS1_TLSTREE 0x20000 # define SSL_STRONG_MASK 0x0000001FU # define SSL_DEFAULT_MASK 0X00000020U @@ -320,6 +336,13 @@ /* Flag used on OpenSSL ciphersuite ids to indicate they are for SSLv3+ */ # define SSL3_CK_CIPHERSUITE_FLAG 0x03000000 +/* Check if an SSL structure is using QUIC (which uses TLSv1.3) */ +# ifndef OPENSSL_NO_QUIC +# define SSL_IS_QUIC(s) (s->quic_method != NULL) +# else +# define SSL_IS_QUIC(s) 0 +# endif + /* Check if an SSL structure is using DTLS */ # define SSL_IS_DTLS(s) (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) @@ -720,6 +743,7 @@ typedef enum tlsext_index_en { TLSEXT_IDX_cryptopro_bug, TLSEXT_IDX_early_data, TLSEXT_IDX_certificate_authorities, + TLSEXT_IDX_quic_transport_params, TLSEXT_IDX_padding, TLSEXT_IDX_psk, /* Dummy index - must always be the last entry */ @@ -1147,11 +1171,26 @@ struct ssl_ctx_st { SSL_async_callback_fn async_cb; void *async_cb_arg; +#ifndef OPENSSL_NO_QUIC + const SSL_QUIC_METHOD *quic_method; +#endif + char *propq; }; typedef struct cert_pkey_st CERT_PKEY; +#ifndef OPENSSL_NO_QUIC +struct quic_data_st { + struct quic_data_st *next; + OSSL_ENCRYPTION_LEVEL level; + size_t offset; + size_t length; +}; +typedef struct quic_data_st QUIC_DATA; +int quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL level); +#endif + struct ssl_st { /* * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, @@ -1411,6 +1450,11 @@ struct ssl_st { unsigned char handshake_traffic_hash[EVP_MAX_MD_SIZE]; unsigned char client_app_traffic_secret[EVP_MAX_MD_SIZE]; unsigned char server_app_traffic_secret[EVP_MAX_MD_SIZE]; +# ifndef OPENSSL_NO_QUIC + unsigned char client_hand_traffic_secret[EVP_MAX_MD_SIZE]; + unsigned char server_hand_traffic_secret[EVP_MAX_MD_SIZE]; + unsigned char client_early_traffic_secret[EVP_MAX_MD_SIZE]; +# endif unsigned char exporter_master_secret[EVP_MAX_MD_SIZE]; unsigned char early_exporter_master_secret[EVP_MAX_MD_SIZE]; EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ @@ -1625,8 +1669,22 @@ struct ssl_st { * selected. */ int tick_identity; + +#ifndef OPENSSL_NO_QUIC + uint8_t *quic_transport_params; + size_t quic_transport_params_len; + uint8_t *peer_quic_transport_params; + size_t peer_quic_transport_params_len; +#endif } ext; +#ifndef OPENSSL_NO_QUIC + OSSL_ENCRYPTION_LEVEL quic_read_level; + OSSL_ENCRYPTION_LEVEL quic_write_level; + QUIC_DATA *quic_input_data_head; + QUIC_DATA *quic_input_data_tail; + const SSL_QUIC_METHOD *quic_method; +#endif /* * Parsed form of the ClientHello, kept around across client_hello_cb * calls. diff --git a/ssl/ssl_quic.c b/ssl/ssl_quic.c new file mode 100644 index 00000000..2d8accbd --- /dev/null +++ b/ssl/ssl_quic.c @@ -0,0 +1,285 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "ssl_local.h" +#include "internal/cryptlib.h" +#include "internal/refcount.h" + +#ifdef OPENSSL_NO_QUIC +NON_EMPTY_TRANSLATION_UNIT +#else + +int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params, + size_t params_len) +{ + uint8_t *tmp; + + if (params == NULL || params_len == 0) { + tmp = NULL; + params_len = 0; + } else { + tmp = OPENSSL_memdup(params, params_len); + if (tmp == NULL) + return 0; + } + + OPENSSL_free(ssl->ext.quic_transport_params); + ssl->ext.quic_transport_params = tmp; + ssl->ext.quic_transport_params_len = params_len; + return 1; +} + +void SSL_get_peer_quic_transport_params(const SSL *ssl, + const uint8_t **out_params, + size_t *out_params_len) +{ + *out_params = ssl->ext.peer_quic_transport_params; + *out_params_len = ssl->ext.peer_quic_transport_params_len; +} + +size_t SSL_quic_max_handshake_flight_len(const SSL *ssl, OSSL_ENCRYPTION_LEVEL level) +{ + /* + * Limits flights to 16K by default when there are no large + * (certificate-carrying) messages. + */ + static const size_t DEFAULT_FLIGHT_LIMIT = 16384; + + switch (level) { + case ssl_encryption_initial: + return DEFAULT_FLIGHT_LIMIT; + case ssl_encryption_early_data: + /* QUIC does not send EndOfEarlyData. */ + return 0; + case ssl_encryption_handshake: + if (ssl->server) { + /* + * Servers may receive Certificate message if configured to request + * client certificates. + */ + if ((ssl->verify_mode & SSL_VERIFY_PEER) + && ssl->max_cert_list > DEFAULT_FLIGHT_LIMIT) + return ssl->max_cert_list; + } else { + /* + * Clients may receive both Certificate message and a CertificateRequest + * message. + */ + if (2*ssl->max_cert_list > DEFAULT_FLIGHT_LIMIT) + return 2 * ssl->max_cert_list; + } + return DEFAULT_FLIGHT_LIMIT; + case ssl_encryption_application: + return DEFAULT_FLIGHT_LIMIT; + } + + return 0; +} + +OSSL_ENCRYPTION_LEVEL SSL_quic_read_level(const SSL *ssl) +{ + return ssl->quic_read_level; +} + +OSSL_ENCRYPTION_LEVEL SSL_quic_write_level(const SSL *ssl) +{ + return ssl->quic_write_level; +} + +int SSL_provide_quic_data(SSL *ssl, OSSL_ENCRYPTION_LEVEL level, + const uint8_t *data, size_t len) +{ + size_t l; + + if (!SSL_IS_QUIC(ssl)) { + SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + /* Level can be different than the current read, but not less */ + if (level < ssl->quic_read_level + || (ssl->quic_input_data_tail != NULL && level < ssl->quic_input_data_tail->level)) { + SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED); + return 0; + } + + /* Split the QUIC messages up, if necessary */ + while (len > 0) { + QUIC_DATA *qd; + const uint8_t *p = data + 1; + + /* Check for an incomplete block */ + qd = ssl->quic_input_data_tail; + if (qd != NULL) { + l = qd->length - qd->offset; + if (l != 0) { + /* we still need to copy `l` bytes into the last data block */ + if (l > len) + l = len; + memcpy((char*)(qd+1) + qd->offset, data, l); + qd->offset += l; + len -= l; + data += l; + continue; + } + } + + n2l3(p, l); + l += SSL3_HM_HEADER_LENGTH; + + qd = OPENSSL_zalloc(sizeof(QUIC_DATA) + l); + if (qd == NULL) { + SSLerr(SSL_F_SSL_PROVIDE_QUIC_DATA, SSL_R_INTERNAL_ERROR); + return 0; + } + + qd->next = NULL; + qd->length = l; + qd->level = level; + /* partial data received? */ + if (l > len) + l = len; + qd->offset = l; + + memcpy((void*)(qd + 1), data, l); + if (ssl->quic_input_data_tail != NULL) + ssl->quic_input_data_tail->next = qd; + else + ssl->quic_input_data_head = qd; + ssl->quic_input_data_tail = qd; + + data += l; + len -= l; + } + + return 1; +} + +int SSL_CTX_set_quic_method(SSL_CTX *ctx, const SSL_QUIC_METHOD *quic_method) +{ + switch (ctx->method->version) { + case DTLS1_VERSION: + case DTLS1_2_VERSION: + case DTLS_ANY_VERSION: + case DTLS1_BAD_VER: + return 0; + default: + break; + } + ctx->quic_method = quic_method; + ctx->options &= ~SSL_OP_ENABLE_MIDDLEBOX_COMPAT; + return 1; +} + +int SSL_set_quic_method(SSL *ssl, const SSL_QUIC_METHOD *quic_method) +{ + switch (ssl->method->version) { + case DTLS1_VERSION: + case DTLS1_2_VERSION: + case DTLS_ANY_VERSION: + case DTLS1_BAD_VER: + return 0; + default: + break; + } + ssl->quic_method = quic_method; + ssl->options &= ~SSL_OP_ENABLE_MIDDLEBOX_COMPAT; + return 1; +} + +int quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL level) +{ + uint8_t *c2s_secret = NULL; + uint8_t *s2c_secret = NULL; + size_t len; + const EVP_MD *md; + + if (!SSL_IS_QUIC(ssl)) + return 1; + + /* secrets from the POV of the client */ + switch (level) { + case ssl_encryption_early_data: + c2s_secret = ssl->client_early_traffic_secret; + break; + case ssl_encryption_handshake: + c2s_secret = ssl->client_hand_traffic_secret; + s2c_secret = ssl->server_hand_traffic_secret; + break; + case ssl_encryption_application: + c2s_secret = ssl->client_app_traffic_secret; + s2c_secret = ssl->server_app_traffic_secret; + break; + default: + return 1; + } + + md = ssl_handshake_md(ssl); + if (md == NULL) { + /* May not have selected cipher, yet */ + const SSL_CIPHER *c = NULL; + + if (ssl->session != NULL) + c = SSL_SESSION_get0_cipher(ssl->session); + else if (ssl->psksession != NULL) + c = SSL_SESSION_get0_cipher(ssl->psksession); + + if (c != NULL) + md = SSL_CIPHER_get_handshake_digest(c); + } + + if ((len = EVP_MD_size(md)) <= 0) { + SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_SET_ENCRYPTION_SECRETS, + ERR_R_INTERNAL_ERROR); + return 0; + } + + if (ssl->server) { + if (!ssl->quic_method->set_encryption_secrets(ssl, level, c2s_secret, + s2c_secret, len)) { + SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_SET_ENCRYPTION_SECRETS, + ERR_R_INTERNAL_ERROR); + return 0; + } + } else { + if (!ssl->quic_method->set_encryption_secrets(ssl, level, s2c_secret, + c2s_secret, len)) { + SSLfatal(ssl, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_SET_ENCRYPTION_SECRETS, + ERR_R_INTERNAL_ERROR); + return 0; + } + } + + return 1; +} + +int SSL_process_quic_post_handshake(SSL *ssl) +{ + int ret; + + if (SSL_in_init(ssl) || !SSL_IS_QUIC(ssl)) { + SSLerr(SSL_F_SSL_PROCESS_QUIC_POST_HANDSHAKE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + ossl_statem_set_in_init(ssl, 1); + ret = ssl->handshake_func(ssl); + ossl_statem_set_in_init(ssl, 0); + + if (ret <= 0) + return 0; + return 1; +} + +int SSL_is_quic(SSL* ssl) +{ + return SSL_IS_QUIC(ssl); +} + +#endif diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 7a699747..3df32b72 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -1115,7 +1115,7 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr else #endif /* check that key <-> cert match */ - if (EVP_PKEY_cmp(pubkey, privatekey) != 1) { + if (EVP_PKEY_eq(pubkey, privatekey) != 1) { SSLerr(SSL_F_SSL_SET_CERT_AND_KEY, SSL_R_PRIVATE_KEY_MISMATCH); goto out; } diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 3c023486..be04efc8 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -56,6 +56,10 @@ static int final_sig_algs(SSL *s, unsigned int context, int sent); static int final_early_data(SSL *s, unsigned int context, int sent); static int final_maxfragmentlen(SSL *s, unsigned int context, int sent); static int init_post_handshake_auth(SSL *s, unsigned int context); +#ifndef OPENSSL_NO_QUIC +static int init_quic_transport_params(SSL *s, unsigned int context); +static int final_quic_transport_params(SSL *s, unsigned int context, int sent); +#endif /* Structure to define a built-in extension */ typedef struct extensions_definition_st { @@ -374,6 +378,19 @@ static const EXTENSION_DEFINITION ext_defs[] = { tls_construct_certificate_authorities, tls_construct_certificate_authorities, NULL, }, +#ifndef OPENSSL_NO_QUIC + { + TLSEXT_TYPE_quic_transport_parameters, + SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS + | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, + init_quic_transport_params, + tls_parse_ctos_quic_transport_params, tls_parse_stoc_quic_transport_params, + tls_construct_stoc_quic_transport_params, tls_construct_ctos_quic_transport_params, + final_quic_transport_params, + }, +#else + INVALID_EXTENSION, +#endif { /* Must be immediately before pre_shared_key */ TLSEXT_TYPE_padding, @@ -1169,13 +1186,26 @@ static int init_etm(SSL *s, unsigned int context) static int init_ems(SSL *s, unsigned int context) { - s->s3.flags &= ~TLS1_FLAGS_RECEIVED_EXTMS; + if (s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) { + s->s3.flags &= ~TLS1_FLAGS_RECEIVED_EXTMS; + s->s3.flags |= TLS1_FLAGS_REQUIRED_EXTMS; + } return 1; } static int final_ems(SSL *s, unsigned int context, int sent) { + /* + * Check extended master secret extension is not dropped on + * renegotiation. + */ + if (!(s->s3.flags & TLS1_FLAGS_RECEIVED_EXTMS) + && (s->s3.flags & TLS1_FLAGS_REQUIRED_EXTMS)) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_FINAL_EMS, + SSL_R_INCONSISTENT_EXTMS); + return 0; + } if (!s->server && s->hit) { /* * Check extended master secret extension is consistent with @@ -1701,3 +1731,15 @@ static int init_post_handshake_auth(SSL *s, unsigned int context) return 1; } + +#ifndef OPENSSL_NO_QUIC +static int init_quic_transport_params(SSL *s, unsigned int context) +{ + return 1; +} + +static int final_quic_transport_params(SSL *s, unsigned int context, int sent) +{ + return 1; +} +#endif diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index e3b51729..2055de38 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -648,21 +648,6 @@ static int add_key_share(SSL *s, WPACKET *pkt, unsigned int curve_id) /* SSLfatal() already called */ return 0; } - - /* - * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint() - * knows how to get a key from an encoded point with the help of - * a OSSL_SERIALIZER deserializer. We know that EVP_PKEY_get0() - * downgrades an EVP_PKEY to contain a legacy key. - * - * THIS IS TEMPORARY - */ - EVP_PKEY_get0(key_share_key); - if (EVP_PKEY_id(key_share_key) == EVP_PKEY_NONE) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_ADD_KEY_SHARE, - ERR_R_EC_LIB); - goto err; - } } /* Encode the public key. */ @@ -1273,7 +1258,28 @@ EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt, #endif } +#ifndef OPENSSL_NO_QUIC +/* SAME AS tls_construct_stoc_quic_transport_params() */ +EXT_RETURN tls_construct_ctos_quic_transport_params(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx) +{ + if (s->ext.quic_transport_params == NULL + || s->ext.quic_transport_params_len == 0) { + return EXT_RETURN_NOT_SENT; + } + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_quic_transport_parameters) + || !WPACKET_sub_memcpy_u16(pkt, s->ext.quic_transport_params, + s->ext.quic_transport_params_len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_CONSTRUCT_CTOS_QUIC_TRANSPORT_PARAMS, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } + + return EXT_RETURN_SENT; +} +#endif /* * Parse the server's renegotiation binding and abort if it's not right */ @@ -1926,22 +1932,6 @@ int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } - /* - * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint() - * knows how to get a key from an encoded point with the help of - * a OSSL_SERIALIZER deserializer. We know that EVP_PKEY_get0() - * downgrades an EVP_PKEY to contain a legacy key. - * - * THIS IS TEMPORARY - */ - EVP_PKEY_get0(skey); - if (EVP_PKEY_id(skey) == EVP_PKEY_NONE) { - EVP_PKEY_free(skey); - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_STOC_KEY_SHARE, - ERR_R_INTERNAL_ERROR); - return 0; - } - if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt), PACKET_remaining(&encoded_pt))) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_KEY_SHARE, @@ -1990,6 +1980,18 @@ int tls_parse_stoc_early_data(SSL *s, PACKET *pkt, unsigned int context, return 0; } +#ifndef OPENSSL_NO_QUIC + /* + * QUIC server must send 0xFFFFFFFF or it's a PROTOCOL_VIOLATION + * per draft-ietf-quic-tls-24 S4.5 + */ + if (s->quic_method != NULL && max_early_data != 0xFFFFFFFF) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_F_TLS_PARSE_STOC_EARLY_DATA, + SSL_R_INVALID_MAX_EARLY_DATA); + return 0; + } +#endif + s->session->ext.max_early_data = max_early_data; return 1; @@ -2077,3 +2079,22 @@ int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 1; } +#ifndef OPENSSL_NO_QUIC +/* SAME AS tls_parse_ctos_quic_transport_params() */ +int tls_parse_stoc_quic_transport_params(SSL *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) +{ + OPENSSL_free(s->ext.peer_quic_transport_params); + s->ext.peer_quic_transport_params = NULL; + s->ext.peer_quic_transport_params_len = 0; + + if (!PACKET_memdup(pkt, + &s->ext.peer_quic_transport_params, + &s->ext.peer_quic_transport_params_len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_PARSE_STOC_QUIC_TRANSPORT_PARAMS, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; +} +#endif diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index fc11a1c9..e13e8feb 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -715,21 +715,6 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, return 0; } - /* - * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint() - * knows how to get a key from an encoded point with the help of - * a OSSL_SERIALIZER deserializer. We know that EVP_PKEY_get0() - * downgrades an EVP_PKEY to contain a legacy key. - * - * THIS IS TEMPORARY - */ - EVP_PKEY_get0(s->s3.peer_tmp); - if (EVP_PKEY_id(s->s3.peer_tmp) == EVP_PKEY_NONE) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_KEY_SHARE, - ERR_R_INTERNAL_ERROR); - return 0; - } - s->s3.group_id = group_id; if (!EVP_PKEY_set1_tls_encodedpoint(s->s3.peer_tmp, @@ -1326,6 +1311,26 @@ int tls_parse_ctos_post_handshake_auth(SSL *s, PACKET *pkt, unsigned int context return 1; } +#ifndef OPENSSL_NO_QUIC +/* SAME AS tls_parse_stoc_quic_transport_params() */ +int tls_parse_ctos_quic_transport_params(SSL *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx) +{ + OPENSSL_free(s->ext.peer_quic_transport_params); + s->ext.peer_quic_transport_params = NULL; + s->ext.peer_quic_transport_params_len = 0; + + if (!PACKET_memdup(pkt, + &s->ext.peer_quic_transport_params, + &s->ext.peer_quic_transport_params_len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_PARSE_CTOS_QUIC_TRANSPORT_PARAMS, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; +} +#endif + /* * Add the server's renegotiation binding */ @@ -1647,7 +1652,9 @@ EXT_RETURN tls_construct_stoc_etm(SSL *s, WPACKET *pkt, unsigned int context, if (s->s3.tmp.new_cipher->algorithm_mac == SSL_AEAD || s->s3.tmp.new_cipher->algorithm_enc == SSL_RC4 || s->s3.tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT - || s->s3.tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12) { + || s->s3.tmp.new_cipher->algorithm_enc == SSL_eGOST2814789CNT12 + || s->s3.tmp.new_cipher->algorithm_enc == SSL_MAGMA + || s->s3.tmp.new_cipher->algorithm_enc == SSL_KUZNYECHIK) { s->ext.use_etm = 0; return EXT_RETURN_NOT_SENT; } @@ -1754,21 +1761,6 @@ EXT_RETURN tls_construct_stoc_key_share(SSL *s, WPACKET *pkt, return EXT_RETURN_FAIL; } - /* - * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint() - * knows how to get a key from an encoded point with the help of - * a OSSL_SERIALIZER deserializer. We know that EVP_PKEY_get0() - * downgrades an EVP_PKEY to contain a legacy key. - * - * THIS IS TEMPORARY - */ - EVP_PKEY_get0(skey); - if (EVP_PKEY_id(skey) == EVP_PKEY_NONE) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_KEY_SHARE, - ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - /* Generate encoding of server key */ encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(skey, &encodedPoint); if (encoded_pt_len == 0) { @@ -1966,12 +1958,20 @@ EXT_RETURN tls_construct_stoc_early_data(SSL *s, WPACKET *pkt, size_t chainidx) { if (context == SSL_EXT_TLS1_3_NEW_SESSION_TICKET) { - if (s->max_early_data == 0) + uint32_t max_early_data = s->max_early_data; + + if (max_early_data == 0) return EXT_RETURN_NOT_SENT; +#ifndef OPENSSL_NO_QUIC + /* QUIC server must always send 0xFFFFFFFF, per draft-ietf-quic-tls-24 S4.5 */ + if (s->quic_method != NULL) + max_early_data = 0xFFFFFFFF; +#endif + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data) || !WPACKET_start_sub_packet_u16(pkt) - || !WPACKET_put_bytes_u32(pkt, s->max_early_data) + || !WPACKET_put_bytes_u32(pkt, max_early_data) || !WPACKET_close(pkt)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_STOC_EARLY_DATA, ERR_R_INTERNAL_ERROR); @@ -2012,3 +2012,26 @@ EXT_RETURN tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context, return EXT_RETURN_SENT; } + +#ifndef OPENSSL_NO_QUIC +/* SAME AS tls_construct_ctos_quic_transport_params() */ +EXT_RETURN tls_construct_stoc_quic_transport_params(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx) +{ + if (s->ext.quic_transport_params == NULL + || s->ext.quic_transport_params_len == 0) { + return EXT_RETURN_NOT_SENT; + } + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_quic_transport_parameters) + || !WPACKET_sub_memcpy_u16(pkt, s->ext.quic_transport_params, + s->ext.quic_transport_params_len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, + SSL_F_TLS_CONSTRUCT_STOC_QUIC_TRANSPORT_PARAMS, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } + + return EXT_RETURN_SENT; +} +#endif diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c index 697e33e2..8072cf6b 100644 --- a/ssl/statem/statem.c +++ b/ssl/statem/statem.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2019 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -576,6 +576,10 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) * In DTLS we get the whole message in one go - header and body */ ret = dtls_get_message(s, &mt, &len); +#ifndef OPENSSL_NO_QUIC + } else if (SSL_IS_QUIC(s)) { + ret = quic_get_message(s, &mt, &len); +#endif } else { ret = tls_get_message_header(s, &mt); } @@ -605,8 +609,8 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) return SUB_STATE_ERROR; } - /* dtls_get_message already did this */ - if (!SSL_IS_DTLS(s) + /* dtls_get_message/quic_get_message already did this */ + if (!SSL_IS_DTLS(s) && !SSL_IS_QUIC(s) && s->s3.tmp.message_size > 0 && !grow_init_buf(s, s->s3.tmp.message_size + SSL3_HM_HEADER_LENGTH)) { @@ -619,8 +623,8 @@ static SUB_STATE_RETURN read_state_machine(SSL *s) /* Fall through */ case READ_STATE_BODY: - if (!SSL_IS_DTLS(s)) { - /* We already got this above for DTLS */ + if (!SSL_IS_DTLS(s) && !SSL_IS_QUIC(s)) { + /* We already got this above for DTLS & QUIC */ ret = tls_get_message_body(s, &len); if (ret == 0) { /* Could be non-blocking IO */ @@ -901,6 +905,15 @@ static SUB_STATE_RETURN write_state_machine(SSL *s) int statem_flush(SSL *s) { s->rwstate = SSL_WRITING; +#ifndef OPENSSL_NO_QUIC + if (SSL_IS_QUIC(s)) { + if (!s->quic_method->flush_flight(s)) { + /* NOTE: BIO_flush() does not generate an error */ + SSLerr(SSL_F_STATEM_FLUSH, ERR_R_INTERNAL_ERROR); + return 0; + } + } else +#endif if (BIO_flush(s->wbio) <= 0) { return 0; } diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 3e65f971..d34acba9 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -914,6 +914,14 @@ int ossl_statem_client_construct_message(SSL *s, WPACKET *pkt, break; case TLS_ST_CW_END_OF_EARLY_DATA: +#ifndef OPENSSL_NO_QUIC + /* QUIC does not send EndOfEarlyData, draft-ietf-quic-tls-24 S8.3 */ + if (s->quic_method != NULL) { + *confunc = NULL; + *mt = SSL3_MT_DUMMY; + break; + } +#endif *confunc = tls_construct_end_of_early_data; *mt = SSL3_MT_END_OF_EARLY_DATA; break; @@ -2231,21 +2239,6 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) return 0; } - /* - * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint() - * knows how to get a key from an encoded point with the help of - * a OSSL_SERIALIZER deserializer. We know that EVP_PKEY_get0() - * downgrades an EVP_PKEY to contain a legacy key. - * - * THIS IS TEMPORARY - */ - EVP_PKEY_get0(s->s3.peer_tmp); - if (EVP_PKEY_id(s->s3.peer_tmp) == EVP_PKEY_NONE) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_SKE_ECDHE, - ERR_R_INTERNAL_ERROR); - return 0; - } - if (!EVP_PKEY_set1_tls_encodedpoint(s->s3.peer_tmp, PACKET_data(&encoded_pt), PACKET_remaining(&encoded_pt))) { @@ -3148,21 +3141,6 @@ static int tls_construct_cke_ecdhe(SSL *s, WPACKET *pkt) goto err; } - /* - * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint() - * knows how to get a key from an encoded point with the help of - * a OSSL_SERIALIZER deserializer. We know that EVP_PKEY_get0() - * downgrades an EVP_PKEY to contain a legacy key. - * - * THIS IS TEMPORARY - */ - EVP_PKEY_get0(ckey); - if (EVP_PKEY_id(skey) == EVP_PKEY_NONE) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_ECDHE, - ERR_R_INTERNAL_ERROR); - goto err; - } - if (ssl_derive(s, ckey, skey, 0) == 0) { /* SSLfatal() already called */ goto err; @@ -3314,6 +3292,144 @@ static int tls_construct_cke_gost(SSL *s, WPACKET *pkt) #endif } +#ifndef OPENSSL_NO_GOST +int gost18_cke_cipher_nid(const SSL *s) +{ + if ((s->s3.tmp.new_cipher->algorithm_enc & SSL_MAGMA) != 0) + return NID_magma_ctr; + else if ((s->s3.tmp.new_cipher->algorithm_enc & SSL_KUZNYECHIK) != 0) + return NID_kuznyechik_ctr; + + return NID_undef; +} + +int gost_ukm(const SSL *s, unsigned char *dgst_buf) +{ + EVP_MD_CTX * hash = NULL; + unsigned int md_len; + const EVP_MD *md = EVP_get_digestbynid(NID_id_GostR3411_2012_256); + + if (md == NULL) + return 0; + + if ((hash = EVP_MD_CTX_new()) == NULL + || EVP_DigestInit(hash, md) <= 0 + || EVP_DigestUpdate(hash, s->s3.client_random, SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(hash, s->s3.server_random, SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestFinal_ex(hash, dgst_buf, &md_len) <= 0) { + EVP_MD_CTX_free(hash); + return 0; + } + + EVP_MD_CTX_free(hash); + return 1; +} +#endif + +static int tls_construct_cke_gost18(SSL *s, WPACKET *pkt) +{ +#ifndef OPENSSL_NO_GOST + /* GOST 2018 key exchange message creation */ + unsigned char rnd_dgst[32], tmp[255]; + EVP_PKEY_CTX *pkey_ctx = NULL; + X509 *peer_cert; + unsigned char *pms = NULL; + size_t pmslen = 0; + size_t msglen; + int cipher_nid = gost18_cke_cipher_nid(s); + + if (cipher_nid == NID_undef) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + ERR_R_INTERNAL_ERROR); + return 0; + } + + if (gost_ukm(s, rnd_dgst) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + ERR_R_INTERNAL_ERROR); + goto err; + } + + /* Pre-master secret - random bytes */ + pmslen = 32; + pms = OPENSSL_malloc(pmslen); + if (pms == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (RAND_bytes_ex(s->ctx->libctx, pms, (int)pmslen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + ERR_R_INTERNAL_ERROR); + goto err; + } + + /* Get server certificate PKEY and create ctx from it */ + peer_cert = s->session->peer; + if (peer_cert == NULL) { + SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); + return 0; + } + + pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, X509_get0_pubkey(peer_cert), s->ctx->propq); + if (pkey_ctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + ERR_R_MALLOC_FAILURE); + return 0; + } + + if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0 ) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + ERR_R_INTERNAL_ERROR); + goto err; + }; + + /* Reuse EVP_PKEY_CTRL_SET_IV, make choice in engine code */ + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, + EVP_PKEY_CTRL_SET_IV, 32, rnd_dgst) < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + SSL_R_LIBRARY_BUG); + goto err; + } + + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, + EVP_PKEY_CTRL_CIPHER, cipher_nid, NULL) < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + SSL_R_LIBRARY_BUG); + goto err; + } + + msglen = 255; + if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, pms, pmslen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + SSL_R_LIBRARY_BUG); + goto err; + } + + if (!WPACKET_memcpy(pkt, tmp, msglen)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + ERR_R_INTERNAL_ERROR); + goto err; + } + + EVP_PKEY_CTX_free(pkey_ctx); + s->s3.tmp.pms = pms; + s->s3.tmp.pmslen = pmslen; + + return 1; + err: + EVP_PKEY_CTX_free(pkey_ctx); + OPENSSL_clear_free(pms, pmslen); + return 0; +#else + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + ERR_R_INTERNAL_ERROR); + return 0; +#endif +} + static int tls_construct_cke_srp(SSL *s, WPACKET *pkt) { #ifndef OPENSSL_NO_SRP @@ -3370,6 +3486,9 @@ int tls_construct_client_key_exchange(SSL *s, WPACKET *pkt) } else if (alg_k & SSL_kGOST) { if (!tls_construct_cke_gost(s, pkt)) goto err; + } else if (alg_k & SSL_kGOST18) { + if (!tls_construct_cke_gost18(s, pkt)) + goto err; } else if (alg_k & SSL_kSRP) { if (!tls_construct_cke_srp(s, pkt)) goto err; diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 8fd68f81..a0bec9e2 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -48,9 +48,23 @@ int ssl3_do_write(SSL *s, int type) { int ret; size_t written = 0; +#ifndef OPENSSL_NO_QUIC + if (SSL_IS_QUIC(s) && type == SSL3_RT_HANDSHAKE) { + ret = s->quic_method->add_handshake_data(s, s->quic_write_level, + (const uint8_t*)&s->init_buf->data[s->init_off], + s->init_num); + if (!ret) { + ret = -1; + /* QUIC can't sent anything out sice the above failed */ + SSLerr(SSL_F_SSL3_DO_WRITE, SSL_R_INTERNAL_ERROR); + } else { + written = s->init_num; + } + } else +#endif + ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], + s->init_num, &written); - ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], - s->init_num, &written); if (ret < 0) return -1; if (type == SSL3_RT_HANDSHAKE) @@ -1183,6 +1197,7 @@ int tls_get_message_header(SSL *s, int *mt) do { while (s->init_num < SSL3_HM_HEADER_LENGTH) { + /* QUIC: either create a special ssl_read_bytes... or if/else this */ i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &recvd_type, &p[s->init_num], SSL3_HM_HEADER_LENGTH - s->init_num, diff --git a/ssl/statem/statem_local.h b/ssl/statem/statem_local.h index f4242fa2..78614635 100644 --- a/ssl/statem/statem_local.h +++ b/ssl/statem/statem_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -93,6 +93,7 @@ WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst); __owur int tls_get_message_header(SSL *s, int *mt); __owur int tls_get_message_body(SSL *s, size_t *len); __owur int dtls_get_message(SSL *s, int *mt, size_t *len); +__owur int quic_get_message(SSL *s, int *mt, size_t *len); /* Message construction and processing functions */ __owur int tls_process_initial_server_flight(SSL *s); @@ -153,6 +154,11 @@ __owur MSG_PROCESS_RETURN tls_process_next_proto(SSL *s, PACKET *pkt); __owur int tls_construct_new_session_ticket(SSL *s, WPACKET *pkt); MSG_PROCESS_RETURN tls_process_end_of_early_data(SSL *s, PACKET *pkt); +#ifndef OPENSSL_NO_GOST +/* These functions are used in GOST18 CKE, both for client and server */ +int gost18_cke_cipher_nid(const SSL *s); +int gost_ukm(const SSL *s, unsigned char *dgst_buf); +#endif /* Extension processing */ @@ -236,6 +242,10 @@ int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); int tls_parse_ctos_post_handshake_auth(SSL *, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); +#ifndef OPENSSL_NO_QUIC +int tls_parse_ctos_quic_transport_params(SSL *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); +#endif EXT_RETURN tls_construct_stoc_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, @@ -298,6 +308,11 @@ EXT_RETURN tls_construct_stoc_cryptopro_bug(SSL *s, WPACKET *pkt, size_t chainidx); EXT_RETURN tls_construct_stoc_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); +#ifndef OPENSSL_NO_QUIC +EXT_RETURN tls_construct_stoc_quic_transport_params(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx); +#endif /* Client Extension processing */ EXT_RETURN tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, unsigned int context, @@ -369,6 +384,11 @@ EXT_RETURN tls_construct_ctos_psk(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); +#ifndef OPENSSL_NO_QUIC +EXT_RETURN tls_construct_ctos_quic_transport_params(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx); +#endif int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); @@ -414,6 +434,10 @@ int tls_parse_stoc_cookie(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); int tls_parse_stoc_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx); +#ifndef OPENSSL_NO_QUIC +int tls_parse_stoc_quic_transport_params(SSL *s, PACKET *pkt, unsigned int context, + X509 *x, size_t chainidx); +#endif int tls_handle_alpn(SSL *s); diff --git a/ssl/statem/statem_quic.c b/ssl/statem/statem_quic.c new file mode 100644 index 00000000..d9c4f78e --- /dev/null +++ b/ssl/statem/statem_quic.c @@ -0,0 +1,109 @@ +/* + * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "../ssl_local.h" +#include "statem_local.h" +#include "internal/cryptlib.h" + +#ifdef OPENSSL_NO_QUIC +NON_EMPTY_TRANSLATION_UNIT +#else + +int quic_get_message(SSL *s, int *mt, size_t *len) +{ + size_t l; + QUIC_DATA *qd = s->quic_input_data_head; + uint8_t *p; + + if (qd == NULL || (qd->length - qd->offset) != 0) { + s->rwstate = SSL_READING; + *len = 0; + return 0; + } + + /* This is where we check for the proper level, not when data is given */ + if (qd->level != s->quic_read_level) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_GET_MESSAGE, + SSL_R_WRONG_ENCRYPTION_LEVEL_RECEIVED); + *len = 0; + return 0; + } + + if (!BUF_MEM_grow_clean(s->init_buf, (int)qd->length)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_GET_MESSAGE, + ERR_R_BUF_LIB); + *len = 0; + return 0; + } + + /* Copy buffered data */ + memcpy(s->init_buf->data, (void*)(qd + 1), qd->length); + s->init_buf->length = qd->length; + s->quic_input_data_head = qd->next; + if (s->quic_input_data_head == NULL) + s->quic_input_data_tail = NULL; + OPENSSL_free(qd); + + s->s3.tmp.message_type = *mt = *(s->init_buf->data); + p = (uint8_t*)s->init_buf->data + 1; + n2l3(p, l); + s->init_num = s->s3.tmp.message_size = *len = l; + s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; + + /* No CCS in QUIC/TLSv1.3? */ + if (*mt == SSL3_MT_CHANGE_CIPHER_SPEC) { + SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, + SSL_F_QUIC_GET_MESSAGE, + SSL_R_CCS_RECEIVED_EARLY); + *len = 0; + return 0; + } + + /* + * If receiving Finished, record MAC of prior handshake messages for + * Finished verification. + */ + if (*mt == SSL3_MT_FINISHED && !ssl3_take_mac(s)) { + /* SSLfatal() already called */ + *len = 0; + return 0; + } + + /* + * We defer feeding in the HRR until later. We'll do it as part of + * processing the message + * The TLsv1.3 handshake transcript stops at the ClientFinished + * message. + */ +#define SERVER_HELLO_RANDOM_OFFSET (SSL3_HM_HEADER_LENGTH + 2) + /* KeyUpdate and NewSessionTicket do not need to be added */ + if (!SSL_IS_TLS13(s) || (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET + && s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) { + if (s->s3.tmp.message_type != SSL3_MT_SERVER_HELLO + || s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE + || memcmp(hrrrandom, + s->init_buf->data + SERVER_HELLO_RANDOM_OFFSET, + SSL3_RANDOM_SIZE) != 0) { + if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, + s->init_num + SSL3_HM_HEADER_LENGTH)) { + /* SSLfatal() already called */ + *len = 0; + return 0; + } + } + } + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, + (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s, + s->msg_callback_arg); + + return 1; +} + +#endif diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index fa402725..68b7f4f3 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -77,7 +77,8 @@ static int ossl_statem_server13_read_transition(SSL *s, int mt) return 1; } break; - } else if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED) { + } else if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED + && !SSL_IS_QUIC(s)) { if (mt == SSL3_MT_END_OF_EARLY_DATA) { st->hand_state = TLS_ST_SR_END_OF_EARLY_DATA; return 1; @@ -2637,20 +2638,6 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) goto err; } - /* - * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint() - * knows how to get a key from an encoded point with the help of - * a OSSL_SERIALIZER deserializer. We know that EVP_PKEY_get0() - * downgrades an EVP_PKEY to contain a legacy key. - * - * THIS IS TEMPORARY - */ - EVP_PKEY_get0(s->s3.tmp.pkey); - if (EVP_PKEY_id(s->s3.tmp.pkey) == EVP_PKEY_NONE) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, 0, ERR_R_EC_LIB); - goto err; - } - /* Encode the public key. */ encodedlen = EVP_PKEY_get1_tls_encodedpoint(s->s3.tmp.pkey, &encodedPoint); @@ -3235,21 +3222,6 @@ static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt) goto err; } - /* - * TODO(3.0) Remove this when EVP_PKEY_get1_tls_encodedpoint() - * knows how to get a key from an encoded point with the help of - * a OSSL_SERIALIZER deserializer. We know that EVP_PKEY_get0() - * downgrades an EVP_PKEY to contain a legacy key. - * - * THIS IS TEMPORARY - */ - EVP_PKEY_get0(ckey); - if (EVP_PKEY_id(ckey) == EVP_PKEY_NONE) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE, - ERR_R_INTERNAL_ERROR); - goto err; - } - if (EVP_PKEY_set1_tls_encodedpoint(ckey, data, i) == 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_ECDHE, ERR_R_EC_LIB); @@ -3431,6 +3403,93 @@ static int tls_process_cke_gost(SSL *s, PACKET *pkt) #endif } +static int tls_process_cke_gost18(SSL *s, PACKET *pkt) +{ +#ifndef OPENSSL_NO_GOST + unsigned char rnd_dgst[32]; + EVP_PKEY_CTX *pkey_ctx = NULL; + EVP_PKEY *pk = NULL; + unsigned char premaster_secret[32]; + const unsigned char *start = NULL; + size_t outlen = 32, inlen = 0; + int ret = 0; + int cipher_nid = gost18_cke_cipher_nid(s); + + if (cipher_nid == NID_undef) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + ERR_R_INTERNAL_ERROR); + return 0; + } + + if (gost_ukm(s, rnd_dgst) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_GOST18, + ERR_R_INTERNAL_ERROR); + goto err; + } + + /* Get our certificate private key */ + pk = s->cert->pkeys[SSL_PKEY_GOST12_512].privatekey != NULL ? + s->cert->pkeys[SSL_PKEY_GOST12_512].privatekey : + s->cert->pkeys[SSL_PKEY_GOST12_256].privatekey; + if (pk == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18, + SSL_R_BAD_HANDSHAKE_STATE); + goto err; + } + + pkey_ctx = EVP_PKEY_CTX_new_from_pkey(s->ctx->libctx, pk, s->ctx->propq); + if (pkey_ctx == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18, + ERR_R_INTERNAL_ERROR); + goto err; + } + + /* Reuse EVP_PKEY_CTRL_SET_IV, make choice in engine code depending on size */ + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_DECRYPT, + EVP_PKEY_CTRL_SET_IV, 32, rnd_dgst) < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18, + SSL_R_LIBRARY_BUG); + goto err; + } + + if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_DECRYPT, + EVP_PKEY_CTRL_CIPHER, cipher_nid, NULL) < 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18, + SSL_R_LIBRARY_BUG); + goto err; + } + inlen = PACKET_remaining(pkt); + start = PACKET_data(pkt); + + if (EVP_PKEY_decrypt(pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18, + SSL_R_DECRYPTION_FAILED); + goto err; + } + /* Generate master secret */ + if (!ssl_generate_master_secret(s, premaster_secret, + sizeof(premaster_secret), 0)) { + /* SSLfatal() already called */ + goto err; + } + ret = 1; + + err: + EVP_PKEY_CTX_free(pkey_ctx); + return ret; +#else + /* Should never happen */ + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CKE_GOST18, + ERR_R_INTERNAL_ERROR); + return 0; +#endif +} + MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) { unsigned long alg_k; @@ -3481,6 +3540,11 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt) /* SSLfatal() already called */ goto err; } + } else if (alg_k & SSL_kGOST18) { + if (!tls_process_cke_gost18(s, pkt)) { + /* SSLfatal() already called */ + goto err; + } } else { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 4a836fa1..4ddee817 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -49,7 +49,7 @@ static int tls1_PRF(SSL *s, kdf = EVP_KDF_fetch(s->ctx->libctx, OSSL_KDF_NAME_TLS1_PRF, s->ctx->propq); if (kdf == NULL) goto err; - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); if (kctx == NULL) goto err; @@ -70,9 +70,9 @@ static int tls1_PRF(SSL *s, *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SEED, (void *)seed5, (size_t)seed5_len); *p = OSSL_PARAM_construct_end(); - if (EVP_KDF_CTX_set_params(kctx, params) + if (EVP_KDF_set_ctx_params(kctx, params) && EVP_KDF_derive(kctx, out, olen)) { - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return 1; } @@ -82,7 +82,7 @@ static int tls1_PRF(SSL *s, ERR_R_INTERNAL_ERROR); else SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return 0; } @@ -109,6 +109,7 @@ static int tls1_generate_key_block(SSL *s, unsigned char *km, size_t num) * record layer. If read_ahead is enabled, then this might be false and this * function will fail. */ +# ifndef OPENSSL_NO_KTLS_RX static int count_unprocessed_records(SSL *s) { SSL3_BUFFER *rbuf = RECORD_LAYER_get_rbuf(&s->rlayer); @@ -132,6 +133,7 @@ static int count_unprocessed_records(SSL *s) return count; } +# endif #endif int tls1_change_cipher_state(SSL *s, int which) @@ -154,10 +156,13 @@ int tls1_change_cipher_state(SSL *s, int which) # ifdef __FreeBSD__ struct tls_enable crypto_info; # else - struct tls12_crypto_info_aes_gcm_128 crypto_info; - unsigned char geniv[12]; + struct tls_crypto_info_all crypto_info; + unsigned char *rec_seq; + void *rl_sequence; +# ifndef OPENSSL_NO_KTLS_RX int count_unprocessed; int bit; +# endif # endif BIO *bio; #endif @@ -180,6 +185,11 @@ int tls1_change_cipher_state(SSL *s, int which) else s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; + if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE) + s->mac_flags |= SSL_MAC_FLAG_READ_MAC_TLSTREE; + else + s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_TLSTREE; + if (s->enc_read_ctx != NULL) { reuse_dd = 1; } else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL) { @@ -230,6 +240,11 @@ int tls1_change_cipher_state(SSL *s, int which) s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; else s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; + + if (s->s3.tmp.new_cipher->algorithm2 & TLS1_TLSTREE) + s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_TLSTREE; + else + s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_TLSTREE; if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) { reuse_dd = 1; } else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) { @@ -431,14 +446,12 @@ int tls1_change_cipher_state(SSL *s, int which) crypto_info.iv = iv; crypto_info.tls_vmajor = (s->version >> 8) & 0x000000ff; crypto_info.tls_vminor = (s->version & 0x000000ff); -# else - /* check that cipher is AES_GCM_128 */ - if (EVP_CIPHER_nid(c) != NID_aes_128_gcm - || EVP_CIPHER_mode(c) != EVP_CIPH_GCM_MODE - || EVP_CIPHER_key_length(c) != TLS_CIPHER_AES_GCM_128_KEY_SIZE) +# else /* !defined(__FreeBSD__) */ + /* check that cipher is supported */ + if (!ktls_check_supported_cipher(c, dd)) goto skip_ktls; - /* check version is 1.2 */ + /* check version */ if (s->version != TLS1_2_VERSION) goto skip_ktls; # endif @@ -469,25 +482,17 @@ int tls1_change_cipher_state(SSL *s, int which) } # ifndef __FreeBSD__ - memset(&crypto_info, 0, sizeof(crypto_info)); - crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128; - crypto_info.info.version = s->version; - - EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GET_IV, - EVP_GCM_TLS_FIXED_IV_LEN + EVP_GCM_TLS_EXPLICIT_IV_LEN, - geniv); - memcpy(crypto_info.iv, geniv + EVP_GCM_TLS_FIXED_IV_LEN, - TLS_CIPHER_AES_GCM_128_IV_SIZE); - memcpy(crypto_info.salt, geniv, TLS_CIPHER_AES_GCM_128_SALT_SIZE); - memcpy(crypto_info.key, key, EVP_CIPHER_key_length(c)); if (which & SSL3_CC_WRITE) - memcpy(crypto_info.rec_seq, &s->rlayer.write_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + rl_sequence = RECORD_LAYER_get_write_sequence(&s->rlayer); else - memcpy(crypto_info.rec_seq, &s->rlayer.read_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + rl_sequence = RECORD_LAYER_get_read_sequence(&s->rlayer); + + if (!ktls_configure_crypto(c, s->version, dd, rl_sequence, &crypto_info, + &rec_seq, iv, key)) + goto skip_ktls; if (which & SSL3_CC_READ) { +# ifndef OPENSSL_NO_KTLS_RX count_unprocessed = count_unprocessed_records(s); if (count_unprocessed < 0) goto skip_ktls; @@ -495,14 +500,17 @@ int tls1_change_cipher_state(SSL *s, int which) /* increment the crypto_info record sequence */ while (count_unprocessed) { for (bit = 7; bit >= 0; bit--) { /* increment */ - ++crypto_info.rec_seq[bit]; - if (crypto_info.rec_seq[bit] != 0) + ++rec_seq[bit]; + if (rec_seq[bit] != 0) break; } count_unprocessed--; } +# else + goto skip_ktls; +# endif } -# endif +# endif /* !__FreeBSD__ */ /* ktls works with user provided buffers directly */ if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) { @@ -615,6 +623,10 @@ size_t tls1_final_finish_mac(SSL *s, const char *str, size_t slen, { size_t hashlen; unsigned char hash[EVP_MAX_MD_SIZE]; + size_t finished_size = TLS1_FINISH_MAC_LENGTH; + + if (s->s3.tmp.new_cipher->algorithm_mkey & SSL_kGOST18) + finished_size = 32; if (!ssl3_digest_cached_records(s, 0)) { /* SSLfatal() already called */ @@ -628,12 +640,12 @@ size_t tls1_final_finish_mac(SSL *s, const char *str, size_t slen, if (!tls1_PRF(s, str, slen, hash, hashlen, NULL, 0, NULL, 0, NULL, 0, s->session->master_key, s->session->master_key_length, - out, TLS1_FINISH_MAC_LENGTH, 1)) { + out, finished_size, 1)) { /* SSLfatal() already called */ return 0; } OPENSSL_cleanse(hash, hashlen); - return TLS1_FINISH_MAC_LENGTH; + return finished_size; } int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 0988d972..fd16d3d9 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -621,7 +621,7 @@ static int tls1_check_pkey_comp(SSL *s, EVP_PKEY *pkey) */ return 1; } else { - int field_type = EC_METHOD_get_field_type(EC_GROUP_method_of(grp)); + int field_type = EC_GROUP_get_field_type(grp); if (field_type == NID_X9_62_prime_field) comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; @@ -1000,6 +1000,21 @@ static const SIGALG_LOOKUP *tls1_get_legacy_sigalg(const SSL *s, int idx) } } } + /* + * As both SSL_PKEY_GOST12_512 and SSL_PKEY_GOST12_256 indices can be used + * with new (aGOST12-only) ciphersuites, we should find out which one is available really. + */ + else if (idx == SSL_PKEY_GOST12_256) { + int real_idx; + + for (real_idx = SSL_PKEY_GOST12_512; real_idx >= SSL_PKEY_GOST12_256; + real_idx--) { + if (s->cert->pkeys[real_idx].privatekey != NULL) { + idx = real_idx; + break; + } + } + } } else { idx = s->cert->key - s->cert->pkeys; } @@ -1119,17 +1134,6 @@ int tls12_check_peer_sigalg(SSL *s, uint16_t sig, EVP_PKEY *pkey) int pkeyid = -1; const SIGALG_LOOKUP *lu; - /* - * TODO(3.0) Remove this when we adapted this function for provider - * side keys. We know that EVP_PKEY_get0() downgrades an EVP_PKEY - * to contain a legacy key. - * - * THIS IS TEMPORARY - */ - EVP_PKEY_get0(pkey); - if (EVP_PKEY_id(pkey) == EVP_PKEY_NONE) - return 0; - pkeyid = EVP_PKEY_id(pkey); /* Should never happen */ if (pkeyid == -1) @@ -1719,7 +1723,6 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) unsigned char sigalgstr[2]; int secbits; - /* See if sigalgs is recognised and if hash is enabled */ if (!tls1_lookup_md(lu, NULL)) return 0; /* DSA is not allowed in TLS 1.3 */ @@ -1767,7 +1770,7 @@ static int tls12_sigalg_allowed(const SSL *s, int op, const SIGALG_LOOKUP *lu) if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) continue; - if ((c->algorithm_mkey & SSL_kGOST) != 0) + if ((c->algorithm_mkey & (SSL_kGOST | SSL_kGOST18)) != 0) break; } if (i == num) @@ -2563,46 +2566,48 @@ int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) #ifndef OPENSSL_NO_DH DH *ssl_get_auto_dh(SSL *s) { + DH *dhp; + BIGNUM *p, *g; int dh_secbits = 80; - if (s->cert->dh_tmp_auto == 2) - return DH_get_1024_160(); - if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) { - if (s->s3.tmp.new_cipher->strength_bits == 256) - dh_secbits = 128; - else - dh_secbits = 80; - } else { - if (s->s3.tmp.cert == NULL) - return NULL; - dh_secbits = EVP_PKEY_security_bits(s->s3.tmp.cert->privatekey); + if (s->cert->dh_tmp_auto != 2) { + if (s->s3.tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aPSK)) { + if (s->s3.tmp.new_cipher->strength_bits == 256) + dh_secbits = 128; + else + dh_secbits = 80; + } else { + if (s->s3.tmp.cert == NULL) + return NULL; + dh_secbits = EVP_PKEY_security_bits(s->s3.tmp.cert->privatekey); + } } - if (dh_secbits >= 128) { - DH *dhp = DH_new(); - BIGNUM *p, *g; - if (dhp == NULL) - return NULL; - g = BN_new(); - if (g == NULL || !BN_set_word(g, 2)) { - DH_free(dhp); - BN_free(g); - return NULL; - } - if (dh_secbits >= 192) - p = BN_get_rfc3526_prime_8192(NULL); - else - p = BN_get_rfc3526_prime_3072(NULL); - if (p == NULL || !DH_set0_pqg(dhp, p, NULL, g)) { - DH_free(dhp); - BN_free(p); - BN_free(g); - return NULL; - } - return dhp; + dhp = DH_new(); + if (dhp == NULL) + return NULL; + g = BN_new(); + if (g == NULL || !BN_set_word(g, 2)) { + DH_free(dhp); + BN_free(g); + return NULL; } - if (dh_secbits >= 112) - return DH_get_2048_224(); - return DH_get_1024_160(); + if (dh_secbits >= 192) + p = BN_get_rfc3526_prime_8192(NULL); + else if (dh_secbits >= 152) + p = BN_get_rfc3526_prime_4096(NULL); + else if (dh_secbits >= 128) + p = BN_get_rfc3526_prime_3072(NULL); + else if (dh_secbits >= 112) + p = BN_get_rfc3526_prime_2048(NULL); + else + p = BN_get_rfc2409_prime_1024(NULL); + if (p == NULL || !DH_set0_pqg(dhp, p, NULL, g)) { + DH_free(dhp); + BN_free(p); + BN_free(g); + return NULL; + } + return dhp; } #endif @@ -3064,12 +3069,12 @@ SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx) } #endif mac = EVP_MAC_fetch(ctx->libctx, "HMAC", NULL); - if (mac == NULL || (ret->ctx = EVP_MAC_CTX_new(mac)) == NULL) + if (mac == NULL || (ret->ctx = EVP_MAC_new_ctx(mac)) == NULL) goto err; EVP_MAC_free(mac); return ret; err: - EVP_MAC_CTX_free(ret->ctx); + EVP_MAC_free_ctx(ret->ctx); EVP_MAC_free(mac); OPENSSL_free(ret); return NULL; @@ -3078,7 +3083,7 @@ SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx) void ssl_hmac_free(SSL_HMAC *ctx) { if (ctx != NULL) { - EVP_MAC_CTX_free(ctx->ctx); + EVP_MAC_free_ctx(ctx->ctx); #ifndef OPENSSL_NO_DEPRECATED_3_0 HMAC_CTX_free(ctx->old_ctx); #endif @@ -3106,7 +3111,7 @@ int ssl_hmac_init(SSL_HMAC *ctx, void *key, size_t len, char *md) *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, md, 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, key, len); *p = OSSL_PARAM_construct_end(); - if (EVP_MAC_CTX_set_params(ctx->ctx, params) && EVP_MAC_init(ctx->ctx)) + if (EVP_MAC_set_ctx_params(ctx->ctx, params) && EVP_MAC_init(ctx->ctx)) return 1; } #ifndef OPENSSL_NO_DEPRECATED_3_0 diff --git a/ssl/t1_trce.c b/ssl/t1_trce.c index 9f018ce1..58695a0b 100644 --- a/ssl/t1_trce.c +++ b/ssl/t1_trce.c @@ -444,6 +444,9 @@ static const ssl_trace_tbl ssl_ciphers_tbl[] = { {0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, {0xFF85, "LEGACY-GOST2012-GOST8912-GOST8912"}, {0xFF87, "GOST2012-NULL-GOST12"}, + {0xC100, "GOST2012-KUZNYECHIK-KUZNYECHIKOMAC"}, + {0xC101, "GOST2012-MAGMA-MAGMAOMAC"}, + {0xC102, "GOST2012-GOST8912-IANA"}, }; /* Compression methods */ @@ -593,7 +596,9 @@ static const ssl_trace_tbl ssl_ctype_tbl[] = { {20, "fortezza_dms"}, {64, "ecdsa_sign"}, {65, "rsa_fixed_ecdh"}, - {66, "ecdsa_fixed_ecdh"} + {66, "ecdsa_fixed_ecdh"}, + {67, "gost_sign256"}, + {68, "gost_sign512"}, }; static const ssl_trace_tbl ssl_psk_kex_modes_tbl[] = { @@ -665,7 +670,10 @@ static int ssl_print_random(BIO *bio, int indent, if (*pmsglen < 32) return 0; - tm = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + tm = ((unsigned int)p[0] << 24) + | ((unsigned int)p[1] << 16) + | ((unsigned int)p[2] << 8) + | (unsigned int)p[3]; p += 4; BIO_indent(bio, indent, 80); BIO_puts(bio, "Random:\n"); @@ -870,8 +878,10 @@ static int ssl_print_extension(BIO *bio, int indent, int server, break; if (extlen != 4) return 0; - max_early_data = (ext[0] << 24) | (ext[1] << 16) | (ext[2] << 8) - | ext[3]; + max_early_data = ((unsigned int)ext[0] << 24) + | ((unsigned int)ext[1] << 16) + | ((unsigned int)ext[2] << 8) + | (unsigned int)ext[3]; BIO_indent(bio, indent + 2, 80); BIO_printf(bio, "max_early_data=%u\n", max_early_data); break; @@ -1078,6 +1088,10 @@ static int ssl_get_keyex(const char **pname, const SSL *ssl) *pname = "GOST"; return SSL_kGOST; } + if (alg_k & SSL_kGOST18) { + *pname = "GOST18"; + return SSL_kGOST18; + } *pname = "UNKNOWN"; return 0; } @@ -1124,7 +1138,11 @@ static int ssl_print_client_keyex(BIO *bio, int indent, const SSL *ssl, ssl_print_hex(bio, indent + 2, "GostKeyTransportBlob", msg, msglen); msglen = 0; break; - + case SSL_kGOST18: + ssl_print_hex(bio, indent + 2, + "GOST-wrapped PreMasterSecret", msg, msglen); + msglen = 0; + break; } return !msglen; @@ -1366,7 +1384,10 @@ static int ssl_print_ticket(BIO *bio, int indent, const SSL *ssl, } if (msglen < 4) return 0; - tick_life = (msg[0] << 24) | (msg[1] << 16) | (msg[2] << 8) | msg[3]; + tick_life = ((unsigned int)msg[0] << 24) + | ((unsigned int)msg[1] << 16) + | ((unsigned int)msg[2] << 8) + | (unsigned int)msg[3]; msglen -= 4; msg += 4; BIO_indent(bio, indent + 2, 80); @@ -1377,7 +1398,10 @@ static int ssl_print_ticket(BIO *bio, int indent, const SSL *ssl, if (msglen < 4) return 0; ticket_age_add = - (msg[0] << 24) | (msg[1] << 16) | (msg[2] << 8) | msg[3]; + ((unsigned int)msg[0] << 24) + | ((unsigned int)msg[1] << 16) + | ((unsigned int)msg[2] << 8) + | (unsigned int)msg[3]; msglen -= 4; msg += 4; BIO_indent(bio, indent + 2, 80); diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index 19e763d1..af1b3b88 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -9,6 +9,8 @@ #include #include "ssl_local.h" +#include "internal/ktls.h" +#include "record/record_local.h" #include "internal/cryptlib.h" #include #include @@ -54,7 +56,7 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret, + 1 + EVP_MAX_MD_SIZE]; WPACKET pkt; - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); if (kctx == NULL) return 0; @@ -70,7 +72,7 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret, */ SSLerr(SSL_F_TLS13_HKDF_EXPAND, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); } - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return 0; } @@ -85,7 +87,7 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret, || !WPACKET_sub_memcpy_u8(&pkt, data, (data == NULL) ? 0 : datalen) || !WPACKET_get_total_written(&pkt, &hkdflabellen) || !WPACKET_finish(&pkt)) { - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); WPACKET_cleanup(&pkt); if (fatal) SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_HKDF_EXPAND, @@ -104,10 +106,10 @@ int tls13_hkdf_expand(SSL *s, const EVP_MD *md, const unsigned char *secret, hkdflabel, hkdflabellen); *p++ = OSSL_PARAM_construct_end(); - ret = EVP_KDF_CTX_set_params(kctx, params) <= 0 + ret = EVP_KDF_set_ctx_params(kctx, params) <= 0 || EVP_KDF_derive(kctx, out, outlen) <= 0; - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); if (ret != 0) { if (fatal) @@ -195,7 +197,7 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md, unsigned char preextractsec[EVP_MAX_MD_SIZE]; kdf = EVP_KDF_fetch(NULL, OSSL_KDF_NAME_HKDF, NULL); - kctx = EVP_KDF_CTX_new(kdf); + kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); if (kctx == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET, @@ -208,7 +210,7 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md, if (!ossl_assert(mdleni >= 0)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET, ERR_R_INTERNAL_ERROR); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return 0; } mdlen = (size_t)mdleni; @@ -231,7 +233,7 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md, SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET, ERR_R_INTERNAL_ERROR); EVP_MD_CTX_free(mctx); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return 0; } EVP_MD_CTX_free(mctx); @@ -242,7 +244,7 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md, sizeof(derived_secret_label) - 1, hash, mdlen, preextractsec, mdlen, 1)) { /* SSLfatal() already called */ - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return 0; } @@ -261,14 +263,14 @@ int tls13_generate_secret(SSL *s, const EVP_MD *md, prevsecretlen); *p++ = OSSL_PARAM_construct_end(); - ret = EVP_KDF_CTX_set_params(kctx, params) <= 0 + ret = EVP_KDF_set_ctx_params(kctx, params) <= 0 || EVP_KDF_derive(kctx, outsecret, mdlen) <= 0; if (ret != 0) SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_GENERATE_SECRET, ERR_R_INTERNAL_ERROR); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); if (prevsecret == preextractsec) OPENSSL_cleanse(preextractsec, mdlen); return ret == 0; @@ -386,9 +388,9 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, const unsigned char *hash, const unsigned char *label, size_t labellen, unsigned char *secret, - unsigned char *iv, EVP_CIPHER_CTX *ciph_ctx) + unsigned char *key, unsigned char *iv, + EVP_CIPHER_CTX *ciph_ctx) { - unsigned char key[EVP_MAX_KEY_LENGTH]; size_t ivlen, keylen, taglen; int hashleni = EVP_MD_size(md); size_t hashlen; @@ -397,14 +399,14 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, if (!ossl_assert(hashleni >= 0)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, ERR_R_EVP_LIB); - goto err; + return 0; } hashlen = (size_t)hashleni; if (!tls13_hkdf_expand(s, md, insecret, label, labellen, hash, hashlen, secret, hashlen, 1)) { /* SSLfatal() already called */ - goto err; + return 0; } /* TODO(size_t): convert me */ @@ -424,7 +426,7 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, } else { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, ERR_R_EVP_LIB); - goto err; + return 0; } if (algenc & (SSL_AES128CCM8 | SSL_AES256CCM8)) taglen = EVP_CCM8_TLS_TAG_LEN; @@ -438,7 +440,7 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, if (!tls13_derive_key(s, md, secret, key, keylen) || !tls13_derive_iv(s, md, secret, iv, ivlen)) { /* SSLfatal() already called */ - goto err; + return 0; } if (EVP_CipherInit_ex(ciph_ctx, ciph, NULL, NULL, NULL, sending) <= 0 @@ -448,37 +450,148 @@ static int derive_secret_key_and_iv(SSL *s, int sending, const EVP_MD *md, || EVP_CipherInit_ex(ciph_ctx, NULL, NULL, key, NULL, -1) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_DERIVE_SECRET_KEY_AND_IV, ERR_R_EVP_LIB); - goto err; + return 0; } return 1; - err: - OPENSSL_cleanse(key, sizeof(key)); - return 0; } +#ifdef CHARSET_EBCDIC +static const unsigned char client_early_traffic[] = {0x63, 0x20, 0x65, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; +static const unsigned char client_handshake_traffic[] = {0x63, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; +static const unsigned char client_application_traffic[] = {0x63, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; +static const unsigned char server_handshake_traffic[] = {0x73, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; +static const unsigned char server_application_traffic[] = {0x73, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; +static const unsigned char exporter_master_secret[] = {0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00}; +static const unsigned char resumption_master_secret[] = {0x72, 0x65, 0x73, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00}; +static const unsigned char early_exporter_master_secret[] = {0x65, 0x20, 0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00}; +#else +static const unsigned char client_early_traffic[] = "c e traffic"; +static const unsigned char client_handshake_traffic[] = "c hs traffic"; +static const unsigned char client_application_traffic[] = "c ap traffic"; +static const unsigned char server_handshake_traffic[] = "s hs traffic"; +static const unsigned char server_application_traffic[] = "s ap traffic"; +static const unsigned char exporter_master_secret[] = "exp master"; +static const unsigned char resumption_master_secret[] = "res master"; +static const unsigned char early_exporter_master_secret[] = "e exp master"; +#endif +#ifndef OPENSSL_NO_QUIC +static int quic_change_cipher_state(SSL *s, int which) +{ + unsigned char hash[EVP_MAX_MD_SIZE]; + size_t hashlen = 0; + int hashleni; + int ret = 0; + const EVP_MD *md = NULL; + OSSL_ENCRYPTION_LEVEL level = ssl_encryption_initial; + int is_handshake = ((which & SSL3_CC_HANDSHAKE) == SSL3_CC_HANDSHAKE); + int is_client_read = ((which & SSL3_CHANGE_CIPHER_CLIENT_READ) == SSL3_CHANGE_CIPHER_CLIENT_READ); + int is_server_write = ((which & SSL3_CHANGE_CIPHER_SERVER_WRITE) == SSL3_CHANGE_CIPHER_SERVER_WRITE); + int is_early = (which & SSL3_CC_EARLY); + + md = ssl_handshake_md(s); + if (!ssl3_digest_cached_records(s, 1) + || !ssl_handshake_hash(s, hash, sizeof(hash), &hashlen)) { + /* SSLfatal() already called */; + goto err; + } + + /* Ensure cast to size_t is safe */ + hashleni = EVP_MD_size(md); + if (!ossl_assert(hashleni >= 0)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_QUIC_CHANGE_CIPHER_STATE, + ERR_R_EVP_LIB); + goto err; + } + hashlen = (size_t)hashleni; + + if (is_client_read || is_server_write) { + if (is_handshake) { + level = ssl_encryption_handshake; + + if (!tls13_hkdf_expand(s, md, s->handshake_secret, client_handshake_traffic, + sizeof(client_handshake_traffic)-1, hash, hashlen, + s->client_hand_traffic_secret, hashlen, 1) + || !ssl_log_secret(s, CLIENT_HANDSHAKE_LABEL, s->client_hand_traffic_secret, hashlen) + || !tls13_derive_finishedkey(s, md, s->client_hand_traffic_secret, + s->client_finished_secret, hashlen) + || !tls13_hkdf_expand(s, md, s->handshake_secret, server_handshake_traffic, + sizeof(server_handshake_traffic)-1, hash, hashlen, + s->server_hand_traffic_secret, hashlen, 1) + || !ssl_log_secret(s, SERVER_HANDSHAKE_LABEL, s->server_hand_traffic_secret, hashlen) + || !tls13_derive_finishedkey(s, md, s->server_hand_traffic_secret, + s->server_finished_secret, hashlen)) { + /* SSLfatal() already called */ + goto err; + } + } else { + level = ssl_encryption_application; + + if (!tls13_hkdf_expand(s, md, s->master_secret, client_application_traffic, + sizeof(client_application_traffic)-1, hash, hashlen, + s->client_app_traffic_secret, hashlen, 1) + || !ssl_log_secret(s, CLIENT_APPLICATION_LABEL, s->client_app_traffic_secret, hashlen) + || !tls13_hkdf_expand(s, md, s->master_secret, server_application_traffic, + sizeof(server_application_traffic)-1, hash, hashlen, + s->server_app_traffic_secret, hashlen, 1) + || !ssl_log_secret(s, SERVER_APPLICATION_LABEL, s->server_app_traffic_secret, hashlen)) { + /* SSLfatal() already called */ + goto err; + } + } + if (!quic_set_encryption_secrets(s, level)) { + /* SSLfatal() already called */ + goto err; + } + if (s->server) + s->quic_write_level = level; + else + s->quic_read_level = level; + } else { + /* is_client_write || is_server_read */ + + if (is_early) { + level = ssl_encryption_early_data; + + if (!tls13_hkdf_expand(s, md, s->early_secret, client_early_traffic, + sizeof(client_early_traffic)-1, hash, hashlen, + s->client_early_traffic_secret, hashlen, 1) + || !ssl_log_secret(s, CLIENT_EARLY_LABEL, s->client_early_traffic_secret, hashlen) + || !quic_set_encryption_secrets(s, level)) { + /* SSLfatal() already called */ + goto err; + } + } else if (is_handshake) { + level = ssl_encryption_handshake; + } else { + level = ssl_encryption_application; + /* + * We also create the resumption master secret, but this time use the + * hash for the whole handshake including the Client Finished + */ + if (!tls13_hkdf_expand(s, md, s->master_secret, resumption_master_secret, + sizeof(resumption_master_secret)-1, hash, hashlen, + s->resumption_master_secret, hashlen, 1)) { + /* SSLfatal() already called */ + goto err; + } + } + + if (s->server) + s->quic_read_level = level; + else + s->quic_write_level = level; + } + + ret = 1; + err: + return ret; +} +#endif /* OPENSSL_NO_QUIC */ int tls13_change_cipher_state(SSL *s, int which) { -#ifdef CHARSET_EBCDIC - static const unsigned char client_early_traffic[] = {0x63, 0x20, 0x65, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; - static const unsigned char client_handshake_traffic[] = {0x63, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; - static const unsigned char client_application_traffic[] = {0x63, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; - static const unsigned char server_handshake_traffic[] = {0x73, 0x20, 0x68, 0x73, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; - static const unsigned char server_application_traffic[] = {0x73, 0x20, 0x61, 0x70, 0x20, /*traffic*/0x74, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x00}; - static const unsigned char exporter_master_secret[] = {0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00}; - static const unsigned char resumption_master_secret[] = {0x72, 0x65, 0x73, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00}; - static const unsigned char early_exporter_master_secret[] = {0x65, 0x20, 0x65, 0x78, 0x70, 0x20, /* master*/ 0x6D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x00}; -#else - static const unsigned char client_early_traffic[] = "c e traffic"; - static const unsigned char client_handshake_traffic[] = "c hs traffic"; - static const unsigned char client_application_traffic[] = "c ap traffic"; - static const unsigned char server_handshake_traffic[] = "s hs traffic"; - static const unsigned char server_application_traffic[] = "s ap traffic"; - static const unsigned char exporter_master_secret[] = "exp master"; - static const unsigned char resumption_master_secret[] = "res master"; - static const unsigned char early_exporter_master_secret[] = "e exp master"; -#endif unsigned char *iv; + unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char secret[EVP_MAX_MD_SIZE]; unsigned char hashval[EVP_MAX_MD_SIZE]; unsigned char *hash = hashval; @@ -492,6 +605,17 @@ int tls13_change_cipher_state(SSL *s, int which) int ret = 0; const EVP_MD *md = NULL; const EVP_CIPHER *cipher = NULL; +#if !defined(OPENSSL_NO_KTLS) && defined(OPENSSL_KTLS_TLS13) +# ifndef __FreeBSD__ + struct tls_crypto_info_all crypto_info; + BIO *bio; +# endif +#endif + +#ifndef OPENSSL_NO_QUIC + if (SSL_IS_QUIC(s)) + return quic_change_cipher_state(s, which); +#endif if (which & SSL3_CC_READ) { if (s->enc_read_ctx != NULL) { @@ -583,6 +707,7 @@ int tls13_change_cipher_state(SSL *s, int which) SSL_F_TLS13_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); goto err; } + cipher = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(sslcipher)); md = ssl_md(sslcipher->algorithm2); if (md == NULL || !EVP_DigestInit_ex(mdctx, md, NULL) @@ -694,9 +819,13 @@ int tls13_change_cipher_state(SSL *s, int which) } } + /* check whether cipher is known */ + if(!ossl_assert(cipher != NULL)) + goto err; + if (!derive_secret_key_and_iv(s, which & SSL3_CC_WRITE, md, cipher, - insecret, hash, label, labellen, secret, iv, - ciph_ctx)) { + insecret, hash, label, labellen, secret, key, + iv, ciph_ctx)) { /* SSLfatal() already called */ goto err; } @@ -737,8 +866,53 @@ int tls13_change_cipher_state(SSL *s, int which) s->statem.enc_write_state = ENC_WRITE_STATE_WRITE_PLAIN_ALERTS; else s->statem.enc_write_state = ENC_WRITE_STATE_VALID; +#ifndef OPENSSL_NO_KTLS +# if defined(OPENSSL_KTLS_TLS13) +# ifndef __FreeBSD__ + if (!(which & SSL3_CC_WRITE) || !(which & SSL3_CC_APPLICATION) + || ((which & SSL3_CC_WRITE) && (s->mode & SSL_MODE_NO_KTLS_TX))) + goto skip_ktls; + + /* ktls supports only the maximum fragment size */ + if (ssl_get_max_send_fragment(s) != SSL3_RT_MAX_PLAIN_LENGTH) + goto skip_ktls; + + /* ktls does not support record padding */ + if (s->record_padding_cb != NULL) + goto skip_ktls; + + /* check that cipher is supported */ + if (!ktls_check_supported_cipher(cipher, ciph_ctx)) + goto skip_ktls; + + bio = s->wbio; + + if (!ossl_assert(bio != NULL)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS13_CHANGE_CIPHER_STATE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + /* All future data will get encrypted by ktls. Flush the BIO or skip ktls */ + if (BIO_flush(bio) <= 0) + goto skip_ktls; + + /* configure kernel crypto structure */ + if (!ktls_configure_crypto(cipher, s->version, ciph_ctx, + RECORD_LAYER_get_write_sequence(&s->rlayer), + &crypto_info, NULL, iv, key)) + goto skip_ktls; + + /* ktls works with user provided buffers directly */ + if (BIO_set_ktls(bio, &crypto_info, which & SSL3_CC_WRITE)) + ssl3_release_write_buffer(s); +# endif +skip_ktls: +# endif +#endif ret = 1; err: + OPENSSL_cleanse(key, sizeof(key)); OPENSSL_cleanse(secret, sizeof(secret)); return ret; } @@ -752,6 +926,7 @@ int tls13_update_key(SSL *s, int sending) #endif const EVP_MD *md = ssl_handshake_md(s); size_t hashlen = EVP_MD_size(md); + unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char *insecret, *iv; unsigned char secret[EVP_MAX_MD_SIZE]; EVP_CIPHER_CTX *ciph_ctx; @@ -776,8 +951,8 @@ int tls13_update_key(SSL *s, int sending) if (!derive_secret_key_and_iv(s, sending, ssl_handshake_md(s), s->s3.tmp.new_sym_enc, insecret, NULL, application_traffic, - sizeof(application_traffic) - 1, secret, iv, - ciph_ctx)) { + sizeof(application_traffic) - 1, secret, key, + iv, ciph_ctx)) { /* SSLfatal() already called */ goto err; } @@ -787,6 +962,7 @@ int tls13_update_key(SSL *s, int sending) s->statem.enc_write_state = ENC_WRITE_STATE_VALID; ret = 1; err: + OPENSSL_cleanse(key, sizeof(key)); OPENSSL_cleanse(secret, sizeof(secret)); return ret; } diff --git a/test/CAss.cnf b/test/CAss.cnf deleted file mode 100644 index d63f8562..00000000 --- a/test/CAss.cnf +++ /dev/null @@ -1,69 +0,0 @@ - -#################################################################### -[ req ] -default_bits = 2048 -default_keyfile = keySS.pem -distinguished_name = req_distinguished_name -encrypt_rsa_key = no -default_md = sha1 - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = AU -countryName_value = AU - -organizationName = Organization Name (eg, company) -organizationName_value = Dodgy Brothers - -commonName = Common Name (eg, YOUR name) -commonName_value = Dodgy CA - -#################################################################### -[ ca ] -default_ca = CA_default # The default ca section - -#################################################################### -[ CA_default ] - -dir = ./demoCA # Where everything is kept -certs = $dir/certs # Where the issued certs are kept -crl_dir = $dir/crl # Where the issued crl are kept -database = $dir/index.txt # database index file. -#unique_subject = no # Set to 'no' to allow creation of - # several certificates with same subject. -new_certs_dir = $dir/newcerts # default place for new certs. - -certificate = $dir/cacert.pem # The CA certificate -serial = $dir/serial # The current serial number -crl = $dir/crl.pem # The current CRL -private_key = $dir/private/cakey.pem# The private key - -x509_extensions = v3_ca # The extensions to add to the cert - -name_opt = ca_default # Subject Name options -cert_opt = ca_default # Certificate field options - -default_days = 365 # how long to certify for -default_crl_days= 30 # how long before next CRL -default_md = md5 # which md to use. -preserve = no # keep passed DN ordering - -policy = policy_anything - -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -localityName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - - - -[ v3_ca ] -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid:always,issuer:always -basicConstraints = critical,CA:true,pathlen:1 -keyUsage = cRLSign, keyCertSign -issuerAltName=issuer:copy diff --git a/test/P1ss.cnf b/test/P1ss.cnf deleted file mode 100644 index 69baaaf8..00000000 --- a/test/P1ss.cnf +++ /dev/null @@ -1,31 +0,0 @@ - -#################################################################### -[ req ] -default_bits = 2048 -default_keyfile = keySS.pem -distinguished_name = req_distinguished_name -encrypt_rsa_key = no -default_md = sha256 - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = AU -countryName_value = AU - -organizationName = Organization Name (eg, company) -organizationName_value = Dodgy Brothers - -0.commonName = Common Name (eg, YOUR name) -0.commonName_value = Brother 1 - -1.commonName = Common Name (eg, YOUR name) -1.commonName_value = Brother 2 - -2.commonName = Common Name (eg, YOUR name) -2.commonName_value = Proxy 1 - -[ v3_proxy ] -basicConstraints=CA:FALSE -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB diff --git a/test/P2ss.cnf b/test/P2ss.cnf deleted file mode 100644 index 8d4f3c8a..00000000 --- a/test/P2ss.cnf +++ /dev/null @@ -1,39 +0,0 @@ - -#################################################################### -[ req ] -default_bits = 2048 -default_keyfile = keySS.pem -distinguished_name = req_distinguished_name -encrypt_rsa_key = no -default_md = sha256 - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = AU -countryName_value = AU - -organizationName = Organization Name (eg, company) -organizationName_value = Dodgy Brothers - -0.commonName = Common Name (eg, YOUR name) -0.commonName_value = Brother 1 - -1.commonName = Common Name (eg, YOUR name) -1.commonName_value = Brother 2 - -2.commonName = Common Name (eg, YOUR name) -2.commonName_value = Proxy 1 - -3.commonName = Common Name (eg, YOUR name) -3.commonName_value = Proxy 2 - -[ v3_proxy ] -basicConstraints=CA:FALSE -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -proxyCertInfo=critical,@proxy_ext - -[ proxy_ext ] -language=id-ppl-anyLanguage -pathlen=0 -policy=text:BC diff --git a/test/README.external b/test/README.external index 2f5423cb..8069ce8d 100644 --- a/test/README.external +++ b/test/README.external @@ -134,6 +134,28 @@ of your system. Certain tests may require more installed packages to run. No tests are expected to fail. +GOST engine test suite +=============== + +Much like the PYCA/Cryptography test suite, this builds and runs the GOST engine +tests against the local OpenSSL build. + +You will need a git checkout of gost-engine at the top level: + +$ git submodule update --init + +Then configure/build OpenSSL enabling external tests: + +$ ./config shared enable-external-tests +$ make + +GOST engine requires CMake for the build process. + +GOST engine tests will then be run as part of the rest of the suite, or can be +explicitly run (with more debugging): + +$ make test VERBOSE=1 TESTS=test_external_gost_engine + Updating test suites ==================== diff --git a/test/Uss.cnf b/test/Uss.cnf deleted file mode 100644 index 95ffb67d..00000000 --- a/test/Uss.cnf +++ /dev/null @@ -1,36 +0,0 @@ - -CN2 = Brother 2 - -#################################################################### -[ req ] -default_bits = 2048 -default_keyfile = keySS.pem -distinguished_name = req_distinguished_name -encrypt_rsa_key = no -default_md = sha256 -prompt = no - -[ req_distinguished_name ] -countryName = AU -organizationName = Dodgy Brothers -0.commonName = Brother 1 -1.commonName = $ENV::CN2 - -[ v3_ee ] -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer:always -basicConstraints = CA:false -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ee_dsa ] -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid:always -basicConstraints = CA:false -keyUsage = nonRepudiation, digitalSignature - -[ v3_ee_ec ] -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid:always -basicConstraints = CA:false -keyUsage = nonRepudiation, digitalSignature, keyAgreement - diff --git a/test/bad_dtls_test.c b/test/bad_dtls_test.c index bfbaa795..d2d6a6b4 100644 --- a/test/bad_dtls_test.c +++ b/test/bad_dtls_test.c @@ -305,14 +305,14 @@ static int send_record(BIO *rbio, unsigned char type, uint64_t seqnr, /* Append HMAC to data */ hmac = EVP_MAC_fetch(NULL, "HMAC", NULL); - ctx = EVP_MAC_CTX_new(hmac); + ctx = EVP_MAC_new_ctx(hmac); EVP_MAC_free(hmac); params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, "SHA1", 0); params[1] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, mac_key, 20); params[2] = OSSL_PARAM_construct_end(); - EVP_MAC_CTX_set_params(ctx, params); + EVP_MAC_set_ctx_params(ctx, params); EVP_MAC_init(ctx); EVP_MAC_update(ctx, epoch, 2); EVP_MAC_update(ctx, seq, 6); @@ -323,7 +323,7 @@ static int send_record(BIO *rbio, unsigned char type, uint64_t seqnr, EVP_MAC_update(ctx, lenbytes, 2); /* Length */ EVP_MAC_update(ctx, enc, len); /* Finally the data itself */ EVP_MAC_final(ctx, enc + len, NULL, SHA_DIGEST_LENGTH); - EVP_MAC_CTX_free(ctx); + EVP_MAC_free_ctx(ctx); /* Append padding bytes */ len += SHA_DIGEST_LENGTH; diff --git a/test/bioprinttest.c b/test/bioprinttest.c index 14f0bfe5..04d1613c 100644 --- a/test/bioprinttest.c +++ b/test/bioprinttest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -249,6 +249,7 @@ static int test_big(void) if (!TEST_int_eq(BIO_snprintf(buf, sizeof(buf), "%f\n", 2 * (double)ULONG_MAX), -1)) return 0; + return 1; } @@ -296,10 +297,20 @@ int setup_tests(void) * Replace testutil output routines. We do this to eliminate possible sources * of BIO error */ +BIO *bio_out = NULL; +BIO *bio_err = NULL; + +static int tap_level = 0; + void test_open_streams(void) { } +void test_adjust_streams_tap_level(int level) +{ + tap_level = level; +} + void test_close_streams(void) { } @@ -311,12 +322,12 @@ void test_close_streams(void) */ int test_vprintf_stdout(const char *fmt, va_list ap) { - return vfprintf(stdout, fmt, ap); + return fprintf(stdout, "%*s# ", tap_level, "") + vfprintf(stdout, fmt, ap); } int test_vprintf_stderr(const char *fmt, va_list ap) { - return vfprintf(stderr, fmt, ap); + return fprintf(stderr, "%*s# ", tap_level, "") + vfprintf(stderr, fmt, ap); } int test_flush_stdout(void) @@ -329,3 +340,23 @@ int test_flush_stderr(void) return fflush(stderr); } +int test_vprintf_tapout(const char *fmt, va_list ap) +{ + return fprintf(stdout, "%*s", tap_level, "") + vfprintf(stdout, fmt, ap); +} + +int test_vprintf_taperr(const char *fmt, va_list ap) +{ + return fprintf(stderr, "%*s", tap_level, "") + vfprintf(stderr, fmt, ap); +} + +int test_flush_tapout(void) +{ + return fflush(stdout); +} + +int test_flush_taperr(void) +{ + return fflush(stderr); +} + diff --git a/test/build.info b/test/build.info index 08e4815c..cf3d7fd3 100644 --- a/test/build.info +++ b/test/build.info @@ -20,7 +20,7 @@ IF[{- !$disabled{tests} -}] LIBS{noinst,has_main}=libtestutil.a SOURCE[libtestutil.a]=testutil/basic_output.c testutil/output_helpers.c \ testutil/driver.c testutil/tests.c testutil/cb.c testutil/stanza.c \ - testutil/format_output.c testutil/tap_bio.c \ + testutil/format_output.c \ testutil/test_cleanup.c testutil/main.c testutil/testutil_init.c \ testutil/options.c testutil/test_options.c \ testutil/apps_mem.c testutil/random.c $LIBAPPSSRC @@ -45,17 +45,17 @@ IF[{- !$disabled{tests} -}] dtlsv1listentest ct_test threadstest afalgtest d2i_test \ ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \ bio_callback_test bio_memleak_test param_build_test \ - bioprinttest sslapitest sslprovidertest dtlstest sslcorrupttest \ + bioprinttest sslapitest dtlstest sslcorrupttest \ bio_enc_test pkey_meth_test pkey_meth_kdf_test evp_kdf_test uitest \ cipherbytes_test \ asn1_encode_test asn1_decode_test asn1_string_table_test \ x509_time_test x509_dup_cert_test x509_check_cert_pkey_test \ recordlentest drbgtest drbg_cavs_test drbg_extra_test sslbuffertest \ time_offset_test pemtest ssl_cert_table_internal_test ciphername_test \ - http_test servername_test ocspapitest rsa_mp_test fatalerrtest tls13ccstest \ + servername_test ocspapitest rsa_mp_test fatalerrtest tls13ccstest \ sysdefaulttest errtest ssl_ctx_test gosttest \ context_internal_test aesgcmtest params_test evp_pkey_dparams_test \ - keymgmt_internal_test + keymgmt_internal_test hexstr_test SOURCE[confdump]=confdump.c INCLUDE[confdump]=../include ../apps/include @@ -140,11 +140,11 @@ IF[{- !$disabled{tests} -}] ENDIF SOURCE[evp_extra_test]=evp_extra_test.c - INCLUDE[evp_extra_test]=../include ../apps/include + INCLUDE[evp_extra_test]=../include ../apps/include ../crypto/include DEPEND[evp_extra_test]=../libcrypto libtestutil.a SOURCE[evp_fetch_prov_test]=evp_fetch_prov_test.c - INCLUDE[evp_fetch_prov_test]=../include ../apps/include + INCLUDE[evp_fetch_prov_test]=../include ../apps/include ../crypto/include DEPEND[evp_fetch_prov_test]=../libcrypto libtestutil.a IF[{- $disabled{fips} || !$target{dso_scheme} -}] DEFINE[evp_extra_test]=NO_FIPS_MODULE @@ -299,26 +299,14 @@ IF[{- !$disabled{tests} -}] INCLUDE[param_build_test]=../include ../apps/include DEPEND[param_build_test]=../libcrypto.a libtestutil.a - SOURCE[sslapitest]=sslapitest.c ssltestlib.c + SOURCE[sslapitest]=sslapitest.c ssltestlib.c filterprov.c INCLUDE[sslapitest]=../include ../apps/include .. DEPEND[sslapitest]=../libcrypto ../libssl libtestutil.a - SOURCE[sslprovidertest]=sslprovidertest.c ssltestlib.c - INCLUDE[sslprovidertest]=../include ../apps/include .. - DEPEND[sslprovidertest]=../libcrypto ../libssl libtestutil.a - SOURCE[ocspapitest]=ocspapitest.c INCLUDE[ocspapitest]=../include ../apps/include DEPEND[ocspapitest]=../libcrypto libtestutil.a - IF[{- !$disabled{sock} -}] - PROGRAMS{noinst}=http_test - ENDIF - - SOURCE[http_test]=http_test.c - INCLUDE[http_test]=../include ../apps/include - DEPEND[http_test]=../libcrypto libtestutil.a - SOURCE[dtlstest]=dtlstest.c ssltestlib.c INCLUDE[dtlstest]=../include ../apps/include DEPEND[dtlstest]=../libcrypto ../libssl libtestutil.a @@ -356,13 +344,13 @@ IF[{- !$disabled{tests} -}] DEPEND[recordlentest]=../libcrypto ../libssl libtestutil.a SOURCE[drbgtest]=drbgtest.c - INCLUDE[drbgtest]=../include ../apps/include + INCLUDE[drbgtest]=../include ../apps/include ../crypto/include DEPEND[drbgtest]=../libcrypto.a libtestutil.a SOURCE[drbg_cavs_test]=drbg_cavs_test.c drbg_cavs_data_ctr.c \ drbg_cavs_data_hash.c drbg_cavs_data_hmac.c - INCLUDE[drbg_cavs_test]=../include ../apps/include . .. + INCLUDE[drbg_cavs_test]=../include ../apps/include . .. ../crypto/include DEPEND[drbg_cavs_test]=../libcrypto libtestutil.a SOURCE[drbg_extra_test]=drbg_extra_test.c @@ -389,10 +377,6 @@ IF[{- !$disabled{tests} -}] INCLUDE[ciphername_test]=../include ../apps/include DEPEND[ciphername_test]=../libcrypto ../libssl libtestutil.a - SOURCE[http_test]=http_test.c - INCLUDE[http_test]=../include ../apps/include - DEPEND[http_test]=../libcrypto libtestutil.a - SOURCE[servername_test]=servername_test.c ssltestlib.c INCLUDE[servername_test]=../include ../apps/include DEPEND[servername_test]=../libcrypto ../libssl libtestutil.a @@ -414,7 +398,7 @@ IF[{- !$disabled{tests} -}] IF[{- !$disabled{shared} -}] PROGRAMS{noinst}=shlibloadtest SOURCE[shlibloadtest]=shlibloadtest.c - INCLUDE[shlibloadtest]=../include ../apps/include + INCLUDE[shlibloadtest]=../include ../apps/include ../crypto/include ENDIF # cipher_overhead_test uses internal symbols, so it must be linked with @@ -527,21 +511,24 @@ IF[{- !$disabled{tests} -}] IF[{- !$disabled{ec} -}] PROGRAMS{noinst}=ec_internal_test curve448_internal_test ENDIF + IF[{- !$disabled{cmac} -}] + PROGRAMS{noinst}=cmactest + ENDIF SOURCE[poly1305_internal_test]=poly1305_internal_test.c - INCLUDE[poly1305_internal_test]=.. ../include ../apps/include + INCLUDE[poly1305_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[poly1305_internal_test]=../libcrypto.a libtestutil.a SOURCE[chacha_internal_test]=chacha_internal_test.c - INCLUDE[chacha_internal_test]=.. ../include ../apps/include + INCLUDE[chacha_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[chacha_internal_test]=../libcrypto.a libtestutil.a SOURCE[asn1_internal_test]=asn1_internal_test.c - INCLUDE[asn1_internal_test]=.. ../include ../apps/include + INCLUDE[asn1_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[asn1_internal_test]=../libcrypto.a libtestutil.a SOURCE[modes_internal_test]=modes_internal_test.c - INCLUDE[modes_internal_test]=.. ../include ../apps/include + INCLUDE[modes_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[modes_internal_test]=../libcrypto.a libtestutil.a SOURCE[x509_internal_test]=x509_internal_test.c @@ -582,7 +569,7 @@ IF[{- !$disabled{tests} -}] DEPEND[ctype_internal_test]=../libcrypto.a libtestutil.a SOURCE[sparse_array_test]=sparse_array_test.c - INCLUDE[sparse_array_test]=../include ../apps/include + INCLUDE[sparse_array_test]=../crypto/include ../include ../apps/include DEPEND[sparse_array_test]=../libcrypto.a libtestutil.a SOURCE[dhtest]=dhtest.c @@ -593,16 +580,22 @@ IF[{- !$disabled{tests} -}] INCLUDE[hmactest]=../include ../apps/include DEPEND[hmactest]=../libcrypto.a libtestutil.a + IF[{- !$disabled{cmac} -}] + SOURCE[cmactest]=cmactest.c + INCLUDE[cmactest]=../include ../apps/include + DEPEND[cmactest]=../libcrypto.a libtestutil.a + ENDIF + SOURCE[siphash_internal_test]=siphash_internal_test.c - INCLUDE[siphash_internal_test]=.. ../include ../apps/include + INCLUDE[siphash_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[siphash_internal_test]=../libcrypto.a libtestutil.a SOURCE[sm2_internal_test]=sm2_internal_test.c - INCLUDE[sm2_internal_test]=../include ../apps/include + INCLUDE[sm2_internal_test]=../include ../apps/include ../crypto/include DEPEND[sm2_internal_test]=../libcrypto.a libtestutil.a SOURCE[sm4_internal_test]=sm4_internal_test.c - INCLUDE[sm4_internal_test]=.. ../include ../apps/include + INCLUDE[sm4_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[sm4_internal_test]=../libcrypto.a libtestutil.a SOURCE[destest]=destest.c @@ -622,7 +615,7 @@ IF[{- !$disabled{tests} -}] DEPEND[rc5test]=../libcrypto.a libtestutil.a SOURCE[ec_internal_test]=ec_internal_test.c - INCLUDE[ec_internal_test]=../include ../crypto/ec ../apps/include + INCLUDE[ec_internal_test]=../include ../crypto/ec ../apps/include ../crypto/include DEPEND[ec_internal_test]=../libcrypto.a libtestutil.a SOURCE[curve448_internal_test]=curve448_internal_test.c @@ -646,7 +639,7 @@ IF[{- !$disabled{tests} -}] DEPEND[bn_internal_test]=../libcrypto.a libtestutil.a SOURCE[asn1_dsa_internal_test]=asn1_dsa_internal_test.c - INCLUDE[asn1_dsa_internal_test]=.. ../include ../apps/include + INCLUDE[asn1_dsa_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[asn1_dsa_internal_test]=../libcrypto.a libtestutil.a SOURCE[keymgmt_internal_test]=keymgmt_internal_test.c @@ -681,6 +674,7 @@ IF[{- !$disabled{tests} -}] IF[{- !$disabled{shared} -}] PROGRAMS{noinst}=tls13secretstest SOURCE[tls13secretstest]=tls13secretstest.c + DEFINE[tls13secretstest]=OPENSSL_NO_KTLS SOURCE[tls13secretstest]= ../ssl/tls13_enc.c ../crypto/packet.c INCLUDE[tls13secretstest]=.. ../include ../apps/include DEPEND[tls13secretstest]=../libcrypto ../libssl libtestutil.a @@ -737,11 +731,21 @@ IF[{- !$disabled{tests} -}] DEPEND[]=provider_internal_test.cnf GENERATE[provider_internal_test.cnf]=provider_internal_test.cnf.in + PROGRAMS{noinst}=provider_fallback_test + SOURCE[provider_fallback_test]=provider_fallback_test.c + INCLUDE[provider_fallback_test]=../include ../apps/include + DEPEND[provider_fallback_test]=../libcrypto libtestutil.a + PROGRAMS{noinst}=params_test SOURCE[params_test]=params_test.c INCLUDE[params_test]=.. ../include ../apps/include DEPEND[params_test]=../libcrypto.a libtestutil.a + PROGRAMS{noinst}=hexstr_test + SOURCE[hexstr_test]=hexstr_test.c + INCLUDE[hexstr_test]=.. ../include ../apps/include + DEPEND[hexstr_test]=../libcrypto.a libtestutil.a + PROGRAMS{noinst}=namemap_internal_test SOURCE[namemap_internal_test]=namemap_internal_test.c INCLUDE[namemap_internal_test]=.. ../include ../apps/include diff --git a/test/ca-and-certs.cnf b/test/ca-and-certs.cnf new file mode 100644 index 00000000..598db2b6 --- /dev/null +++ b/test/ca-and-certs.cnf @@ -0,0 +1,90 @@ + +CN2 = Brother 2 + +#################################################################### +[ req ] +default_bits = 2048 +default_keyfile = keySS.pem +distinguished_name = req_distinguished_name +encrypt_rsa_key = no +default_md = sha1 + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_value = AU +organizationName = Organization Name (eg, company) +organizationName_value = Dodgy Brothers +commonName = Common Name (eg, YOUR name) +commonName_value = Dodgy CA + +#################################################################### +[ userreq ] +default_bits = 2048 +default_keyfile = keySS.pem +distinguished_name = user_dn +encrypt_rsa_key = no +default_md = sha256 +prompt = no + +[ user_dn ] +countryName = AU +organizationName = Dodgy Brothers +0.commonName = Brother 1 +1.commonName = $ENV::CN2 + +[ v3_ee ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +basicConstraints = CA:false +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ee_dsa ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always +basicConstraints = CA:false +keyUsage = nonRepudiation, digitalSignature + +[ v3_ee_ec ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always +basicConstraints = CA:false +keyUsage = nonRepudiation, digitalSignature, keyAgreement + +#################################################################### +[ ca ] +default_ca = CA_default + +[ CA_default ] +dir = ./demoCA +certs = $dir/certs +crl_dir = $dir/crl +database = $dir/index.txt +new_certs_dir = $dir/newcerts +certificate = $dir/cacert.pem +serial = $dir/serial +crl = $dir/crl.pem +private_key = $dir/private/cakey.pem +x509_extensions = v3_ca +name_opt = ca_default +cert_opt = ca_default +default_days = 365 +default_crl_days= 30 +default_md = sha1 +preserve = no +policy = policy_anything + +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ v3_ca ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +basicConstraints = critical,CA:true,pathlen:1 +keyUsage = cRLSign, keyCertSign +issuerAltName = issuer:copy diff --git a/test/cmactest.c b/test/cmactest.c new file mode 100644 index 00000000..cb2b273b --- /dev/null +++ b/test/cmactest.c @@ -0,0 +1,216 @@ +/* + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * CMAC low level APIs are deprecated for public use, but still ok for internal + * use. + */ +#include "internal/deprecated.h" + +#include +#include +#include + +#include "internal/nelem.h" + +#include +#include +#include + +#include "testutil.h" + +static const char xtskey[32] = { + 0x00, 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 +}; + +static struct test_st { + const char key[32]; + int key_len; + const unsigned char data[64]; + int data_len; + const char *mac; +} test[3] = { + { + { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + }, + 16, + "My test data", + 12, + "29cec977c48f63c200bd5c4a6881b224" + }, + { + { + 0x00, 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 + }, + 32, + "My test data", + 12, + "db6493aa04e4761f473b2b453c031c9a" + }, + { + { + 0x00, 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 + }, + 32, + "My test data again", + 18, + "65c11c75ecf590badd0a5e56cbb8af60" + }, +}; + +static char *pt(unsigned char *md, unsigned int len); + +static int test_cmac_bad(void) +{ + CMAC_CTX *ctx = NULL; + int ret = 0; + + ctx = CMAC_CTX_new(); + if (!TEST_ptr(ctx) + || !TEST_false(CMAC_Init(ctx, NULL, 0, NULL, NULL)) + || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len)) + /* Should be able to pass cipher first, and then key */ + || !TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_128_cbc(), NULL)) + /* Must have a key */ + || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len)) + /* Now supply the key */ + || !TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, NULL, NULL)) + /* Update should now work */ + || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len)) + /* XTS is not a suitable cipher to use */ + || !TEST_false(CMAC_Init(ctx, xtskey, sizeof(xtskey), EVP_aes_128_xts(), + NULL)) + || !TEST_false(CMAC_Update(ctx, test[0].data, test[0].data_len))) + goto err; + + ret = 1; +err: + CMAC_CTX_free(ctx); + return ret; +} + +static int test_cmac_run(void) +{ + char *p; + CMAC_CTX *ctx = NULL; + unsigned char buf[AES_BLOCK_SIZE]; + size_t len; + int ret = 0; + + ctx = CMAC_CTX_new(); + + if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, + EVP_aes_128_cbc(), NULL)) + || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len)) + || !TEST_true(CMAC_Final(ctx, buf, &len))) + goto err; + + p = pt(buf, len); + if (!TEST_str_eq(p, test[0].mac)) + goto err; + + if (!TEST_true(CMAC_Init(ctx, test[1].key, test[1].key_len, + EVP_aes_256_cbc(), NULL)) + || !TEST_true(CMAC_Update(ctx, test[1].data, test[1].data_len)) + || !TEST_true(CMAC_Final(ctx, buf, &len))) + goto err; + + p = pt(buf, len); + if (!TEST_str_eq(p, test[1].mac)) + goto err; + + if (!TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL)) + || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len)) + || !TEST_true(CMAC_Final(ctx, buf, &len))) + goto err; + p = pt(buf, len); + if (!TEST_str_eq(p, test[2].mac)) + goto err; + /* Test reusing a key */ + if (!TEST_true(CMAC_Init(ctx, NULL, 0, NULL, NULL)) + || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len)) + || !TEST_true(CMAC_Final(ctx, buf, &len))) + goto err; + p = pt(buf, len); + if (!TEST_str_eq(p, test[2].mac)) + goto err; + + /* Test setting the cipher and key separately */ + if (!TEST_true(CMAC_Init(ctx, NULL, 0, EVP_aes_256_cbc(), NULL)) + || !TEST_true(CMAC_Init(ctx, test[2].key, test[2].key_len, NULL, NULL)) + || !TEST_true(CMAC_Update(ctx, test[2].data, test[2].data_len)) + || !TEST_true(CMAC_Final(ctx, buf, &len))) + goto err; + p = pt(buf, len); + if (!TEST_str_eq(p, test[2].mac)) + goto err; + + ret = 1; +err: + CMAC_CTX_free(ctx); + return ret; +} + +static int test_cmac_copy(void) +{ + char *p; + CMAC_CTX *ctx = NULL, *ctx2 = NULL; + unsigned char buf[AES_BLOCK_SIZE]; + size_t len; + int ret = 0; + + ctx = CMAC_CTX_new(); + ctx2 = CMAC_CTX_new(); + if (!TEST_ptr(ctx) || !TEST_ptr(ctx2)) + goto err; + + if (!TEST_true(CMAC_Init(ctx, test[0].key, test[0].key_len, + EVP_aes_128_cbc(), NULL)) + || !TEST_true(CMAC_Update(ctx, test[0].data, test[0].data_len)) + || !TEST_true(CMAC_CTX_copy(ctx2, ctx)) + || !TEST_true(CMAC_Final(ctx2, buf, &len))) + goto err; + + p = pt(buf, len); + if (!TEST_str_eq(p, test[0].mac)) + goto err; + + ret = 1; +err: + CMAC_CTX_free(ctx2); + CMAC_CTX_free(ctx); + return ret; +} + +static char *pt(unsigned char *md, unsigned int len) +{ + unsigned int i; + static char buf[80]; + + for (i = 0; i < len; i++) + sprintf(&(buf[i * 2]), "%02x", md[i]); + return buf; +} + +int setup_tests(void) +{ + ADD_TEST(test_cmac_bad); + ADD_TEST(test_cmac_run); + ADD_TEST(test_cmac_copy); + return 1; +} + diff --git a/test/cmp_client_test.c b/test/cmp_client_test.c index ab2b9302..2f7fbf7b 100644 --- a/test/cmp_client_test.c +++ b/test/cmp_client_test.c @@ -252,7 +252,8 @@ static int execute_try_certreq_poll_test(CMP_SES_TEST_FIXTURE *fixture) && check_after == CHECK_AFTER && TEST_ptr_eq(OSSL_CMP_CTX_get0_newCert(ctx), NULL) && TEST_int_eq(fixture->expected, OSSL_CMP_try_certreq(ctx, TYPE, NULL)) - && TEST_int_eq(0, X509_cmp(OSSL_CMP_CTX_get0_newCert(ctx), client_cert)); + && TEST_int_eq(0, + X509_cmp(OSSL_CMP_CTX_get0_newCert(ctx), client_cert)); } static int test_try_certreq_poll(void) diff --git a/test/cmp_ctx_test.c b/test/cmp_ctx_test.c index 89805342..86eb430e 100644 --- a/test/cmp_ctx_test.c +++ b/test/cmp_ctx_test.c @@ -305,15 +305,15 @@ static int test_cmp_ctx_log_cb(void) return result; } -static BIO *test_http_cb(BIO *bio, void *arg, int use_ssl, int detail) +static BIO *test_http_cb(OSSL_CMP_CTX *ctx, BIO *hbio, unsigned long detail) { return NULL; } -static OSSL_CMP_MSG *test_transfer_cb(OSSL_CMP_CTX *ctx, - const OSSL_CMP_MSG *req) +static int test_transfer_cb(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, + OSSL_CMP_MSG **res) { - return NULL; + return 0; } static int test_certConf_cb(OSSL_CMP_CTX *ctx, X509 *cert, int fail_info, @@ -498,6 +498,7 @@ static X509_STORE *X509_STORE_new_1(void) #define IS_NEG(x) ((x) < 0) #define IS_0(x) ((x) == 0) /* for any type */ +#define IS_DEFAULT_PORT(x) ((x) == OSSL_CMP_DEFAULT_PORT) #define DROP(x) (void)(x) /* dummy free() for non-pointer and function types */ #define RET_IF_NULL_ARG(ctx, ret) \ @@ -546,7 +547,6 @@ static X509_STORE *X509_STORE_new_1(void) STACK_OF(TYPE)*, NULL, IS_0, \ sk_##TYPE##_new_null(), sk_##TYPE##_free) -typedef OSSL_HTTP_bio_cb_t OSSL_CMP_http_cb_t; #define DEFINE_SET_CB_TEST(FIELD) \ static OSSL_CMP_##FIELD##_t OSSL_CMP_CTX_get_##FIELD(const CMP_CTX *ctx) \ { \ @@ -565,13 +565,13 @@ typedef OSSL_HTTP_bio_cb_t OSSL_CMP_http_cb_t; DEFAULT, 1, DROP) #define DEFINE_SET_GET_INT_TEST(OSSL_CMP, CTX, FIELD) \ DEFINE_SET_GET_INT_TEST_DEFAULT(OSSL_CMP, CTX, FIELD, IS_NEG) -#define DEFINE_SET_INT_TEST(FIELD) \ +#define DEFINE_SET_PORT_TEST(FIELD) \ static int OSSL_CMP_CTX_get_##FIELD(const CMP_CTX *ctx) \ { \ RET_IF_NULL_ARG(ctx, -1); \ return ctx->FIELD; \ } \ - DEFINE_SET_GET_INT_TEST_DEFAULT(OSSL_CMP, CTX, FIELD, IS_0) + DEFINE_SET_GET_INT_TEST_DEFAULT(OSSL_CMP, CTX, FIELD, IS_DEFAULT_PORT) #define DEFINE_SET_GET_ARG_FN(SETN, GETN, FIELD, ARG, T) \ static int OSSL_CMP_CTX_##SETN##_##FIELD##_##ARG(CMP_CTX *ctx, T val) \ @@ -729,10 +729,10 @@ DEFINE_SET_GET_BASE_TEST(OSSL_CMP_CTX, set, get, 0, option_16, int, -1, IS_0, \ DEFINE_SET_CB_TEST(log_cb) DEFINE_SET_TEST_DEFAULT(OSSL_CMP, CTX, 1, 1, serverPath, char, IS_0) -DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, server, char) -DEFINE_SET_INT_TEST(serverPort) -DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, proxy, char) -DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, no_proxy, char) +DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, serverName, char) +DEFINE_SET_PORT_TEST(serverPort) +DEFINE_SET_TEST(OSSL_CMP, CTX, 1, 1, proxyName, char) +DEFINE_SET_PORT_TEST(proxyPort) DEFINE_SET_CB_TEST(http_cb) DEFINE_SET_GET_P_VOID_TEST(http_cb_arg) DEFINE_SET_CB_TEST(transfer_cb) @@ -814,10 +814,10 @@ int setup_tests(void) #endif /* message transfer: */ ADD_TEST(test_CTX_set1_get0_serverPath); - ADD_TEST(test_CTX_set1_get0_server); + ADD_TEST(test_CTX_set1_get0_serverName); ADD_TEST(test_CTX_set_get_serverPort); - ADD_TEST(test_CTX_set1_get0_proxy); - ADD_TEST(test_CTX_set1_get0_no_proxy); + ADD_TEST(test_CTX_set1_get0_proxyName); + ADD_TEST(test_CTX_set_get_proxyPort); ADD_TEST(test_CTX_set_get_http_cb); ADD_TEST(test_CTX_set_get_http_cb_arg); ADD_TEST(test_CTX_set_get_transfer_cb); diff --git a/test/cmp_vfy_test.c b/test/cmp_vfy_test.c index c74dd2fa..583e7c2f 100644 --- a/test/cmp_vfy_test.c +++ b/test/cmp_vfy_test.c @@ -123,7 +123,8 @@ static int test_verify_popo_bad(void) static int execute_validate_msg_test(CMP_VFY_TEST_FIXTURE *fixture) { return TEST_int_eq(fixture->expected, - OSSL_CMP_validate_msg(fixture->cmp_ctx, fixture->msg)); + ossl_cmp_msg_check_update(fixture->cmp_ctx, fixture->msg, + NULL, 0)); } static int execute_validate_cert_path_test(CMP_VFY_TEST_FIXTURE *fixture) @@ -387,19 +388,19 @@ static int test_validate_cert_path_expired(void) return result; } -static int execute_MSG_check_received_test(CMP_VFY_TEST_FIXTURE *fixture) +static int execute_msg_check_test(CMP_VFY_TEST_FIXTURE *fixture) { const OSSL_CMP_PKIHEADER *hdr = OSSL_CMP_MSG_get0_header(fixture->msg); const ASN1_OCTET_STRING *tid = OSSL_CMP_HDR_get0_transactionID(hdr); if (!TEST_int_eq(fixture->expected, - ossl_cmp_msg_check_received(fixture->cmp_ctx, - fixture->msg, - fixture->allow_unprotected_cb, - fixture->additional_arg))) + ossl_cmp_msg_check_update(fixture->cmp_ctx, + fixture->msg, + fixture->allow_unprotected_cb, + fixture->additional_arg))) return 0; - if (fixture->expected < 0) /* error expected aready during above check */ + if (fixture->expected == 0) /* error expected aready during above check */ return 1; return TEST_int_eq(0, @@ -416,10 +417,10 @@ static int allow_unprotected(const OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, return allow; } -static void setup_check_received(CMP_VFY_TEST_FIXTURE **fixture, int expected, - ossl_cmp_allow_unprotected_cb_t cb, int arg, - const unsigned char *trid_data, - const unsigned char *nonce_data) +static void setup_check_update(CMP_VFY_TEST_FIXTURE **fixture, int expected, + ossl_cmp_allow_unprotected_cb_t cb, int arg, + const unsigned char *trid_data, + const unsigned char *nonce_data) { OSSL_CMP_CTX *ctx = (*fixture)->cmp_ctx; int nonce_len = OSSL_CMP_SENDERNONCE_LENGTH; @@ -448,33 +449,32 @@ static void setup_check_received(CMP_VFY_TEST_FIXTURE **fixture, int expected, } #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -static int test_MSG_check_received_no_protection_no_cb(void) +static int test_msg_check_no_protection_no_cb(void) { SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_received(&fixture, -1, NULL, 0, NULL, NULL); - EXECUTE_TEST(execute_MSG_check_received_test, tear_down); + setup_check_update(&fixture, 0, NULL, 0, NULL, NULL); + EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } -static int test_MSG_check_received_no_protection_restrictive_cb(void) +static int test_msg_check_no_protection_restrictive_cb(void) { SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_received(&fixture, -1, allow_unprotected, 0, NULL, NULL); - EXECUTE_TEST(execute_MSG_check_received_test, tear_down); + setup_check_update(&fixture, 0, allow_unprotected, 0, NULL, NULL); + EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } #endif -static int test_MSG_check_received_no_protection_permissive_cb(void) +static int test_msg_check_no_protection_permissive_cb(void) { SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_received(&fixture, OSSL_CMP_PKIBODY_IP, allow_unprotected, 1, - NULL, NULL); - EXECUTE_TEST(execute_MSG_check_received_test, tear_down); + setup_check_update(&fixture, 1, allow_unprotected, 1, NULL, NULL); + EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } -static int test_MSG_check_received_check_transaction_id(void) +static int test_msg_check_transaction_id(void) { /* Transaction id belonging to CMP_IR_rmprotection.der */ const unsigned char trans_id[OSSL_CMP_TRANSACTIONID_LENGTH] = { @@ -483,23 +483,22 @@ static int test_MSG_check_received_check_transaction_id(void) }; SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_received(&fixture, OSSL_CMP_PKIBODY_IP, allow_unprotected, 1, - trans_id, NULL); - EXECUTE_TEST(execute_MSG_check_received_test, tear_down); + setup_check_update(&fixture, 1, allow_unprotected, 1, trans_id, NULL); + EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -static int test_MSG_check_received_check_transaction_id_bad(void) +static int test_msg_check_transaction_id_bad(void) { SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_received(&fixture, -1, allow_unprotected, 1, rand_data, NULL); - EXECUTE_TEST(execute_MSG_check_received_test, tear_down); + setup_check_update(&fixture, 0, allow_unprotected, 1, rand_data, NULL); + EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } #endif -static int test_MSG_check_received_check_recipient_nonce(void) +static int test_msg_check_recipient_nonce(void) { /* Recipient nonce belonging to CMP_IP_ir_rmprotection.der */ const unsigned char rec_nonce[OSSL_CMP_SENDERNONCE_LENGTH] = { @@ -508,18 +507,17 @@ static int test_MSG_check_received_check_recipient_nonce(void) }; SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_received(&fixture, OSSL_CMP_PKIBODY_IP, allow_unprotected, 1, - NULL, rec_nonce); - EXECUTE_TEST(execute_MSG_check_received_test, tear_down); + setup_check_update(&fixture, 1, allow_unprotected, 1, NULL, rec_nonce); + EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -static int test_MSG_check_received_check_recipient_nonce_bad(void) +static int test_msg_check_recipient_nonce_bad(void) { SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_check_received(&fixture, -1, allow_unprotected, 1, NULL, rand_data); - EXECUTE_TEST(execute_MSG_check_received_test, tear_down); + setup_check_update(&fixture, 0, allow_unprotected, 1, NULL, rand_data); + EXECUTE_TEST(execute_msg_check_test, tear_down); return result; } #endif @@ -629,17 +627,17 @@ int setup_tests(void) ADD_TEST(test_validate_cert_path_wrong_anchor); #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - ADD_TEST(test_MSG_check_received_no_protection_no_cb); - ADD_TEST(test_MSG_check_received_no_protection_restrictive_cb); + ADD_TEST(test_msg_check_no_protection_no_cb); + ADD_TEST(test_msg_check_no_protection_restrictive_cb); #endif - ADD_TEST(test_MSG_check_received_no_protection_permissive_cb); - ADD_TEST(test_MSG_check_received_check_transaction_id); + ADD_TEST(test_msg_check_no_protection_permissive_cb); + ADD_TEST(test_msg_check_transaction_id); #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - ADD_TEST(test_MSG_check_received_check_transaction_id_bad); + ADD_TEST(test_msg_check_transaction_id_bad); #endif - ADD_TEST(test_MSG_check_received_check_recipient_nonce); + ADD_TEST(test_msg_check_recipient_nonce); #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - ADD_TEST(test_MSG_check_received_check_recipient_nonce_bad); + ADD_TEST(test_msg_check_recipient_nonce_bad); #endif return 1; diff --git a/test/dsatest.c b/test/dsatest.c index c9857d6c..8444ea14 100644 --- a/test/dsatest.c +++ b/test/dsatest.c @@ -282,7 +282,7 @@ static int dsa_keygen_test(void) &pcount_out)) || !TEST_int_eq(pcount_out, expected_c) || !TEST_false(EVP_PKEY_get_utf8_string_param(key, - OSSL_PKEY_PARAM_FFC_GROUP, + OSSL_PKEY_PARAM_DH_GROUP, group_out, sizeof(group_out), &len))) goto end; diff --git a/test/ectest.c b/test/ectest.c index bbcd9677..2fdf3392 100644 --- a/test/ectest.c +++ b/test/ectest.c @@ -9,7 +9,8 @@ */ /* - * We need access to the deprecated EC_POINTs_mul for testing purposes + * We need access to the deprecated EC_POINTs_mul, EC_GROUP_precompute_mult, + * and EC_GROUP_have_precompute_mult for testing purposes * when the deprecated calls are not hidden */ #ifndef OPENSSL_NO_DEPRECATED_3_0 @@ -58,7 +59,9 @@ static int group_order_tests(EC_GROUP *group) if (!TEST_true(EC_GROUP_get_order(group, order, ctx)) || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) || !TEST_true(EC_POINT_is_at_infinity(group, Q)) +# ifndef OPENSSL_NO_DEPRECATED_3_0 || !TEST_true(EC_GROUP_precompute_mult(group, ctx)) +# endif || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) || !TEST_true(EC_POINT_is_at_infinity(group, Q)) || !TEST_true(EC_POINT_copy(P, G)) @@ -158,9 +161,7 @@ static int prime_field_tests(void) { BN_CTX *ctx = NULL; BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL; - EC_GROUP *group = NULL, *tmp = NULL; - EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, - *P_256 = NULL, *P_384 = NULL, *P_521 = NULL; + EC_GROUP *group = NULL; EC_POINT *P = NULL, *Q = NULL, *R = NULL; BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL; # ifndef OPENSSL_NO_DEPRECATED_3_0 @@ -178,20 +179,8 @@ static int prime_field_tests(void) || !TEST_true(BN_hex2bn(&p, "17")) || !TEST_true(BN_hex2bn(&a, "1")) || !TEST_true(BN_hex2bn(&b, "1")) - /* - * applications should use EC_GROUP_new_curve_GFp so - * that the library gets to choose the EC_METHOD - */ - || !TEST_ptr(group = EC_GROUP_new(EC_GFp_mont_method())) - || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx)) - || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group))) - || !TEST_true(EC_GROUP_copy(tmp, group))) - goto err; - EC_GROUP_free(group); - group = tmp; - tmp = NULL; - - if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))) + || !TEST_ptr(group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) + || !TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))) goto err; TEST_info("Curve defined by Weierstrass equation"); @@ -324,8 +313,6 @@ static int prime_field_tests(void) || !TEST_BN_eq(y, z) || !TEST_int_eq(EC_GROUP_get_degree(group), 160) || !group_order_tests(group) - || !TEST_ptr(P_160 = EC_GROUP_new(EC_GROUP_method_of(group))) - || !TEST_true(EC_GROUP_copy(P_160, group)) /* Curve P-192 (FIPS PUB 186-2, App. 6) */ @@ -363,8 +350,6 @@ static int prime_field_tests(void) ctx)) || !TEST_int_eq(EC_GROUP_get_degree(group), 192) || !group_order_tests(group) - || !TEST_ptr(P_192 = EC_GROUP_new(EC_GROUP_method_of(group))) - || !TEST_true(EC_GROUP_copy(P_192, group)) /* Curve P-224 (FIPS PUB 186-2, App. 6) */ @@ -402,8 +387,6 @@ static int prime_field_tests(void) ctx)) || !TEST_int_eq(EC_GROUP_get_degree(group), 224) || !group_order_tests(group) - || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group))) - || !TEST_true(EC_GROUP_copy(P_224, group)) /* Curve P-256 (FIPS PUB 186-2, App. 6) */ @@ -442,8 +425,6 @@ static int prime_field_tests(void) ctx)) || !TEST_int_eq(EC_GROUP_get_degree(group), 256) || !group_order_tests(group) - || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group))) - || !TEST_true(EC_GROUP_copy(P_256, group)) /* Curve P-384 (FIPS PUB 186-2, App. 6) */ @@ -488,8 +469,6 @@ static int prime_field_tests(void) ctx)) || !TEST_int_eq(EC_GROUP_get_degree(group), 384) || !group_order_tests(group) - || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group))) - || !TEST_true(EC_GROUP_copy(P_384, group)) /* Curve P-521 (FIPS PUB 186-2, App. 6) */ || !TEST_true(BN_hex2bn(&p, "1FF" @@ -544,8 +523,6 @@ static int prime_field_tests(void) ctx)) || !TEST_int_eq(EC_GROUP_get_degree(group), 521) || !group_order_tests(group) - || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group))) - || !TEST_true(EC_GROUP_copy(P_521, group)) /* more tests using the last curve */ @@ -617,7 +594,6 @@ err: BN_free(a); BN_free(b); EC_GROUP_free(group); - EC_GROUP_free(tmp); EC_POINT_free(P); EC_POINT_free(Q); EC_POINT_free(R); @@ -626,13 +602,6 @@ err: BN_free(z); BN_free(yplusone); BN_free(scalar3); - - EC_GROUP_free(P_160); - EC_GROUP_free(P_192); - EC_GROUP_free(P_224); - EC_GROUP_free(P_256); - EC_GROUP_free(P_384); - EC_GROUP_free(P_521); return r; } @@ -814,7 +783,7 @@ static int char2_curve_test(int n) BN_CTX *ctx = NULL; BIGNUM *p = NULL, *a = NULL, *b = NULL; BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL; - EC_GROUP *group = NULL, *variable = NULL; + EC_GROUP *group = NULL; EC_POINT *P = NULL, *Q = NULL, *R = NULL; # ifndef OPENSSL_NO_DEPRECATED_3_0 const EC_POINT *points[3]; @@ -833,8 +802,7 @@ static int char2_curve_test(int n) || !TEST_true(BN_hex2bn(&p, test->p)) || !TEST_true(BN_hex2bn(&a, test->a)) || !TEST_true(BN_hex2bn(&b, test->b)) - || !TEST_true(group = EC_GROUP_new(EC_GF2m_simple_method())) - || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx)) + || !TEST_true(group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) || !TEST_ptr(P = EC_POINT_new(group)) || !TEST_ptr(Q = EC_POINT_new(group)) || !TEST_ptr(R = EC_POINT_new(group)) @@ -884,9 +852,7 @@ static int char2_curve_test(int n) # endif if (!TEST_int_eq(EC_GROUP_get_degree(group), test->degree) - || !group_order_tests(group) - || !TEST_ptr(variable = EC_GROUP_new(EC_GROUP_method_of(group))) - || !TEST_true(EC_GROUP_copy(variable, group))) + || !group_order_tests(group)) goto err; /* more tests using the last curve */ @@ -963,7 +929,6 @@ err: EC_POINT_free(Q); EC_POINT_free(R); EC_GROUP_free(group); - EC_GROUP_free(variable); return r; } @@ -971,7 +936,7 @@ static int char2_field_tests(void) { BN_CTX *ctx = NULL; BIGNUM *p = NULL, *a = NULL, *b = NULL; - EC_GROUP *group = NULL, *tmp = NULL; + EC_GROUP *group = NULL; EC_POINT *P = NULL, *Q = NULL, *R = NULL; BIGNUM *x = NULL, *y = NULL, *z = NULL, *cof = NULL, *yplusone = NULL; unsigned char buf[100]; @@ -987,20 +952,8 @@ static int char2_field_tests(void) || !TEST_true(BN_hex2bn(&b, "1"))) goto err; - group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use - * EC_GROUP_new_curve_GF2m - * so that the library gets - * to choose the EC_METHOD */ - if (!TEST_ptr(group) - || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx)) - || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group))) - || !TEST_true(EC_GROUP_copy(tmp, group))) - goto err; - EC_GROUP_free(group); - group = tmp; - tmp = NULL; - - if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))) + if (!TEST_ptr(group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) + || !TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx))) goto err; TEST_info("Curve defined by Weierstrass equation"); @@ -1121,7 +1074,6 @@ err: BN_free(a); BN_free(b); EC_GROUP_free(group); - EC_GROUP_free(tmp); EC_POINT_free(P); EC_POINT_free(Q); EC_POINT_free(R); @@ -1204,13 +1156,12 @@ static int group_field_test(void) return r; } -# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 /* - * nistp_test_params contains magic numbers for testing our optimized - * implementations of several NIST curves with characteristic > 3. + * nistp_test_params contains magic numbers for testing + * several NIST curves with characteristic > 3. */ struct nistp_test_params { - const EC_METHOD *(*meth) (void); + const int nid; int degree; /* * Qx, Qy and D are taken from @@ -1223,7 +1174,7 @@ struct nistp_test_params { static const struct nistp_test_params nistp_tests_params[] = { { /* P-224 */ - EC_GFp_nistp224_method, + NID_secp224r1, 224, /* p */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", @@ -1246,7 +1197,7 @@ static const struct nistp_test_params nistp_tests_params[] = { }, { /* P-256 */ - EC_GFp_nistp256_method, + NID_X9_62_prime256v1, 256, /* p */ "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", @@ -1269,7 +1220,7 @@ static const struct nistp_test_params nistp_tests_params[] = { }, { /* P-521 */ - EC_GFp_nistp521_method, + NID_secp521r1, 521, /* p */ "1ff" @@ -1333,7 +1284,7 @@ static int nistp_single_test(int idx) || !TEST_ptr(order = BN_new()) || !TEST_ptr(yplusone = BN_new()) - || !TEST_ptr(NISTP = EC_GROUP_new(test->meth())) + || !TEST_ptr(NISTP = EC_GROUP_new_by_curve_name(test->nid)) || !TEST_true(BN_hex2bn(&p, test->p)) || !TEST_int_eq(1, BN_check_prime(p, ctx, NULL)) || !TEST_true(BN_hex2bn(&a, test->a)) @@ -1388,16 +1339,13 @@ static int nistp_single_test(int idx) /* random point multiplication */ EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) - - /* - * We have not performed precomputation so have_precompute mult should be - * false - */ +# ifndef OPENSSL_NO_DEPRECATED_3_0 + /* We have not performed precomp so this should be false */ || !TEST_false(EC_GROUP_have_precompute_mult(NISTP)) - - /* now repeat all tests with precomputation */ + /* now repeat all tests with precomputation */ || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx)) - || !TEST_true(EC_GROUP_have_precompute_mult(NISTP))) +# endif + ) goto err; /* fixed point multiplication */ @@ -1429,7 +1377,7 @@ static int nistp_single_test(int idx) || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx))) goto err; - r = group_order_tests(NISTP); + r = 1; err: EC_GROUP_free(NISTP); EC_POINT_free(G); @@ -1448,7 +1396,6 @@ err: BN_CTX_free(ctx); return r; } -# endif static const unsigned char p521_named[] = { 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23, @@ -1542,7 +1489,7 @@ static int check_named_curve_test(int id) /* Determine if the built-in curve has a seed field set */ has_seed = (EC_GROUP_get_seed_len(group) > 0); - field_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); + field_nid = EC_GROUP_get_field_type(group); if (field_nid == NID_X9_62_characteristic_two_field) { if (!TEST_ptr(other_p = BN_dup(group_p)) || !TEST_true(BN_lshift1(other_p, other_p))) @@ -2157,7 +2104,7 @@ static int cofactor_range_test(void) */ static int cardinality_test(int n) { - int ret = 0; + int ret = 0, is_binary = 0; int nid = curves[n].nid; BN_CTX *ctx = NULL; EC_GROUP *g1 = NULL, *g2 = NULL; @@ -2168,14 +2115,13 @@ static int cardinality_test(int n) TEST_info("Curve %s cardinality test", OBJ_nid2sn(nid)); if (!TEST_ptr(ctx = BN_CTX_new()) - || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid)) - || !TEST_ptr(g2 = EC_GROUP_new(EC_GROUP_method_of(g1)))) { - EC_GROUP_free(g1); - EC_GROUP_free(g2); + || !TEST_ptr(g1 = EC_GROUP_new_by_curve_name(nid))) { BN_CTX_free(ctx); return 0; } + is_binary = (EC_GROUP_get_field_type(g1) == NID_X9_62_characteristic_two_field); + BN_CTX_start(ctx); g1_p = BN_CTX_get(ctx); g1_a = BN_CTX_get(ctx); @@ -2193,7 +2139,14 @@ static int cardinality_test(int n) || !TEST_true(BN_copy(g1_order, EC_GROUP_get0_order(g1))) || !TEST_true(EC_GROUP_get_cofactor(g1, g1_cf, ctx)) /* construct g2 manually with g1 parameters */ - || !TEST_true(EC_GROUP_set_curve(g2, g1_p, g1_a, g1_b, ctx)) +# ifndef OPENSSL_NO_EC2M + || !TEST_ptr(g2 = (is_binary) ? + EC_GROUP_new_curve_GF2m(g1_p, g1_a, g1_b, ctx) : + EC_GROUP_new_curve_GFp(g1_p, g1_a, g1_b, ctx)) +# else + || !TEST_int_eq(0, is_binary) + || !TEST_ptr(g2 = EC_GROUP_new_curve_GFp(g1_p, g1_a, g1_b, ctx)) +# endif || !TEST_ptr(g2_gen = EC_POINT_new(g2)) || !TEST_true(EC_POINT_set_affine_coordinates(g2, g2_gen, g1_x, g1_y, ctx)) /* pass NULL cofactor: lib should compute it */ @@ -2237,7 +2190,6 @@ static int check_ec_key_field_public_range_test(int id) int ret = 0, type = 0; const EC_POINT *pub = NULL; const EC_GROUP *group = NULL; - const EC_METHOD *meth = NULL; const BIGNUM *field = NULL; BIGNUM *x = NULL, *y = NULL; EC_KEY *key = NULL; @@ -2246,7 +2198,6 @@ static int check_ec_key_field_public_range_test(int id) || !TEST_ptr(y = BN_new()) || !TEST_ptr(key = EC_KEY_new_by_curve_name(curves[id].nid)) || !TEST_ptr(group = EC_KEY_get0_group(key)) - || !TEST_ptr(meth = EC_GROUP_method_of(group)) || !TEST_ptr(field = EC_GROUP_get0_field(group)) || !TEST_int_gt(EC_KEY_generate_key(key), 0) || !TEST_int_gt(EC_KEY_check_key(key), 0) @@ -2259,7 +2210,7 @@ static int check_ec_key_field_public_range_test(int id) * Make the public point out of range by adding the field (which will still * be the same point on the curve). The add is different for char2 fields. */ - type = EC_METHOD_get_field_type(meth); + type = EC_GROUP_get_field_type(group); #ifndef OPENSSL_NO_EC2M if (type == NID_X9_62_characteristic_two_field) { /* test for binary curves */ @@ -2404,9 +2355,7 @@ int setup_tests(void) ADD_TEST(char2_field_tests); ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests)); # endif -# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params)); -# endif ADD_ALL_TESTS(internal_curve_test, crv_len); ADD_ALL_TESTS(internal_curve_test_method, crv_len); ADD_TEST(group_field_test); diff --git a/test/errtest.c b/test/errtest.c index 179c338c..f7a6f854 100644 --- a/test/errtest.c +++ b/test/errtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,8 +7,10 @@ * https://www.openssl.org/source/license.html */ +#include #include #include +#include #include "testutil.h" @@ -18,6 +20,49 @@ # include #endif +#ifndef OPENSSL_NO_DEPRECATED_3_0 +# define IS_HEX(ch) ((ch >= '0' && ch <='9') || (ch >= 'A' && ch <='F')) + +static int test_print_error_format(void) +{ + static const char expected_format[] = + ":error::system library:%s:Operation not permitted:" +# ifndef OPENSSL_NO_FILENAMES + "errtest.c:30:"; +# else + ":0:"; +# endif + char expected[256]; + char *out = NULL, *p = NULL; + int ret = 0, len; + BIO *bio = NULL; + + BIO_snprintf(expected, sizeof(expected), expected_format, OPENSSL_FUNC); + + if (!TEST_ptr(bio = BIO_new(BIO_s_mem()))) + return 0; + + ERR_PUT_error(ERR_LIB_SYS, 0, 1, "errtest.c", 30); + ERR_print_errors(bio); + + if (!TEST_int_gt(len = BIO_get_mem_data(bio, &out), 0)) + goto err; + /* Skip over the variable thread id at the start of the string */ + for (p = out; *p != ':' && *p != 0; ++p) { + if (!TEST_true(IS_HEX(*p))) + goto err; + } + if (!TEST_true(*p != 0) + || !TEST_strn_eq(expected, p, strlen(expected))) + goto err; + + ret = 1; +err: + BIO_free(bio); + return ret; +} +#endif + /* Test that querying the error queue preserves the OS error. */ static int preserves_system_error(void) { @@ -79,5 +124,8 @@ int setup_tests(void) ADD_TEST(preserves_system_error); ADD_TEST(vdata_appends); ADD_TEST(raised_error); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + ADD_TEST(test_print_error_format); +#endif return 1; } diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index 53d2f3af..7f07ab73 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -767,6 +767,40 @@ static int test_EVP_PKCS82PKEY(void) } #endif +/* This uses kExampleRSAKeyDER and kExampleRSAKeyPKCS8 to verify encoding */ +static int test_privatekey_to_pkcs8(void) +{ + EVP_PKEY *pkey = NULL; + BIO *membio = NULL; + char *membuf = NULL; + size_t membuf_len = 0; + int ok = 0; + + if (!TEST_ptr(membio = BIO_new(BIO_s_mem())) + || !TEST_ptr(pkey = load_example_rsa_key()) + || !TEST_int_gt(i2d_PKCS8PrivateKey_bio(membio, pkey, NULL, + NULL, 0, NULL, NULL), + 0) + || !TEST_ptr((membuf_len = (size_t)BIO_get_mem_data(membio, &membuf), + membuf)) + || !TEST_mem_eq(membuf, membuf_len, + kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8)) + /* + * We try to write PEM as well, just to see that it doesn't err, but + * assume that the result is correct. + */ + || !TEST_int_gt(PEM_write_bio_PKCS8PrivateKey(membio, pkey, NULL, + NULL, 0, NULL, NULL), + 0)) + goto done; + + ok = 1; + done: + EVP_PKEY_free(pkey); + BIO_free_all(membio); + return ok; +} + #if !defined(OPENSSL_NO_SM2) && !defined(FIPS_MODULE) static int test_EVP_SM2_verify(void) @@ -1246,6 +1280,47 @@ static int test_HKDF(void) return ret; } +static int test_emptyikm_HKDF(void) +{ + EVP_PKEY_CTX *pctx; + unsigned char out[20]; + size_t outlen; + int ret = 0; + unsigned char salt[] = "9876543210"; + unsigned char key[] = ""; + unsigned char info[] = "stringinfo"; + const unsigned char expected[] = { + 0x68, 0x81, 0xa5, 0x3e, 0x5b, 0x9c, 0x7b, 0x6f, 0x2e, 0xec, 0xc8, 0x47, + 0x7c, 0xfa, 0x47, 0x35, 0x66, 0x82, 0x15, 0x30 + }; + size_t expectedlen = sizeof(expected); + + if (!TEST_ptr(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, NULL))) + goto done; + + outlen = sizeof(out); + memset(out, 0, outlen); + + if (!TEST_int_gt(EVP_PKEY_derive_init(pctx), 0) + || !TEST_int_gt(EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()), 0) + || !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, + sizeof(salt) - 1), 0) + || !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_key(pctx, key, + sizeof(key) - 1), 0) + || !TEST_int_gt(EVP_PKEY_CTX_add1_hkdf_info(pctx, info, + sizeof(info) - 1), 0) + || !TEST_int_gt(EVP_PKEY_derive(pctx, out, &outlen), 0) + || !TEST_mem_eq(out, outlen, expected, expectedlen)) + goto done; + + ret = 1; + + done: + EVP_PKEY_CTX_free(pctx); + + return ret; +} + #ifndef OPENSSL_NO_EC static int test_X509_PUBKEY_inplace(void) { @@ -1625,6 +1700,47 @@ static int test_keygen_with_empty_template(int n) return ret; } +/* + * Test that we fail if we attempt to use an algorithm that is not available + * in the current library context (unless we are using an algorithm that should + * be made available via legacy codepaths). + */ +static int test_pkey_ctx_fail_without_provider(int tst) +{ + OPENSSL_CTX *tmpctx = OPENSSL_CTX_new(); + OSSL_PROVIDER *nullprov = NULL; + EVP_PKEY_CTX *pctx = NULL; + int ret = 0; + + if (!TEST_ptr(tmpctx)) + goto err; + + nullprov = OSSL_PROVIDER_load(tmpctx, "null"); + if (!TEST_ptr(nullprov)) + goto err; + + pctx = EVP_PKEY_CTX_new_from_name(tmpctx, tst == 0 ? "RSA" : "HMAC", ""); + + /* RSA is not available via any provider so we expect this to fail */ + if (tst == 0 && !TEST_ptr_null(pctx)) + goto err; + + /* + * HMAC is always available because it is implemented via legacy codepaths + * and not in a provider at all. We expect this to pass. + */ + if (tst == 1 && !TEST_ptr(pctx)) + goto err; + + ret = 1; + + err: + EVP_PKEY_CTX_free(pctx); + OSSL_PROVIDER_unload(nullprov); + OPENSSL_CTX_free(tmpctx); + return ret; +} + int setup_tests(void) { testctx = OPENSSL_CTX_new(); @@ -1636,6 +1752,7 @@ int setup_tests(void) ADD_TEST(test_EVP_DigestVerifyInit); ADD_TEST(test_EVP_Enveloped); ADD_ALL_TESTS(test_d2i_AutoPrivateKey, OSSL_NELEM(keydata)); + ADD_TEST(test_privatekey_to_pkcs8); #ifndef OPENSSL_NO_EC ADD_TEST(test_EVP_PKCS82PKEY); #endif @@ -1657,6 +1774,7 @@ int setup_tests(void) ADD_TEST(test_CMAC_keygen); #endif ADD_TEST(test_HKDF); + ADD_TEST(test_emptyikm_HKDF); #ifndef OPENSSL_NO_EC ADD_TEST(test_X509_PUBKEY_inplace); ADD_ALL_TESTS(test_invalide_ec_char2_pub_range_decode, @@ -1673,6 +1791,7 @@ int setup_tests(void) ADD_TEST(test_EVP_PKEY_set1_DH); #endif ADD_ALL_TESTS(test_keygen_with_empty_template, 2); + ADD_ALL_TESTS(test_pkey_ctx_fail_without_provider, 2); return 1; } diff --git a/test/evp_kdf_test.c b/test/evp_kdf_test.c index 5d807cd5..9a7221df 100644 --- a/test/evp_kdf_test.c +++ b/test/evp_kdf_test.c @@ -21,7 +21,7 @@ static EVP_KDF_CTX *get_kdfbyname(const char *name) { EVP_KDF *kdf = EVP_KDF_fetch(NULL, name, NULL); - EVP_KDF_CTX *kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_CTX *kctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); return kctx; @@ -50,11 +50,11 @@ static int test_kdf_tls1_prf(void) ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_TLS1_PRF)) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0) && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } @@ -80,11 +80,11 @@ static int test_kdf_hkdf(void) ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_HKDF)) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0) && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } @@ -121,10 +121,10 @@ static int test_kdf_pbkdf2(void) *p = OSSL_PARAM_construct_end(); if (!TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_PBKDF2)) - || !TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + || !TEST_true(EVP_KDF_set_ctx_params(kctx, params)) || !TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0) || !TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)) - || !TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + || !TEST_true(EVP_KDF_set_ctx_params(kctx, params)) /* A key length that is too small should fail */ || !TEST_int_eq(EVP_KDF_derive(kctx, out, 112 / 8 - 1), 0) /* A key length that is too large should fail */ @@ -156,7 +156,7 @@ static int test_kdf_pbkdf2(void) #endif ret = 1; err: - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } @@ -191,15 +191,15 @@ static int test_kdf_scrypt(void) ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_SCRYPT)) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) /* failure test *//* && TEST_int_le(EVP_KDF_derive(kctx, out, sizeof(out)), 0)*/ && TEST_true(OSSL_PARAM_set_uint(p - 1, 10 * 1024 * 1024)) - && TEST_true(EVP_KDF_CTX_set_params(kctx, p - 1)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, p - 1)) && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0) && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } #endif /* OPENSSL_NO_SCRYPT */ @@ -235,11 +235,11 @@ static int test_kdf_ss_hash(void) ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_SSKDF)) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0) && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } @@ -289,11 +289,11 @@ static int test_kdf_x963(void) ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_X963KDF)) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0) && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } @@ -345,11 +345,11 @@ static int test_kdf_kbkdf_6803_128(void) kctx = get_kdfbyname("KBKDF"); ret = TEST_ptr(kctx) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, result, sizeof(result)), 0) && TEST_mem_eq(result, sizeof(result), outputs[i], sizeof(outputs[i])); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); if (ret != 1) return ret; } @@ -411,11 +411,11 @@ static int test_kdf_kbkdf_6803_256(void) kctx = get_kdfbyname("KBKDF"); ret = TEST_ptr(kctx) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, result, sizeof(result)), 0) && TEST_mem_eq(result, sizeof(result), outputs[i], sizeof(outputs[i])); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); if (ret != 1) return ret; } @@ -459,11 +459,11 @@ static int test_kdf_kbkdf_8009_prf1(void) kctx = get_kdfbyname("KBKDF"); ret = TEST_ptr(kctx) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, result, sizeof(result)), 0) && TEST_mem_eq(result, sizeof(result), output, sizeof(output)); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } @@ -504,11 +504,11 @@ static int test_kdf_kbkdf_8009_prf2(void) kctx = get_kdfbyname("KBKDF"); ret = TEST_ptr(kctx) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, result, sizeof(result)), 0) && TEST_mem_eq(result, sizeof(result), output, sizeof(output)); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } @@ -547,11 +547,11 @@ static int test_kdf_ss_hmac(void) ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_SSKDF)) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0) && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } @@ -593,11 +593,11 @@ static int test_kdf_ss_kmac(void) ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_SSKDF)) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0) && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } @@ -651,11 +651,11 @@ static int test_kdf_sshkdf(void) ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_SSHKDF)) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0) && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } @@ -725,11 +725,11 @@ static int test_kdf_x942_asn1(void) ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_X942KDF)) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0) && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } #endif /* OPENSSL_NO_CMS */ @@ -763,11 +763,11 @@ static int test_kdf_krb5kdf(void) ret = TEST_ptr(kctx = get_kdfbyname(OSSL_KDF_NAME_KRB5KDF)) - && TEST_true(EVP_KDF_CTX_set_params(kctx, params)) + && TEST_true(EVP_KDF_set_ctx_params(kctx, params)) && TEST_int_gt(EVP_KDF_derive(kctx, out, sizeof(out)), 0) && TEST_mem_eq(out, sizeof(out), expected, sizeof(expected)); - EVP_KDF_CTX_free(kctx); + EVP_KDF_free_ctx(kctx); return ret; } diff --git a/test/evp_pkey_provided_test.c b/test/evp_pkey_provided_test.c index c5ef7241..ffb56cb3 100644 --- a/test/evp_pkey_provided_test.c +++ b/test/evp_pkey_provided_test.c @@ -447,7 +447,7 @@ static int test_fromdata_dh_named_group(void) || !TEST_ptr(pub = BN_bin2bn(pub_data, sizeof(pub_data), NULL)) || !TEST_ptr(priv = BN_bin2bn(priv_data, sizeof(priv_data), NULL)) || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld, - OSSL_PKEY_PARAM_FFC_GROUP, + OSSL_PKEY_PARAM_DH_GROUP, group_name, 0)) || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub)) || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, priv)) @@ -464,7 +464,7 @@ static int test_fromdata_dh_named_group(void) || !TEST_int_eq(EVP_PKEY_size(pk), 256)) goto err; - if (!TEST_true(EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_FFC_GROUP, + if (!TEST_true(EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_DH_GROUP, name_out, sizeof(name_out), &len)) || !TEST_str_eq(name_out, group_name) @@ -588,7 +588,7 @@ static int test_fromdata_dh_fips186_4(void) || !TEST_ptr(pub = BN_bin2bn(pub_data, sizeof(pub_data), NULL)) || !TEST_ptr(priv = BN_bin2bn(priv_data, sizeof(priv_data), NULL)) || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld, - OSSL_PKEY_PARAM_FFC_GROUP, + OSSL_PKEY_PARAM_DH_GROUP, group_name, 0)) || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub)) || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, priv)) @@ -605,7 +605,7 @@ static int test_fromdata_dh_fips186_4(void) || !TEST_int_eq(EVP_PKEY_size(pk), 256)) goto err; - if (!TEST_true(EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_FFC_GROUP, + if (!TEST_true(EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_DH_GROUP, name_out, sizeof(name_out), &len)) || !TEST_str_eq(name_out, group_name) @@ -855,7 +855,8 @@ static int test_fromdata_ecx(int tst) goto err; if (!TEST_ptr(copy_pk = EVP_PKEY_new()) - || !TEST_false(EVP_PKEY_copy_parameters(copy_pk, pk))) + /* This should succeed because there are no parameters to copy */ + || !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk))) goto err; if (!TEST_true(EVP_PKEY_get_octet_string_param( @@ -1143,7 +1144,7 @@ static int test_fromdata_dsa_fips186_4(void) || !TEST_int_eq(EVP_PKEY_size(pk), 2 + 2 * (3 + sizeof(q_data)))) goto err; - if (!TEST_false(EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_FFC_GROUP, + if (!TEST_false(EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_DH_GROUP, name_out, sizeof(name_out), &len)) || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PUB_KEY, diff --git a/test/evp_test.c b/test/evp_test.c index 6727a007..ef5d9500 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -1323,12 +1323,12 @@ static int mac_test_run_mac(EVP_TEST *t) } params[params_n] = OSSL_PARAM_construct_end(); - if ((ctx = EVP_MAC_CTX_new(expected->mac)) == NULL) { + if ((ctx = EVP_MAC_new_ctx(expected->mac)) == NULL) { t->err = "MAC_CREATE_ERROR"; goto err; } - if (!EVP_MAC_CTX_set_params(ctx, params)) { + if (!EVP_MAC_set_ctx_params(ctx, params)) { t->err = "MAC_BAD_PARAMS"; goto err; } @@ -1360,7 +1360,7 @@ static int mac_test_run_mac(EVP_TEST *t) while (params_n-- > params_n_allocstart) { OPENSSL_free(params[params_n].data); } - EVP_MAC_CTX_free(ctx); + EVP_MAC_free_ctx(ctx); OPENSSL_free(got); return 1; } @@ -2095,7 +2095,7 @@ static int kdf_test_init(EVP_TEST *t, const char *name) OPENSSL_free(kdata); return 0; } - kdata->ctx = EVP_KDF_CTX_new(kdf); + kdata->ctx = EVP_KDF_new_ctx(kdf); EVP_KDF_free(kdf); if (kdata->ctx == NULL) { OPENSSL_free(kdata); @@ -2113,7 +2113,7 @@ static void kdf_test_cleanup(EVP_TEST *t) for (p = kdata->params; p->key != NULL; p++) OPENSSL_free(p->data); OPENSSL_free(kdata->output); - EVP_KDF_CTX_free(kdata->ctx); + EVP_KDF_free_ctx(kdata->ctx); } static int kdf_test_ctrl(EVP_TEST *t, EVP_KDF_CTX *kctx, @@ -2122,7 +2122,8 @@ static int kdf_test_ctrl(EVP_TEST *t, EVP_KDF_CTX *kctx, KDF_DATA *kdata = t->data; int rv; char *p, *name; - const OSSL_PARAM *defs = EVP_KDF_settable_ctx_params(EVP_KDF_CTX_kdf(kctx)); + const OSSL_PARAM *defs = + EVP_KDF_settable_ctx_params(EVP_KDF_get_ctx_kdf(kctx)); if (!TEST_ptr(name = OPENSSL_strdup(value))) return 0; @@ -2178,7 +2179,7 @@ static int kdf_test_run(EVP_TEST *t) unsigned char *got = NULL; size_t got_len = expected->output_len; - if (!EVP_KDF_CTX_set_params(expected->ctx, expected->params)) { + if (!EVP_KDF_set_ctx_params(expected->ctx, expected->params)) { t->err = "KDF_CTRL_ERROR"; return 1; } @@ -2404,7 +2405,7 @@ static int keypair_test_run(EVP_TEST *t) goto end; } - if ((rv = EVP_PKEY_cmp(pair->privk, pair->pubk)) != 1 ) { + if ((rv = EVP_PKEY_eq(pair->privk, pair->pubk)) != 1 ) { if ( 0 == rv ) { t->err = "KEYPAIR_MISMATCH"; } else if ( -1 == rv ) { @@ -2995,7 +2996,8 @@ static int key_unsupported(void) long err = ERR_peek_error(); if (ERR_GET_LIB(err) == ERR_LIB_EVP - && ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_ALGORITHM) { + && (ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_ALGORITHM + || ERR_GET_REASON(err) == EVP_R_FETCH_FAILED)) { ERR_clear_error(); return 1; } diff --git a/test/exdatatest.c b/test/exdatatest.c index 3ce6d33c..8dd9261d 100644 --- a/test/exdatatest.c +++ b/test/exdatatest.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -37,7 +37,7 @@ static void exnew(void *parent, void *ptr, CRYPTO_EX_DATA *ad, } static int exdup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, - void *from_d, int idx, long argl, void *argp) + void **from_d, int idx, long argl, void *argp) { if (!TEST_int_eq(idx, saved_idx) || !TEST_long_eq(argl, saved_argl) @@ -87,7 +87,7 @@ static void exnew2(void *parent, void *ptr, CRYPTO_EX_DATA *ad, } static int exdup2(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, - void *from_d, int idx, long argl, void *argp) + void **from_d, int idx, long argl, void *argp) { MYOBJ_EX_DATA **update_ex_data = (MYOBJ_EX_DATA**)from_d; MYOBJ_EX_DATA *ex_data = NULL; diff --git a/test/filterprov.c b/test/filterprov.c new file mode 100644 index 00000000..9fe6690e --- /dev/null +++ b/test/filterprov.c @@ -0,0 +1,199 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * A filtering provider for test purposes. We pass all calls through to the + * default provider except where we want other behaviour for a test. + */ + +#include +#include +#include +#include +#include + +OSSL_provider_init_fn filter_provider_init; + +int filter_provider_set_filter(int operation, const char *name); + +#define MAX_FILTERS 10 +#define MAX_ALG_FILTERS 5 + +struct filter_prov_globals_st { + OPENSSL_CTX *libctx; + OSSL_PROVIDER *deflt; + struct { + int operation; + OSSL_ALGORITHM alg[MAX_ALG_FILTERS + 1]; + } dispatch[MAX_FILTERS]; + int num_dispatch; +}; + +static struct filter_prov_globals_st ourglobals; + +static struct filter_prov_globals_st *get_globals(void) +{ + /* + * Ideally we'd like to store this in the OPENSSL_CTX so that we can have + * more than one instance of the filter provider at a time. But for now we + * just make it simple. + */ + return &ourglobals; +} + +static OSSL_provider_gettable_params_fn filter_gettable_params; +static OSSL_provider_get_params_fn filter_get_params; +static OSSL_provider_query_operation_fn filter_query; +static OSSL_provider_teardown_fn filter_teardown; + +static const OSSL_PARAM *filter_gettable_params(void *provctx) +{ + struct filter_prov_globals_st *globs = get_globals(); + + return OSSL_PROVIDER_gettable_params(globs->deflt); +} + +static int filter_get_params(void *provctx, OSSL_PARAM params[]) +{ + struct filter_prov_globals_st *globs = get_globals(); + + return OSSL_PROVIDER_get_params(globs->deflt, params); +} + +static const OSSL_ALGORITHM *filter_query(void *provctx, + int operation_id, + int *no_cache) +{ + struct filter_prov_globals_st *globs = get_globals(); + int i; + + for (i = 0; i < globs->num_dispatch; i++) { + if (globs->dispatch[i].operation == operation_id) { + *no_cache = 0; + return globs->dispatch[i].alg; + } + } + + /* No filter set, so pass it down to the chained provider */ + return OSSL_PROVIDER_query_operation(globs->deflt, operation_id, no_cache); +} + +static void filter_teardown(void *provctx) +{ + struct filter_prov_globals_st *globs = get_globals(); + + OSSL_PROVIDER_unload(globs->deflt); + OPENSSL_CTX_free(globs->libctx); +} + +/* Functions we provide to the core */ +static const OSSL_DISPATCH filter_dispatch_table[] = { + { OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))filter_gettable_params }, + { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))filter_get_params }, + { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))filter_query }, + { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))filter_teardown }, + { 0, NULL } +}; + +int filter_provider_init(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in, + const OSSL_DISPATCH **out, + void **provctx) +{ + memset(&ourglobals, 0, sizeof(ourglobals)); + ourglobals.libctx = OPENSSL_CTX_new(); + if (ourglobals.libctx == NULL) + goto err; + + ourglobals.deflt = OSSL_PROVIDER_load(ourglobals.libctx, "default"); + if (ourglobals.deflt == NULL) + goto err; + + *provctx = OSSL_PROVIDER_get0_provider_ctx(ourglobals.deflt); + *out = filter_dispatch_table; + return 1; + + err: + OSSL_PROVIDER_unload(ourglobals.deflt); + OPENSSL_CTX_free(ourglobals.libctx); + return 0; +} + +/* + * Set a filter for the given operation id. The filter string is a colon + * separated list of algorithms that will be made available by this provider. + * Anything not in the filter will be suppressed. If a filter is not set for + * a given operation id then all algorithms are made available. + */ +int filter_provider_set_filter(int operation, const char *filterstr) +{ + int no_cache = 0; + int algnum = 0, last = 0, ret = 0; + struct filter_prov_globals_st *globs = get_globals(); + size_t namelen; + char *filterstrtmp = OPENSSL_strdup(filterstr); + char *name, *sep; + const OSSL_ALGORITHM *provalgs = OSSL_PROVIDER_query_operation(globs->deflt, + operation, + &no_cache); + const OSSL_ALGORITHM *algs; + + if (filterstrtmp == NULL) + goto err; + + /* We don't support no_cache */ + if (no_cache) + goto err; + + /* Nothing to filter */ + if (provalgs == NULL) + goto err; + + if (globs->num_dispatch >= MAX_FILTERS) + goto err; + + for (name = filterstrtmp; !last; name = sep + 1) { + sep = strstr(name, ":"); + if (sep != NULL) + *sep = '\0'; + else + last = 1; + namelen = strlen(name); + + for (algs = provalgs; algs->algorithm_names != NULL; algs++) { + const char *found = strstr(algs->algorithm_names, name); + + if (found == NULL) + continue; + if (found[namelen] != '\0' && found[namelen] != ':') + continue; + if (found != algs->algorithm_names && found[-1] != ':') + continue; + + /* We found a match */ + if (algnum >= MAX_ALG_FILTERS) + goto err; + + globs->dispatch[globs->num_dispatch].alg[algnum++] = *algs; + break; + } + if (algs->algorithm_names == NULL) { + /* No match found */ + goto err; + } + } + + globs->dispatch[globs->num_dispatch].operation = operation; + globs->num_dispatch++; + + ret = 1; + err: + OPENSSL_free(filterstrtmp); + return ret; +} diff --git a/test/handshake_helper.c b/test/handshake_helper.c index 32aa12c4..2dfded5c 100644 --- a/test/handshake_helper.c +++ b/test/handshake_helper.c @@ -641,7 +641,8 @@ static int configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, } if (extra->client.alpn_protocols != NULL) { unsigned char *alpn_protos = NULL; - size_t alpn_protos_len; + size_t alpn_protos_len = 0; + if (!TEST_true(parse_protos(extra->client.alpn_protocols, &alpn_protos, &alpn_protos_len)) /* Reversed return value convention... */ @@ -938,16 +939,24 @@ static void do_reneg_setup_step(const SSL_TEST_CTX *test_ctx, PEER *peer) if (SSL_is_server(peer->ssl)) { ret = SSL_renegotiate(peer->ssl); } else { + int full_reneg = 0; + + if (test_ctx->extra.client.no_extms_on_reneg) { + SSL_set_options(peer->ssl, SSL_OP_NO_EXTENDED_MASTER_SECRET); + full_reneg = 1; + } if (test_ctx->extra.client.reneg_ciphers != NULL) { if (!SSL_set_cipher_list(peer->ssl, test_ctx->extra.client.reneg_ciphers)) { peer->status = PEER_ERROR; return; } - ret = SSL_renegotiate(peer->ssl); - } else { - ret = SSL_renegotiate_abbreviated(peer->ssl); + full_reneg = 1; } + if (full_reneg) + ret = SSL_renegotiate(peer->ssl); + else + ret = SSL_renegotiate_abbreviated(peer->ssl); } if (!ret) { peer->status = PEER_ERROR; diff --git a/test/hexstr_test.c b/test/hexstr_test.c new file mode 100644 index 00000000..c4f13b6d --- /dev/null +++ b/test/hexstr_test.c @@ -0,0 +1,133 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * https://www.openssl.org/source/license.html + * or in the file LICENSE in the source distribution. + */ + +/* + * This program tests the use of OSSL_PARAM, currently in raw form. + */ + +#include "internal/nelem.h" +#include "internal/cryptlib.h" +#include "testutil.h" + +struct testdata +{ + const char *in; + const unsigned char *expected; + size_t expected_len; + const char sep; +}; + +static const unsigned char test_1[] = { 0xAB, 0xCD, 0xEF, 0xF1 }; +static const unsigned char test_2[] = { 0xAB, 0xCD, 0xEF, 0x76, 0x00 }; + +static struct testdata tbl_testdata[] = { + { + "AB:CD:EF:F1", + test_1, sizeof(test_1), + ':', + }, + { + "AB:CD:EF:76:00", + test_2, sizeof(test_2), + ':', + }, + { + "AB_CD_EF_F1", + test_1, sizeof(test_1), + '_', + }, + { + "AB_CD_EF_76_00", + test_2, sizeof(test_2), + '_', + }, + { + "ABCDEFF1", + test_1, sizeof(test_1), + '\0', + }, + { + "ABCDEF7600", + test_2, sizeof(test_2), + '\0', + }, +}; + +static int test_hexstr_sep_to_from(int test_index) +{ + int ret = 0; + long len = 0; + unsigned char *buf = NULL; + char *out = NULL; + struct testdata *test = &tbl_testdata[test_index]; + + if (!TEST_ptr(buf = openssl_hexstr2buf_sep(test->in, &len, test->sep)) + || !TEST_mem_eq(buf, len, test->expected, test->expected_len) + || !TEST_ptr(out = openssl_buf2hexstr_sep(buf, len, test->sep)) + || !TEST_str_eq(out, test->in)) + goto err; + + ret = 1; +err: + OPENSSL_free(buf); + OPENSSL_free(out); + return ret; +} + +static int test_hexstr_to_from(int test_index) +{ + int ret = 0; + long len = 0; + unsigned char *buf = NULL; + char *out = NULL; + struct testdata *test = &tbl_testdata[test_index]; + + if (test->sep != '_') { + if (!TEST_ptr(buf = OPENSSL_hexstr2buf(test->in, &len)) + || !TEST_mem_eq(buf, len, test->expected, test->expected_len) + || !TEST_ptr(out = OPENSSL_buf2hexstr(buf, len))) + goto err; + if (test->sep == ':') { + if (!TEST_str_eq(out, test->in)) + goto err; + } else if (!TEST_str_ne(out, test->in)) { + goto err; + } + } else { + if (!TEST_ptr_null(buf = OPENSSL_hexstr2buf(test->in, &len))) + goto err; + } + ret = 1; +err: + OPENSSL_free(buf); + OPENSSL_free(out); + return ret; +} + +static int test_hexstr_ex_to_from(int test_index) +{ + size_t len = 0; + char out[64]; + unsigned char buf[64]; + struct testdata *test = &tbl_testdata[test_index]; + + return TEST_true(OPENSSL_hexstr2buf_ex(buf, sizeof(buf), &len, test->in)) + && TEST_mem_eq(buf, len, test->expected, test->expected_len) + && TEST_true(OPENSSL_buf2hexstr_ex(out, sizeof(out), NULL, buf, len)) + && TEST_str_eq(out, test->in); +} + +int setup_tests(void) +{ + ADD_ALL_TESTS(test_hexstr_sep_to_from, OSSL_NELEM(tbl_testdata)); + ADD_ALL_TESTS(test_hexstr_to_from, OSSL_NELEM(tbl_testdata)); + ADD_ALL_TESTS(test_hexstr_ex_to_from, 2); + return 1; +} diff --git a/test/http_test.c b/test/http_test.c deleted file mode 100644 index f0b12a7d..00000000 --- a/test/http_test.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. - * Copyright Siemens AG 2020 - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include - -#include "testutil.h" - -DEFINE_STACK_OF(CONF_VALUE) - -static const ASN1_ITEM *x509_it = NULL; -static X509 *x509 = NULL; -#define SERVER "mock.server" -#define PORT "81" -#define RPATH "path/any.crt" -static const char *rpath; - -static X509 *load_pem_cert(const char *file) -{ - X509 *cert = NULL; - BIO *bio = NULL; - - if (!TEST_ptr(bio = BIO_new(BIO_s_file()))) - return NULL; - if (TEST_int_gt(BIO_read_filename(bio, file), 0)) - (void)TEST_ptr(cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)); - - BIO_free(bio); - return cert; -} - -/* - * pretty trivial HTTP mock server: - * for POST, copy request headers+body from mem BIO 'in' as response to 'out' - * for GET, first redirect the request then respond with 'rsp' of ASN1 type 'it' - */ -static int mock_http_server(BIO *in, BIO *out, - ASN1_VALUE *rsp, const ASN1_ITEM *it) -{ - const char *req; - long count = BIO_get_mem_data(in, (unsigned char **)&req); - const char *hdr = (char *)req; - int is_get = count >= 4 && strncmp(hdr, "GET ", 4) == 0; - int len; - - /* first line should contain " HTTP/1.x" */ - if (is_get) - hdr += 4; - else if (TEST_true(count >= 5 && strncmp(hdr, "POST ", 5) == 0)) - hdr += 5; - else - return 0; - - while (*rpath == '/') - rpath++; - while (*hdr == '/') - hdr++; - len = strlen(rpath); - if (!TEST_strn_eq(hdr, rpath, len) || !TEST_char_eq(hdr++[len], ' ')) - return 0; - hdr += len; - len = strlen("HTTP/1."); - if (!TEST_strn_eq(hdr, "HTTP/1.", len)) - return 0; - hdr += len; - /* check for HTTP version 1.0 .. 1.1 */ - if (!TEST_char_le('0', *hdr) || !TEST_char_le(*hdr++, '1')) - return 0; - if (!TEST_char_eq(*hdr++, '\r') || !TEST_char_eq(*hdr++, '\n')) - return 0; - count -= (hdr - req); - if (count <= 0 || out == NULL) - return 0; - - if (is_get && strcmp(rpath, RPATH) == 0) { - rpath = "path/new.crt"; - return BIO_printf(out, "HTTP/1.1 301 Moved Permanently\r\n" - "Location: /%s\r\n\r\n", rpath) > 0; /* same server */ - } - if (BIO_printf(out, "HTTP/1.1 200 OK\r\n") <= 0) - return 0; - if (is_get) { /* construct new header and body */ - if ((len = ASN1_item_i2d(rsp, NULL, it)) <= 0) - return 0; - if (BIO_printf(out, "Content-Type: application/x-x509-ca-cert\r\n" - "Content-Length: %d\r\n\r\n", len) <= 0) - return 0; - return ASN1_item_i2d_bio(it, out, rsp); - } else { - return BIO_write(out, hdr, count) == count; /* echo header and body */ - } -} - -static long http_bio_cb_ex(BIO *bio, int oper, const char *argp, size_t len, - int cmd, long argl, int ret, size_t *processed) -{ - - if (oper == (BIO_CB_CTRL | BIO_CB_RETURN) && cmd == BIO_CTRL_FLUSH) - ret = mock_http_server(bio, (BIO *)BIO_get_callback_arg(bio), - (ASN1_VALUE *)x509, x509_it); - return ret; -} - -static int test_http_x509(int do_get) -{ - X509 *rcert = NULL; - BIO *wbio = BIO_new(BIO_s_mem()); - BIO *rbio = BIO_new(BIO_s_mem()); - STACK_OF(CONF_VALUE) *headers = NULL; - int res = 0; - - if (wbio == NULL || rbio == NULL) - goto err; - BIO_set_callback_ex(wbio, http_bio_cb_ex); - BIO_set_callback_arg(wbio, (char *)rbio); - - rpath = RPATH; - rcert = (X509 *) - (do_get ? - OSSL_HTTP_get_asn1("http://"SERVER":"PORT"/"RPATH, - NULL /* proxy */, NULL /* no_proxy */, - wbio, rbio, NULL /* bio_update_fn */, NULL, - headers, 0 /* maxline */, - 0 /* max_resp_len */, 0 /* timeout */, - "application/x-x509-ca-cert", x509_it) - : - OSSL_HTTP_post_asn1(SERVER, PORT, RPATH, 0 /* use_ssl */, - NULL /* proxy */, NULL /* no_proxy */, - wbio, rbio, NULL /* bio_update_fn */, NULL, - headers, "application/x-x509-ca-cert", - (ASN1_VALUE *)x509, x509_it, 0 /* maxline */, - 0 /* max_resp_len */, 0 /* timeout */, - "application/x-x509-ca-cert", x509_it) - ); - res = TEST_ptr(rcert) && TEST_int_eq(X509_cmp(x509, rcert), 0); - - err: - X509_free(rcert); - BIO_free(wbio); - BIO_free(rbio); - sk_CONF_VALUE_pop_free(headers, X509V3_conf_free); - return res; -} - -static int test_http_get_x509(void) -{ - return test_http_x509(1); -} - -static int test_http_post_x509(void) -{ - return test_http_x509(0); -} - -void cleanup_tests(void) -{ - X509_free(x509); -} - -int setup_tests(void) -{ - if (!test_skip_common_options()) { - TEST_error("Error parsing test options\n"); - return 0; - } - - x509_it = ASN1_ITEM_rptr(X509); - if (!TEST_ptr((x509 = load_pem_cert(test_get_argument(0))))) - return 1; - - ADD_TEST(test_http_get_x509); - ADD_TEST(test_http_post_x509); - return 1; -} diff --git a/test/ossl_shim/ossl_shim.cc b/test/ossl_shim/ossl_shim.cc index ea1ff3a9..0184778d 100644 --- a/test/ossl_shim/ossl_shim.cc +++ b/test/ossl_shim/ossl_shim.cc @@ -1,5 +1,5 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -39,6 +39,7 @@ OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib")) #include #include #include +#include #include #include #include @@ -370,8 +371,10 @@ static int NewSessionCallback(SSL *ssl, SSL_SESSION *session) { } static int TicketKeyCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv, - EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx, + EVP_CIPHER_CTX *ctx, EVP_MAC_CTX *hmac_ctx, int encrypt) { + OSSL_PARAM params[3], *p = params; + if (!encrypt) { if (GetTestState(ssl)->ticket_decrypt_done) { fprintf(stderr, "TicketKeyCallback called after completion.\n"); @@ -391,8 +394,16 @@ static int TicketKeyCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv, return 0; } - if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) || - !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) { + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, + const_cast("SHA256"), 0); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + (void *)kZeros, + sizeof(kZeros)); + *p = OSSL_PARAM_construct_end(); + + if (!EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt) + || !EVP_MAC_init(hmac_ctx) + || !EVP_MAC_set_ctx_params(hmac_ctx, params)) { return -1; } @@ -625,7 +636,7 @@ static bssl::UniquePtr SetupCtx(const TestConfig *config) { SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback); if (config->use_ticket_callback) { - SSL_CTX_set_tlsext_ticket_key_cb(ssl_ctx.get(), TicketKeyCallback); + SSL_CTX_set_tlsext_ticket_key_evp_cb(ssl_ctx.get(), TicketKeyCallback); } if (config->enable_client_custom_extension && diff --git a/test/ossl_shim/test_config.h b/test/ossl_shim/test_config.h index 83677df5..6dc73194 100644 --- a/test/ossl_shim/test_config.h +++ b/test/ossl_shim/test_config.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,6 +13,8 @@ #include #include +#include + struct TestConfig { int port = 0; diff --git a/test/provider_fallback_test.c b/test/provider_fallback_test.c new file mode 100644 index 00000000..ce621845 --- /dev/null +++ b/test/provider_fallback_test.c @@ -0,0 +1,57 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "testutil.h" + +static int test_provider(OPENSSL_CTX *ctx) +{ + EVP_KEYMGMT *rsameth = NULL; + const OSSL_PROVIDER *prov = NULL; + int ok; + + ok = TEST_true(OSSL_PROVIDER_available(ctx, "default")) + && TEST_ptr(rsameth = EVP_KEYMGMT_fetch(ctx, "RSA", NULL)) + && TEST_ptr(prov = EVP_KEYMGMT_provider(rsameth)) + && TEST_str_eq(OSSL_PROVIDER_name(prov), "default"); + + EVP_KEYMGMT_free(rsameth); + return ok; +} + +static int test_fallback_provider(void) +{ + return test_provider(NULL); +} + +static int test_explicit_provider(void) +{ + OPENSSL_CTX *ctx = NULL; + OSSL_PROVIDER *prov = NULL; + int ok; + + ok = TEST_ptr(ctx = OPENSSL_CTX_new()) + && TEST_ptr(prov = OSSL_PROVIDER_load(ctx, "default")) + && test_provider(ctx) + && TEST_true(OSSL_PROVIDER_unload(prov)); + + OPENSSL_CTX_free(ctx); + return ok; +} + + +int setup_tests(void) +{ + ADD_TEST(test_fallback_provider); + ADD_TEST(test_explicit_provider); + return 1; +} + diff --git a/test/proxy.cnf b/test/proxy.cnf new file mode 100644 index 00000000..e6b60542 --- /dev/null +++ b/test/proxy.cnf @@ -0,0 +1,61 @@ + +## Config file for proxy certificate testing. + +[ req ] +default_bits = 2048 +default_keyfile = keySS.pem +distinguished_name = req_distinguished_name_p1 +encrypt_rsa_key = no +default_md = sha256 + +[ req_distinguished_name_p1 ] +countryName = Country Name (2 letter code) +countryName_value = AU +organizationName = Organization Name (eg, company) +organizationName_value = Dodgy Brothers +0.commonName = Common Name (eg, YOUR name) +0.commonName_value = Brother 1 +1.commonName = Common Name (eg, YOUR name) +1.commonName_value = Brother 2 +2.commonName = Common Name (eg, YOUR name) +2.commonName_value = Proxy 1 + +[ proxy ] +basicConstraints = CA:FALSE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +proxyCertInfo = critical,language:id-ppl-anyLanguage,pathlen:1,policy:text:AB + +#################################################################### + +[ proxy2_req ] +default_bits = 2048 +default_keyfile = keySS.pem +distinguished_name = req_distinguished_name_p2 +encrypt_rsa_key = no +default_md = sha256 + +[ req_distinguished_name_p2 ] +countryName = Country Name (2 letter code) +countryName_value = AU +organizationName = Organization Name (eg, company) +organizationName_value = Dodgy Brothers +0.commonName = Common Name (eg, YOUR name) +0.commonName_value = Brother 1 +1.commonName = Common Name (eg, YOUR name) +1.commonName_value = Brother 2 +2.commonName = Common Name (eg, YOUR name) +2.commonName_value = Proxy 1 +3.commonName = Common Name (eg, YOUR name) +3.commonName_value = Proxy 2 + +[ proxy_2 ] +basicConstraints = CA:FALSE +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +proxyCertInfo = critical,@proxy_ext + +[ proxy_ext ] +language = id-ppl-anyLanguage +pathlen = 0 +policy = text:BC diff --git a/test/recipes/80-test_http.t b/test/recipes/04-test_hexstring.t similarity index 56% rename from test/recipes/80-test_http.t rename to test/recipes/04-test_hexstring.t index 2297c5a5..664868fe 100644 --- a/test/recipes/80-test_http.t +++ b/test/recipes/04-test_hexstring.t @@ -6,16 +6,10 @@ # in the file LICENSE in the source distribution or at # https://www.openssl.org/source/license.html +use strict; +use OpenSSL::Test; +use OpenSSL::Test::Simple; -use OpenSSL::Test qw/:DEFAULT srctop_file/; -use OpenSSL::Test::Utils; +setup("test_hexstring"); -setup("test_http"); - -plan tests => 1; - -SKIP: { - skip "sockets disabled", 1 if disabled("sock"); - ok(run(test(["http_test", - srctop_file("test", "certs", "ca-cert.pem")]))); -} +simple_test("test_hexstring", "hexstr_test"); diff --git a/test/recipes/04-test_provider_fallback.t b/test/recipes/04-test_provider_fallback.t new file mode 100644 index 00000000..39d3b105 --- /dev/null +++ b/test/recipes/04-test_provider_fallback.t @@ -0,0 +1,18 @@ +#! /usr/bin/env perl +# Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use File::Spec; +use OpenSSL::Test::Simple; + +# We must ensure that OPENSSL_CONF points at an empty file. Otherwise, we +# risk that the configuration file contains statements that load providers, +# which defeats the purpose of this test. The NUL device is good enough. +$ENV{OPENSSL_CONF} = File::Spec->devnull(); + +simple_test("test_provider_fallback", "provider_fallback_test"); diff --git a/test/recipes/05-test_cmac.t b/test/recipes/05-test_cmac.t new file mode 100644 index 00000000..499f713f --- /dev/null +++ b/test/recipes/05-test_cmac.t @@ -0,0 +1,12 @@ +#! /usr/bin/env perl +# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +use OpenSSL::Test::Simple; + +simple_test("test_cmac", "cmactest", "cmac"); diff --git a/test/recipes/15-test_genrsa.t b/test/recipes/15-test_genrsa.t index d1b2130d..17b0cbc1 100644 --- a/test/recipes/15-test_genrsa.t +++ b/test/recipes/15-test_genrsa.t @@ -16,10 +16,18 @@ use OpenSSL::Test::Utils; setup("test_genrsa"); -plan tests => 5; +plan tests => 12; # We want to know that an absurdly small number of bits isn't support -is(run(app([ 'openssl', 'genrsa', '-3', '-out', 'genrsatest.pem', '8'])), 0, "genrsa -3 8"); +if (disabled("deprecated-3.0")) { + is(run(app([ 'openssl', 'genpkey', '-out', 'genrsatest.pem', + '-algorithm', 'RSA', '-pkeyopt', 'rsa_keygen_bits:8', + '-pkeyopt', 'rsa_keygen_pubexp:3'])), + 0, "genrsa -3 8"); +} else { + is(run(app([ 'openssl', 'genrsa', '-3', '-out', 'genrsatest.pem', '8'])), + 0, "genrsa -3 8"); +} # Depending on the shared library, we might have different lower limits. # Let's find it! This is a simple binary search @@ -29,10 +37,21 @@ is(run(app([ 'openssl', 'genrsa', '-3', '-out', 'genrsatest.pem', '8'])), 0, "ge note "Looking for lowest amount of bits"; my $bad = 3; # Log2 of number of bits (2 << 3 == 8) my $good = 11; # Log2 of number of bits (2 << 11 == 2048) +my $fin; while ($good > $bad + 1) { my $checked = int(($good + $bad + 1) / 2); - if (run(app([ 'openssl', 'genrsa', '-3', '-out', 'genrsatest.pem', - 2 ** $checked ], stderr => undef))) { + my $bits = 2 ** $checked; + if (disabled("deprecated-3.0")) { + $fin = run(app([ 'openssl', 'genpkey', '-out', 'genrsatest.pem', + '-algorithm', 'RSA', '-pkeyopt', 'rsa_keygen_pubexp:65537', + '-pkeyopt', "rsa_keygen_bits:$bits", + ], stderr => undef)); + } else { + $fin = run(app([ 'openssl', 'genrsa', '-3', '-out', 'genrsatest.pem', + $bits + ], stderr => undef)); + } + if ($fin) { note 2 ** $checked, " bits is good"; $good = $checked; } else { @@ -44,11 +63,45 @@ $good++ if $good == $bad; $good = 2 ** $good; note "Found lowest allowed amount of bits to be $good"; -ok(run(app([ 'openssl', 'genrsa', '-3', '-out', 'genrsatest.pem', $good ])), - "genrsa -3 $good"); -ok(run(app([ 'openssl', 'rsa', '-check', '-in', 'genrsatest.pem', '-noout' ])), - "rsa -check"); -ok(run(app([ 'openssl', 'genrsa', '-f4', '-out', 'genrsatest.pem', $good ])), - "genrsa -f4 $good"); -ok(run(app([ 'openssl', 'rsa', '-check', '-in', 'genrsatest.pem', '-noout' ])), - "rsa -check"); +ok(run(app([ 'openssl', 'genpkey', '-algorithm', 'RSA', + '-pkeyopt', 'rsa_keygen_pubexp:65537', + '-pkeyopt', "rsa_keygen_bits:$good", + '-out', 'genrsatest.pem' ])), + "genpkey -3 $good"); +ok(run(app([ 'openssl', 'pkey', '-check', '-in', 'genrsatest.pem', '-noout' ])), + "pkey -check"); +ok(run(app([ 'openssl', 'genpkey', '-algorithm', 'RSA', + '-pkeyopt', 'rsa_keygen_pubexp:65537', + '-pkeyopt', "rsa_keygen_bits:$good", + '-out', 'genrsatest.pem' ])), + "genpkey -f4 $good"); + +ok(run(app([ 'openssl', 'genpkey', '-algorithm', 'RSA', + '-pkeyopt', 'rsa_keygen_bits:2048', + '-out', 'genrsatest2048.pem' ])), + "genpkey 2048 bits"); +ok(run(app([ 'openssl', 'pkey', '-check', '-in', 'genrsatest2048.pem', '-noout' ])), + "pkey -check"); + +ok(!run(app([ 'openssl', 'genpkey', '-algorithm', 'RSA', + '-pkeyopt', 'hexe:02', + '-out', 'genrsatest.pem' ])), + "genpkey with a bad public exponent should fail"); +ok(!run(app([ 'openssl', 'genpkey', '-algorithm', 'RSA', + '-pkeyopt', 'e:65538', + '-out', 'genrsatest.pem' ])), + "genpkey with a even public exponent should fail"); + + + SKIP: { + skip "Skipping rsa command line test", 4 if disabled("deprecated-3.0"); + + ok(run(app([ 'openssl', 'genrsa', '-3', '-out', 'genrsatest.pem', $good ])), + "genrsa -3 $good"); + ok(run(app([ 'openssl', 'rsa', '-check', '-in', 'genrsatest.pem', '-noout' ])), + "rsa -check"); + ok(run(app([ 'openssl', 'genrsa', '-f4', '-out', 'genrsatest.pem', $good ])), + "genrsa -f4 $good"); + ok(run(app([ 'openssl', 'rsa', '-check', '-in', 'genrsatest.pem', '-noout' ])), + "rsa -check"); +} diff --git a/test/recipes/25-test_verify_store.t b/test/recipes/25-test_verify_store.t index c8c57a7b..920b608a 100644 --- a/test/recipes/25-test_verify_store.t +++ b/test/recipes/25-test_verify_store.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -18,34 +18,31 @@ plan tests => 10; my $dummycnf = srctop_file("apps", "openssl.cnf"); +my $cnf = srctop_file("test", "ca-and-certs.cnf"); my $CAkey = "keyCA.ss"; my $CAcert="certCA.ss"; my $CAserial="certCA.srl"; my $CAreq="reqCA.ss"; -my $CAconf=srctop_file("test","CAss.cnf"); my $CAreq2="req2CA.ss"; # temp - -my $Uconf=srctop_file("test","Uss.cnf"); my $Ukey="keyU.ss"; my $Ureq="reqU.ss"; my $Ucert="certU.ss"; SKIP: { req( 'make cert request', - qw(-new), - -config => $CAconf, + qw(-new -section userreq), + -config => $cnf, -out => $CAreq, -keyout => $CAkey ); skip 'failure', 8 unless x509( 'convert request into self-signed cert', - qw(-req -CAcreateserial), + qw(-req -CAcreateserial -days 30), + qw(-extensions v3_ca), -in => $CAreq, -out => $CAcert, -signkey => $CAkey, - -days => 30, - -extfile => $CAconf, - -extensions => 'v3_ca' ); + -extfile => $cnf ); skip 'failure', 7 unless x509( 'convert cert into a cert request', @@ -56,13 +53,13 @@ SKIP: { skip 'failure', 6 unless req( 'verify request 1', - qw(-verify -noout), + qw(-verify -noout -section userreq), -config => $dummycnf, -in => $CAreq ); skip 'failure', 5 unless req( 'verify request 2', - qw(-verify -noout), + qw(-verify -noout -section userreq), -config => $dummycnf, -in => $CAreq2 ); @@ -73,29 +70,27 @@ SKIP: { skip 'failure', 3 unless req( 'make a user cert request', - qw(-new), - -config => $Uconf, + qw(-new -section userreq), + -config => $cnf, -out => $Ureq, -keyout => $Ukey ); skip 'failure', 2 unless x509( 'sign user cert request', - qw(-req -CAcreateserial), + qw(-req -CAcreateserial -days 30 -extensions v3_ee), -in => $Ureq, -out => $Ucert, -CA => $CAcert, -CAkey => $CAkey, -CAserial => $CAserial, - -days => 30, - -extfile => $Uconf, - -extensions => 'v3_ee' ) + -extfile => $cnf ) && verify( undef, -CAstore => $CAcert, $Ucert ); skip 'failure', 0 unless x509( 'Certificate details', - qw( -subject -issuer -startdate -enddate -noout), + qw(-subject -issuer -startdate -enddate -noout), -in => $Ucert ); } diff --git a/test/recipes/30-test_evp_data/evpciph.txt b/test/recipes/30-test_evp_data/evpciph.txt index 4d7f9f0d..4f7afd0e 100644 --- a/test/recipes/30-test_evp_data/evpciph.txt +++ b/test/recipes/30-test_evp_data/evpciph.txt @@ -259,7 +259,6 @@ Ciphertext = B2EB05E2C39BE9FCDA6C19078C6A9D1B # AES-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec # CFB128-AES128.Encrypt Cipher = AES-128-CFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = 000102030405060708090A0B0C0D0E0F Operation = ENCRYPT @@ -267,7 +266,6 @@ Plaintext = 6BC1BEE22E409F96E93D7E117393172A Ciphertext = 3B3FD92EB72DAD20333449F8E83CFB4A Cipher = AES-128-CFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = 3B3FD92EB72DAD20333449F8E83CFB4A Operation = ENCRYPT @@ -275,7 +273,6 @@ Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51 Ciphertext = C8A64537A0B3A93FCDE3CDAD9F1CE58B Cipher = AES-128-CFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = C8A64537A0B3A93FCDE3CDAD9F1CE58B Operation = ENCRYPT @@ -283,7 +280,6 @@ Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF Ciphertext = 26751F67A3CBB140B1808CF187A4F4DF Cipher = AES-128-CFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = 26751F67A3CBB140B1808CF187A4F4DF Operation = ENCRYPT @@ -292,7 +288,6 @@ Ciphertext = C04B05357C5D1C0EEAC4C66F9FF7F2E6 # CFB128-AES128.Decrypt Cipher = AES-128-CFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = 000102030405060708090A0B0C0D0E0F Operation = DECRYPT @@ -300,7 +295,6 @@ Plaintext = 6BC1BEE22E409F96E93D7E117393172A Ciphertext = 3B3FD92EB72DAD20333449F8E83CFB4A Cipher = AES-128-CFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = 3B3FD92EB72DAD20333449F8E83CFB4A Operation = DECRYPT @@ -308,7 +302,6 @@ Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51 Ciphertext = C8A64537A0B3A93FCDE3CDAD9F1CE58B Cipher = AES-128-CFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = C8A64537A0B3A93FCDE3CDAD9F1CE58B Operation = DECRYPT @@ -316,7 +309,6 @@ Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF Ciphertext = 26751F67A3CBB140B1808CF187A4F4DF Cipher = AES-128-CFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = 26751F67A3CBB140B1808CF187A4F4DF Operation = DECRYPT @@ -325,7 +317,6 @@ Ciphertext = C04B05357C5D1C0EEAC4C66F9FF7F2E6 # CFB128-AES192.Encrypt Cipher = AES-192-CFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = 000102030405060708090A0B0C0D0E0F Operation = ENCRYPT @@ -333,7 +324,6 @@ Plaintext = 6BC1BEE22E409F96E93D7E117393172A Ciphertext = CDC80D6FDDF18CAB34C25909C99A4174 Cipher = AES-192-CFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = CDC80D6FDDF18CAB34C25909C99A4174 Operation = ENCRYPT @@ -341,7 +331,6 @@ Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51 Ciphertext = 67CE7F7F81173621961A2B70171D3D7A Cipher = AES-192-CFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = 67CE7F7F81173621961A2B70171D3D7A Operation = ENCRYPT @@ -349,7 +338,6 @@ Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF Ciphertext = 2E1E8A1DD59B88B1C8E60FED1EFAC4C9 Cipher = AES-192-CFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = 2E1E8A1DD59B88B1C8E60FED1EFAC4C9 Operation = ENCRYPT @@ -358,7 +346,6 @@ Ciphertext = C05F9F9CA9834FA042AE8FBA584B09FF # CFB128-AES192.Decrypt Cipher = AES-192-CFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = 000102030405060708090A0B0C0D0E0F Operation = DECRYPT @@ -366,7 +353,6 @@ Plaintext = 6BC1BEE22E409F96E93D7E117393172A Ciphertext = CDC80D6FDDF18CAB34C25909C99A4174 Cipher = AES-192-CFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = CDC80D6FDDF18CAB34C25909C99A4174 Operation = DECRYPT @@ -374,7 +360,6 @@ Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51 Ciphertext = 67CE7F7F81173621961A2B70171D3D7A Cipher = AES-192-CFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = 67CE7F7F81173621961A2B70171D3D7A Operation = DECRYPT @@ -382,7 +367,6 @@ Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF Ciphertext = 2E1E8A1DD59B88B1C8E60FED1EFAC4C9 Cipher = AES-192-CFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = 2E1E8A1DD59B88B1C8E60FED1EFAC4C9 Operation = DECRYPT @@ -391,7 +375,6 @@ Ciphertext = C05F9F9CA9834FA042AE8FBA584B09FF # CFB128-AES256.Encrypt Cipher = AES-256-CFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = 000102030405060708090A0B0C0D0E0F Operation = ENCRYPT @@ -399,7 +382,6 @@ Plaintext = 6BC1BEE22E409F96E93D7E117393172A Ciphertext = DC7E84BFDA79164B7ECD8486985D3860 Cipher = AES-256-CFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = DC7E84BFDA79164B7ECD8486985D3860 Operation = ENCRYPT @@ -407,7 +389,6 @@ Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51 Ciphertext = 39FFED143B28B1C832113C6331E5407B Cipher = AES-256-CFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = 39FFED143B28B1C832113C6331E5407B Operation = ENCRYPT @@ -415,7 +396,6 @@ Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF Ciphertext = DF10132415E54B92A13ED0A8267AE2F9 Cipher = AES-256-CFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = DF10132415E54B92A13ED0A8267AE2F9 Operation = ENCRYPT @@ -424,7 +404,6 @@ Ciphertext = 75A385741AB9CEF82031623D55B1E471 # CFB128-AES256.Decrypt Cipher = AES-256-CFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = 000102030405060708090A0B0C0D0E0F Operation = DECRYPT @@ -432,7 +411,6 @@ Plaintext = 6BC1BEE22E409F96E93D7E117393172A Ciphertext = DC7E84BFDA79164B7ECD8486985D3860 Cipher = AES-256-CFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = DC7E84BFDA79164B7ECD8486985D3860 Operation = DECRYPT @@ -440,7 +418,6 @@ Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51 Ciphertext = 39FFED143B28B1C832113C6331E5407B Cipher = AES-256-CFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = 39FFED143B28B1C832113C6331E5407B Operation = DECRYPT @@ -448,7 +425,6 @@ Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF Ciphertext = DF10132415E54B92A13ED0A8267AE2F9 Cipher = AES-256-CFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = DF10132415E54B92A13ED0A8267AE2F9 Operation = DECRYPT @@ -459,7 +435,6 @@ Ciphertext = 75A385741AB9CEF82031623D55B1E471 # AES-bits-CFB:key:IV/output':plaintext:ciphertext:encdec # OFB-AES128.Encrypt Cipher = AES-128-OFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = 000102030405060708090A0B0C0D0E0F Operation = ENCRYPT @@ -467,7 +442,6 @@ Plaintext = 6BC1BEE22E409F96E93D7E117393172A Ciphertext = 3B3FD92EB72DAD20333449F8E83CFB4A Cipher = AES-128-OFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = 50FE67CC996D32B6DA0937E99BAFEC60 Operation = ENCRYPT @@ -475,7 +449,6 @@ Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51 Ciphertext = 7789508D16918F03F53C52DAC54ED825 Cipher = AES-128-OFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = D9A4DADA0892239F6B8B3D7680E15674 Operation = ENCRYPT @@ -483,7 +456,6 @@ Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF Ciphertext = 9740051E9C5FECF64344F7A82260EDCC Cipher = AES-128-OFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = A78819583F0308E7A6BF36B1386ABF23 Operation = ENCRYPT @@ -492,7 +464,6 @@ Ciphertext = 304C6528F659C77866A510D9C1D6AE5E # OFB-AES128.Decrypt Cipher = AES-128-OFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = 000102030405060708090A0B0C0D0E0F Operation = DECRYPT @@ -500,7 +471,6 @@ Plaintext = 6BC1BEE22E409F96E93D7E117393172A Ciphertext = 3B3FD92EB72DAD20333449F8E83CFB4A Cipher = AES-128-OFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = 50FE67CC996D32B6DA0937E99BAFEC60 Operation = DECRYPT @@ -508,7 +478,6 @@ Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51 Ciphertext = 7789508D16918F03F53C52DAC54ED825 Cipher = AES-128-OFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = D9A4DADA0892239F6B8B3D7680E15674 Operation = DECRYPT @@ -516,7 +485,6 @@ Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF Ciphertext = 9740051E9C5FECF64344F7A82260EDCC Cipher = AES-128-OFB -Availablein = default Key = 2B7E151628AED2A6ABF7158809CF4F3C IV = A78819583F0308E7A6BF36B1386ABF23 Operation = DECRYPT @@ -525,7 +493,6 @@ Ciphertext = 304C6528F659C77866A510D9C1D6AE5E # OFB-AES192.Encrypt Cipher = AES-192-OFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = 000102030405060708090A0B0C0D0E0F Operation = ENCRYPT @@ -533,7 +500,6 @@ Plaintext = 6BC1BEE22E409F96E93D7E117393172A Ciphertext = CDC80D6FDDF18CAB34C25909C99A4174 Cipher = AES-192-OFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = A609B38DF3B1133DDDFF2718BA09565E Operation = ENCRYPT @@ -541,7 +507,6 @@ Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51 Ciphertext = FCC28B8D4C63837C09E81700C1100401 Cipher = AES-192-OFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = 52EF01DA52602FE0975F78AC84BF8A50 Operation = ENCRYPT @@ -549,7 +514,6 @@ Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF Ciphertext = 8D9A9AEAC0F6596F559C6D4DAF59A5F2 Cipher = AES-192-OFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = BD5286AC63AABD7EB067AC54B553F71D Operation = ENCRYPT @@ -558,7 +522,6 @@ Ciphertext = 6D9F200857CA6C3E9CAC524BD9ACC92A # OFB-AES192.Decrypt Cipher = AES-192-OFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = 000102030405060708090A0B0C0D0E0F Operation = ENCRYPT @@ -566,7 +529,6 @@ Plaintext = 6BC1BEE22E409F96E93D7E117393172A Ciphertext = CDC80D6FDDF18CAB34C25909C99A4174 Cipher = AES-192-OFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = A609B38DF3B1133DDDFF2718BA09565E Operation = ENCRYPT @@ -574,7 +536,6 @@ Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51 Ciphertext = FCC28B8D4C63837C09E81700C1100401 Cipher = AES-192-OFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = 52EF01DA52602FE0975F78AC84BF8A50 Operation = ENCRYPT @@ -582,7 +543,6 @@ Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF Ciphertext = 8D9A9AEAC0F6596F559C6D4DAF59A5F2 Cipher = AES-192-OFB -Availablein = default Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B IV = BD5286AC63AABD7EB067AC54B553F71D Operation = ENCRYPT @@ -591,7 +551,6 @@ Ciphertext = 6D9F200857CA6C3E9CAC524BD9ACC92A # OFB-AES256.Encrypt Cipher = AES-256-OFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = 000102030405060708090A0B0C0D0E0F Operation = ENCRYPT @@ -599,7 +558,6 @@ Plaintext = 6BC1BEE22E409F96E93D7E117393172A Ciphertext = DC7E84BFDA79164B7ECD8486985D3860 Cipher = AES-256-OFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = B7BF3A5DF43989DD97F0FA97EBCE2F4A Operation = ENCRYPT @@ -607,7 +565,6 @@ Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51 Ciphertext = 4FEBDC6740D20B3AC88F6AD82A4FB08D Cipher = AES-256-OFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = E1C656305ED1A7A6563805746FE03EDC Operation = ENCRYPT @@ -615,7 +572,6 @@ Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF Ciphertext = 71AB47A086E86EEDF39D1C5BBA97C408 Cipher = AES-256-OFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = 41635BE625B48AFC1666DD42A09D96E7 Operation = ENCRYPT @@ -624,7 +580,6 @@ Ciphertext = 0126141D67F37BE8538F5A8BE740E484 # OFB-AES256.Decrypt Cipher = AES-256-OFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = 000102030405060708090A0B0C0D0E0F Operation = DECRYPT @@ -632,7 +587,6 @@ Plaintext = 6BC1BEE22E409F96E93D7E117393172A Ciphertext = DC7E84BFDA79164B7ECD8486985D3860 Cipher = AES-256-OFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = B7BF3A5DF43989DD97F0FA97EBCE2F4A Operation = DECRYPT @@ -640,7 +594,6 @@ Plaintext = AE2D8A571E03AC9C9EB76FAC45AF8E51 Ciphertext = 4FEBDC6740D20B3AC88F6AD82A4FB08D Cipher = AES-256-OFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = E1C656305ED1A7A6563805746FE03EDC Operation = DECRYPT @@ -648,7 +601,6 @@ Plaintext = 30C81C46A35CE411E5FBC1191A0A52EF Ciphertext = 71AB47A086E86EEDF39D1C5BBA97C408 Cipher = AES-256-OFB -Availablein = default Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 IV = 41635BE625B48AFC1666DD42A09D96E7 Operation = DECRYPT diff --git a/test/recipes/30-test_evp_data/evpdigest.txt b/test/recipes/30-test_evp_data/evpdigest.txt index b09a747b..b492eab3 100644 --- a/test/recipes/30-test_evp_data/evpdigest.txt +++ b/test/recipes/30-test_evp_data/evpdigest.txt @@ -505,12 +505,10 @@ Input = 991c4e7402c7da689dd5525af76fcc58fe9cc1451308c0c4600363586ccc83c9ec10a8c9 Output = cd0f2a48e9aa8cc700d3f64efb013f3600ebdbb524930c682d21025eab990eb6d7c52e611f884031fafd9360e5225ab7e4ec24cbe97f3af6dbe4a86a4f068ba7 Digest = SHAKE128 -Availablein = default Input = "" Output = 7F9C2BA4E88F827D616045507605853ED73B8093F6EFBC88EB1A6EACFA66EF263CB1EEA988004B93103CFB0AEEFD2A686E01FA4A58E8A3639CA8A1E3F9AE57E235B8CC873C23DC62B8D260169AFA2F75AB916A58D974918835D25E6A435085B2BADFD6DFAAC359A5EFBB7BCC4B59D538DF9A04302E10C8BC1CBF1A0B3A5120EA17CDA7CFAD765F5623474D368CCCA8AF0007CD9F5E4C849F167A580B14AABDEFAEE7EEF47CB0FCA9767BE1FDA69419DFB927E9DF07348B196691ABAEB580B32DEF58538B8D23F87732EA63B02B4FA0F4873360E2841928CD60DD4CEE8CC0D4C922A96188D032675C8AC850933C7AFF1533B94C834ADBB69C6115BAD4692D8619F90B0CDF8A7B9C264029AC185B70B83F2801F2F4B3F70C593EA3AEEB613A7F1B1DE33FD75081F592305F2E4526EDC09631B10958F464D889F31BA010250FDA7F1368EC2967FC84EF2AE9AFF268E0B1700AFFC6820B523A3D917135F2DFF2EE06BFE72B3124721D4A26C04E53A75E30E73A7A9C4A95D91C55D495E9F51DD0B5E9D83C6D5E8CE803AA62B8D654DB53D09B8DCFF273CDFEB573FAD8BCD45578BEC2E770D01EFDE86E721A3F7C6CCE275DABE6E2143F1AF18DA7EFDDC4C7B70B5E345DB93CC936BEA323491CCB38A388F546A9FF00DD4E1300B9B2153D2041D205B443E41B45A653F2A5C4492C1ADD544512DDA2529833462B71A41A45BE97290B6F Digest = SHAKE128 -Availablein = default Input = A3 Count = 200 Output = 131AB8D2B594946B9C81333F9BB6E0CE75C3B93104FA3469D3917457385DA037CF232EF7164A6D1EB448C8908186AD852D3F85A5CF28DA1AB6FE3438171978467F1C05D58C7EF38C284C41F6C2221A76F12AB1C04082660250802294FB87180213FDEF5B0ECB7DF50CA1F8555BE14D32E10F6EDCDE892C09424B29F597AFC270C904556BFCB47A7D40778D390923642B3CBD0579E60908D5A000C1D08B98EF933F806445BF87F8B009BA9E94F7266122ED7AC24E5E266C42A82FA1BBEFB7B8DB0066E16A85E0493F07DF4809AEC084A593748AC3DDE5A6D7AAE1E8B6E5352B2D71EFBB47D4CAEED5E6D633805D2D323E6FD81B4684B93A2677D45E7421C2C6AEA259B855A698FD7D13477A1FE53E5A4A6197DBEC5CE95F505B520BCD9570C4A8265A7E01F89C0C002C59BFEC6CD4A5C109258953EE5EE70CD577EE217AF21FA70178F0946C9BF6CA8751793479F6B537737E40B6ED28511D8A2D7E73EB75F8DAAC912FF906E0AB955B083BAC45A8E5E9B744C8506F37E9B4E749A184B30F43EB188D855F1B70D71FF3E50C537AC1B0F8974F0FE1A6AD295BA42F6AEC74D123A7ABEDDE6E2C0711CAB36BE5ACB1A5A11A4B1DB08BA6982EFCCD716929A7741CFC63AA4435E0B69A9063E880795C3DC5EF3272E11C497A91ACF699FEFEE206227A44C9FB359FD56AC0A9A75A743CFF6862F17D7259AB075216C0699511643B6439 @@ -521,28 +519,23 @@ Input = a6fe00064257aa318b621c5eb311d32bb8004c2fa1a969d205d71762cc5d2e6339079926 Output = 3109d9472ca436e805c6b3db2251a9bc Digest = SHAKE128 -Availablein = default Input = 49d81708d86cd59dea0ac2c1017a9712d6dffb754dde0b57a9023a39fc5f5b6be276fc176f59f6826610428fac3a0e85fcf71011db061b8fcf2bf085ccd45670effb6dc46f4e3f2ed08e981c5935187fc95b86cf46da675096b1cf9591a67842d6301116be93d8288e4d6b70f1b1db8aa5d203b774a21825665b8170351ee86801da91154570eaf80a1564945af7822df8232fd04ea65593a7f2ab1e9e84cf6ad6c494c9ec2d9d27aaad2b8f7e4f33f12a17b422bc2d4724c13ff8a8b62054d1bfb5c33b9c11183cd8df67694300165ca37637b5a781155f1c070d156339a0242374c6723b6584bffb71c02b935455f8cb086392f5e8e8cc2015956d8f19daeb6aca4476b27108387a2ce0dc5591154d0b94ddc090abe8f4363036b821062baffb7fe550ea7dcd30bfd86c84710081e1c9e450475e123c5ec41f98ff0149bbf6405b5207cad1fb2f313d0f2bcee9be3f6ebe623049640d9234ab644a172ab14ba02633a339b5b9bb38226fda5694f7ec63ebbb8238eb8219ec9c429f4bf0353383a72f2d21702f5e3c513499f04852710f33044512edc47a56bad90885e5713851a7efac694b869fa590076e844ff757d95de581c1b3fa3dd8ccd28cad4f8ae173ee1b28f98ee606dca89063fbef0f262b33053f2c854debdc9cd433ab77abb64f445aa9b981761c4761767f3b71c2646c7b0d873baae50bc9f0 Output = c609be05458f7ab33e7b6b54bc6e8999 Digest = SHAKE256 -Availablein = default Input = "" Output = 46B9DD2B0BA88D13233B3FEB743EEB243FCD52EA62B81B82B50C27646ED5762FD75DC4DDD8C0F200CB05019D67B592F6FC821C49479AB48640292EACB3B7C4BE141E96616FB13957692CC7EDD0B45AE3DC07223C8E92937BEF84BC0EAB862853349EC75546F58FB7C2775C38462C5010D846C185C15111E595522A6BCD16CF86F3D122109E3B1FDD943B6AEC468A2D621A7C06C6A957C62B54DAFC3BE87567D677231395F6147293B68CEAB7A9E0C58D864E8EFDE4E1B9A46CBE854713672F5CAAAE314ED9083DAB4B099F8E300F01B8650F1F4B1D8FCF3F3CB53FB8E9EB2EA203BDC970F50AE55428A91F7F53AC266B28419C3778A15FD248D339EDE785FB7F5A1AAA96D313EACC890936C173CDCD0FAB882C45755FEB3AED96D477FF96390BF9A66D1368B208E21F7C10D04A3DBD4E360633E5DB4B602601C14CEA737DB3DCF722632CC77851CBDDE2AAF0A33A07B373445DF490CC8FC1E4160FF118378F11F0477DE055A81A9EDA57A4A2CFB0C83929D310912F729EC6CFA36C6AC6A75837143045D791CC85EFF5B21932F23861BCF23A52B5DA67EAF7BAAE0F5FB1369DB78F3AC45F8C4AC5671D85735CDDDB09D2B1E34A1FC066FF4A162CB263D6541274AE2FCC865F618ABE27C124CD8B074CCD516301B91875824D09958F341EF274BDAB0BAE316339894304E35877B0C28A9B1FD166C796B9CC258A064A8F57E27F2A Digest = SHAKE256 -Availablein = default Input = A3 Count = 200 Output = CD8A920ED141AA0407A22D59288652E9D9F1A7EE0C1E7C1CA699424DA84A904D2D700CAAE7396ECE96604440577DA4F3AA22AEB8857F961C4CD8E06F0AE6610B1048A7F64E1074CD629E85AD7566048EFC4FB500B486A3309A8F26724C0ED628001A1099422468DE726F1061D99EB9E93604D5AA7467D4B1BD6484582A384317D7F47D750B8F5499512BB85A226C4243556E696F6BD072C5AA2D9B69730244B56853D16970AD817E213E470618178001C9FB56C54FEFA5FEE67D2DA524BB3B0B61EF0E9114A92CDBB6CCCB98615CFE76E3510DD88D1CC28FF99287512F24BFAFA1A76877B6F37198E3A641C68A7C42D45FA7ACC10DAE5F3CEFB7B735F12D4E589F7A456E78C0F5E4C4471FFFA5E4FA0514AE974D8C2648513B5DB494CEA847156D277AD0E141C24C7839064CD08851BC2E7CA109FD4E251C35BB0A04FB05B364FF8C4D8B59BC303E25328C09A882E952518E1A8AE0FF265D61C465896973D7490499DC639FB8502B39456791B1B6EC5BCC5D9AC36A6DF622A070D43FED781F5F149F7B62675E7D1A4D6DEC48C1C7164586EAE06A51208C0B791244D307726505C3AD4B26B6822377257AA152037560A739714A3CA79BD605547C9B78DD1F596F2D4F1791BC689A0E9B799A37339C04275733740143EF5D2B58B96A363D4E08076A1A9D7846436E4DCA5728B6F760EEF0CA92BF0BE5615E96959D767197A0BEEB Digest = SHAKE256 -Availablein = default Input = dc5a100fa16df1583c79722a0d72833d3bf22c109b8889dbd35213c6bfce205813edae3242695cfd9f59b9a1c203c1b72ef1a5423147cb990b5316a85266675894e2644c3f9578cebe451a09e58c53788fe77a9e850943f8a275f830354b0593a762bac55e984db3e0661eca3cb83f67a6fb348e6177f7dee2df40c4322602f094953905681be3954fe44c4c902c8f6bba565a788b38f13411ba76ce0f9f6756a2a2687424c5435a51e62df7a8934b6e141f74c6ccf539e3782d22b5955d3baf1ab2cf7b5c3f74ec2f9447344e937957fd7f0bdfec56d5d25f61cde18c0986e244ecf780d6307e313117256948d4230ebb9ea62bb302cfe80d7dfebabc4a51d7687967ed5b416a139e974c005fff507a96 Output = 2bac5716803a9cda8f9e84365ab0a681327b5ba34fdedfb1c12e6e807f45284b Digest = SHAKE256 -Availablein = default Input = 16caf60da14b4fa9174a6d40c23cff93ed8fc9279990f749718db1500036ef2222498ffab86fa568a0611299e54e58d83281ac558d3f4d2541ee158b1c7d4d76dbffc64ae39925e3329f7fd894fa26fc1acdc22bc858a3438e1c55707a3f75ad2b33c48789937a24b34ddd85390611088cba3231b2a3a0a93e5d9a8780470fcff92cb03811234a330db353283b3bc3036f9125efb3eaed613bfa0c59975cc2e52c33b3e6e5123e1626190a4a0261e1f5ad9bc2ee34f331736b3bd26d274536f5ae90f5186c27fdd7e8c72972f64016e72d1d32b59b8715e5b867154b99cb140a668b9d560e2c307e3904d9297f9f07dfd7629ccc526e41c109c8fc7c53b604293c6cd42933e77e11031a42f605485fe893b129bcbf705c0f45a4b087bfcead5c187ac1174322909a2d4f8b61f001c4074951000c4c550ed5564458f444dab8aae2fe8daaa6a30d209fecddf2a893df46e18b4b4460e4011d23f01d4c49a4cc1c82405f6ac5339eac41385f3295c657ac43a72fed62e6daee94ef271638f292b8e18860de0699eb45fb7d3aa81f61d44158edd68ebc244451918b Output = 21a48efd949c3f785179a0e340756a23f77d29a7625229a71a05731c7fbd5aa9 @@ -550,22 +543,18 @@ Output = 21a48efd949c3f785179a0e340756a23f77d29a7625229a71a05731c7fbd5aa9 # http://csrc.nist.gov/groups/STM/cavp/secure-hashing.html#test-vectors Digest = SHAKE128 -Availablein = default Input = c60a221c975e14bf835827c1103a2906 Output = 0db7f7196eee8dd6994a16ded19cb09f05f89ccd2464333df2c017c6ca041fa0d54a4832a74ce86ce9b41d8e523e66ce6ef9df7c20aa70e0ac00f54eb072a472ef46cf2a933df0d5f9fafab6388a206f6bd1df50b0836500c758c557c8ac965733fdaaa59f5ed661a1bda61e2952886a60f9568157e3d72e49b6e061fc08f3f1caf159e8eff77ea5221565d2 Digest = SHAKE128 -Availablein = default Input = 0a13ad2c7a239b4ba73ea6592ae84ea9 Output = 5feaf99c15f48851943ff9baa6e5055d8377f0dd347aa4dbece51ad3a6d9ce0c01aee9fe2260b80a4673a909b532adcdd1e421c32d6460535b5fe392a58d2634979a5a104d6c470aa3306c400b061db91c463b2848297bca2bc26d1864ba49d7ff949ebca50fbf79a5e63716dc82b600bd52ca7437ed774d169f6bf02e46487956fba2230f34cd2a0485484d Digest = SHAKE256 -Availablein = default Input = 6ae23f058f0f2264a18cd609acc26dd4dbc00f5c3ee9e13ecaea2bb5a2f0bb6b Output = b9b92544fb25cfe4ec6fe437d8da2bbe00f7bdaface3de97b8775a44d753c3adca3f7c6f183cc8647e229070439aa9539ae1f8f13470c9d3527fffdeef6c94f9f0520ff0c1ba8b16e16014e1af43ac6d94cb7929188cce9d7b02f81a2746f52ba16988e5f6d93298d778dfe05ea0ef256ae3728643ce3e29c794a0370e9ca6a8bf3e7a41e86770676ac106f7ae79e67027ce7b7b38efe27d253a52b5cb54d6eb4367a87736ed48cb45ef27f42683da140ed3295dfc575d3ea38cfc2a3697cc92864305407369b4abac054e497378dd9fd0c4b352ea3185ce1178b3dc1599df69db29259d4735320c8e7d33e8226620c9a1d22761f1d35bdff79a Digest = SHAKE256 -Availablein = default Input = 8d8001e2c096f1b88e7c9224a086efd4797fbf74a8033a2d422a2b6b8f6747e4 Output = 2e975f6a8a14f0704d51b13667d8195c219f71e6345696c49fa4b9d08e9225d3d39393425152c97e71dd24601c11abcfa0f12f53c680bd3ae757b8134a9c10d429615869217fdd5885c4db174985703a6d6de94a667eac3023443a8337ae1bc601b76d7d38ec3c34463105f0d3949d78e562a039e4469548b609395de5a4fd43c46ca9fd6ee29ada5efc07d84d553249450dab4a49c483ded250c9338f85cd937ae66bb436f3b4026e859fda1ca571432f3bfc09e7c03ca4d183b741111ca0483d0edabc03feb23b17ee48e844ba2408d9dcfd0139d2e8c7310125aee801c61ab7900d1efc47c078281766f361c5e6111346235e1dc38325666c diff --git a/test/recipes/80-test_ca.t b/test/recipes/80-test_ca.t index 3d4dfcd0..bbb0af75 100644 --- a/test/recipes/80-test_ca.t +++ b/test/recipes/80-test_ca.t @@ -18,26 +18,29 @@ use OpenSSL::Test::Utils; setup("test_ca"); $ENV{OPENSSL} = cmdstr(app(["openssl"]), display => 1); -my $std_openssl_cnf = - srctop_file("apps", $^O eq "VMS" ? "openssl-vms.cnf" : "openssl.cnf"); + +my $cnf = '"' . srctop_file("test","ca-and-certs.cnf") . '"';; +my $std_openssl_cnf = '"' + . srctop_file("apps", $^O eq "VMS" ? "openssl-vms.cnf" : "openssl.cnf") + . '"'; rmtree("demoCA", { safe => 0 }); plan tests => 6; SKIP: { - $ENV{OPENSSL_CONFIG} = '-config "'.srctop_file("test", "CAss.cnf").'"'; + $ENV{OPENSSL_CONFIG} = '-config ' . $cnf; skip "failed creating CA structure", 4 if !ok(run(perlapp(["CA.pl","-newca"], stdin => undef)), 'creating CA structure'); - $ENV{OPENSSL_CONFIG} = '-config "'.srctop_file("test", "Uss.cnf").'"'; + $ENV{OPENSSL_CONFIG} = '-config ' . $cnf; skip "failed creating new certificate request", 3 if !ok(run(perlapp(["CA.pl","-newreq", - "-extra-req","-outform DER"])), + '-extra-req', '-outform DER -section userreq'])), 'creating certificate request'); - $ENV{OPENSSL_CONFIG} = '-rand_serial -inform DER -config "'.$std_openssl_cnf.'"'; + $ENV{OPENSSL_CONFIG} = '-rand_serial -inform DER -config '.$std_openssl_cnf; skip "failed to sign certificate request", 2 - if !is(yes(cmdstr(perlapp(["CA.pl", "-sign", "-extra-ca"]))), 0, + if !is(yes(cmdstr(perlapp(["CA.pl", "-sign"]))), 0, 'signing certificate request'); ok(run(perlapp(["CA.pl", "-verify", "newcert.pem"])), @@ -46,8 +49,8 @@ plan tests => 6; skip "CT not configured, can't use -precert", 1 if disabled("ct"); - $ENV{OPENSSL_CONFIG} = '-config "'.srctop_file("test", "Uss.cnf").'"'; - ok(run(perlapp(["CA.pl", "-precert"], stderr => undef)), + $ENV{OPENSSL_CONFIG} = '-config ' . $cnf; + ok(run(perlapp(["CA.pl", "-precert", '-extra-req', '-section userreq'], stderr => undef)), 'creating new pre-certificate'); } @@ -56,7 +59,7 @@ SKIP: { if disabled("sm2"); is(yes(cmdstr(app(["openssl", "ca", "-config", - srctop_file("test", "CAss.cnf"), + $cnf, "-in", srctop_file("test", "certs", "sm2-csr.pem"), "-out", "sm2-test.crt", "-sigopt", "distid:1234567812345678", diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t index db2fce65..76342481 100644 --- a/test/recipes/80-test_cms.t +++ b/test/recipes/80-test_cms.t @@ -30,7 +30,7 @@ my $smcont = srctop_file("test", "smcont.txt"); my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib) = disabled qw/des dh dsa ec ec2m rc2 zlib/; -plan tests => 7; +plan tests => 10; my @smime_pkcs7_tests = ( @@ -251,26 +251,6 @@ my @smime_cms_tests = ( "-CAfile", catfile($smdir, "smroot.pem") ] ], - [ "signed content DER format, RSA key, CAdES-BES compatible", - [ "{cmd1}", "-sign", "-cades", "-in", $smcont, "-outform", "DER", - "-nodetach", - "-certfile", catfile($smdir, "smroot.pem"), - "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ], - [ "{cmd2}", "-verify", "-in", "{output}.cms", "-inform", "DER", - "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ], - \&final_compare - ], - - [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible", - [ "{cmd1}", "-sign", "-cades", "-md", "sha256", "-in", $smcont, - "-outform", "DER", "-nodetach", - "-certfile", catfile($smdir, "smroot.pem"), - "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ], - [ "{cmd2}", "-verify", "-in", "{output}.cms", "-inform", "DER", - "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ], - \&final_compare - ], - [ "enveloped content test streaming S/MIME format, DES, 3 recipients, keyid", [ "{cmd1}", "-encrypt", "-in", $smcont, "-stream", "-out", "{output}.cms", "-keyid", @@ -360,6 +340,87 @@ my @smime_cms_tests = ( ); +my @smime_cms_cades_tests = ( + + [ "signed content DER format, RSA key, CAdES-BES compatible", + [ "{cmd1}", "-sign", "-cades", "-in", $smcont, "-outform", "DER", + "-nodetach", + "-certfile", catfile($smdir, "smroot.pem"), + "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ], + [ "{cmd2}", "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER", + "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ], + \&final_compare + ], + + [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible", + [ "{cmd1}", "-sign", "-cades", "-md", "sha256", "-in", $smcont, "-outform", + "DER", "-nodetach", "-certfile", catfile($smdir, "smroot.pem"), + "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ], + [ "{cmd2}", "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER", + "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ], + \&final_compare + ], + + [ "signed content DER format, RSA key, SHA512 md, CAdES-BES compatible", + [ "{cmd1}", "-sign", "-cades", "-md", "sha512", "-in", $smcont, "-outform", + "DER", "-nodetach", "-certfile", catfile($smdir, "smroot.pem"), + "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ], + [ "{cmd2}", "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER", + "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ], + \&final_compare + ], + + [ "signed content DER format, RSA key, SHA256 md, CAdES-BES compatible", + [ "{cmd1}", "-sign", "-cades", "-binary", "-nodetach", "-nosmimecap", "-md", "sha256", + "-in", $smcont, "-outform", "DER", + "-certfile", catfile($smdir, "smroot.pem"), + "-signer", catfile($smdir, "smrsa1.pem"), + "-outform", "DER", "-out", "{output}.cms" ], + [ "{cmd2}", "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER", + "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ], + \&final_compare + ], + + [ "resigned content DER format, RSA key, SHA256 md, CAdES-BES compatible", + [ "{cmd1}", "-sign", "-cades", "-binary", "-nodetach", "-nosmimecap", "-md", "sha256", + "-in", $smcont, "-outform", "DER", + "-certfile", catfile($smdir, "smroot.pem"), + "-signer", catfile($smdir, "smrsa1.pem"), + "-outform", "DER", "-out", "{output}.cms" ], + [ "{cmd1}", "-resign", "-cades", "-binary", "-nodetach", "-nosmimecap", "-md", "sha256", + "-inform", "DER", "-in", "{output}.cms", + "-certfile", catfile($smdir, "smroot.pem"), + "-signer", catfile($smdir, "smrsa2.pem"), + "-outform", "DER", "-out", "{output}2.cms" ], + + [ "{cmd2}", "-verify", "-cades", "-in", "{output}2.cms", "-inform", "DER", + "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ], + \&final_compare + ], +); + +my @smime_cms_cades_ko_tests = ( + [ "signed content DER format, RSA key, but verified as CAdES-BES compatible", + [ "-sign", "-in", $smcont, "-outform", "DER", "-nodetach", + "-certfile", catfile($smdir, "smroot.pem"), + "-signer", catfile($smdir, "smrsa1.pem"), "-out", "{output}.cms" ], + [ "-verify", "-cades", "-in", "{output}.cms", "-inform", "DER", + "-CAfile", catfile($smdir, "smroot.pem"), "-out", "{output}.txt" ], + \&final_compare + ] +); + +# cades options test - check that some combinations are rejected +my @smime_cms_cades_invalid_option_tests = ( + [ + [ "-cades", "-noattr" ], + ],[ + [ "-verify", "-cades", "-noattr" ], + ],[ + [ "-verify", "-cades", "-noverify" ], + ], +); + my @smime_cms_comp_tests = ( [ "compressed content test streaming PEM format", @@ -491,7 +552,7 @@ my @smime_cms_param_tests = ( "-in", "{output}.cms", "-out", "{output}.txt" ], \&final_compare ] - ); +); my @contenttype_cms_test = ( [ "signed content test - check that content type is added to additional signerinfo, RSA keys", @@ -542,7 +603,7 @@ sub runner_loop { $x; } @$_; - diag "CMD: openssl", join(" ", @cmd); + diag "CMD: openssl ", join(" ", @cmd); $ok &&= run(app(["openssl", @cmd])); $opts{input} = $opts{output}; } @@ -654,6 +715,36 @@ subtest "CMS Decrypt message encrypted with OpenSSL 1.1.1\n" => sub { } }; +subtest "CAdES <=> CAdES consistency tests\n" => sub { + plan tests => (scalar @smime_cms_cades_tests); + + runner_loop(prefix => 'cms-cades', cmd1 => 'cms', cmd2 => 'cms', + tests => [ @smime_cms_cades_tests ]); +}; + +subtest "CAdES; cms incompatible arguments tests\n" => sub { + plan tests => (scalar @smime_cms_cades_invalid_option_tests); + + foreach (@smime_cms_cades_invalid_option_tests) { + ok(!run(app(["openssl", "cms", @{$$_[0]} ] ))); + } +}; + +subtest "CAdES ko tests\n" => sub { + plan tests => (scalar @smime_cms_cades_ko_tests); + + foreach (@smime_cms_cades_ko_tests) { + SKIP: { + my $skip_reason = check_availability($$_[0]); + skip $skip_reason, 1 if $skip_reason; + + ok(run(app(["openssl", "cms", @{$$_[1]}])) + && !run(app(["openssl", "cms", @{$$_[2]}])), + $$_[0]); + } + } +}; + sub check_availability { my $tnam = shift; diff --git a/test/recipes/80-test_ssl_old.t b/test/recipes/80-test_ssl_old.t index e01137d5..85f71614 100644 --- a/test/recipes/80-test_ssl_old.t +++ b/test/recipes/80-test_ssl_old.t @@ -44,33 +44,27 @@ my @verifycmd = ("openssl", "verify"); my @genpkeycmd = ("openssl", "genpkey"); my $dummycnf = srctop_file("apps", "openssl.cnf"); +my $cnf = srctop_file("test", "ca-and-certs.cnf"); my $CAkey = "keyCA.ss"; my $CAcert="certCA.ss"; my $CAserial="certCA.srl"; my $CAreq="reqCA.ss"; -my $CAconf=srctop_file("test","CAss.cnf"); my $CAreq2="req2CA.ss"; # temp - -my $Uconf=srctop_file("test","Uss.cnf"); my $Ukey="keyU.ss"; my $Ureq="reqU.ss"; my $Ucert="certU.ss"; - my $Dkey="keyD.ss"; my $Dreq="reqD.ss"; my $Dcert="certD.ss"; - my $Ekey="keyE.ss"; my $Ereq="reqE.ss"; my $Ecert="certE.ss"; -my $P1conf=srctop_file("test","P1ss.cnf"); +my $proxycnf=srctop_file("test", "proxy.cnf"); my $P1key="keyP1.ss"; my $P1req="reqP1.ss"; my $P1cert="certP1.ss"; my $P1intermediate="tmp_intP1.ss"; - -my $P2conf=srctop_file("test","P2ss.cnf"); my $P2key="keyP2.ss"; my $P2req="reqP2.ss"; my $P2cert="certP2.ss"; @@ -133,7 +127,7 @@ sub testss { SKIP: { skip 'failure', 16 unless - ok(run(app([@reqcmd, "-config", $CAconf, + ok(run(app([@reqcmd, "-config", $cnf, "-out", $CAreq, "-keyout", $CAkey, @req_new])), 'make cert request'); @@ -141,7 +135,7 @@ sub testss { skip 'failure', 15 unless ok(run(app([@x509cmd, "-CAcreateserial", "-in", $CAreq, "-days", "30", "-req", "-out", $CAcert, "-signkey", $CAkey, - "-extfile", $CAconf, "-extensions", "v3_ca"], + "-extfile", $cnf, "-extensions", "v3_ca"], stdout => "err.ss")), 'convert request into self-signed cert'); @@ -167,7 +161,7 @@ sub testss { 'verify signature'); skip 'failure', 10 unless - ok(run(app([@reqcmd, "-config", $Uconf, + ok(run(app([@reqcmd, "-config", $cnf, "-section", "userreq", "-out", $Ureq, "-keyout", $Ukey, @req_new], stdout => "err.ss")), 'make a user cert request'); @@ -176,7 +170,7 @@ sub testss { ok(run(app([@x509cmd, "-CAcreateserial", "-in", $Ureq, "-days", "30", "-req", "-out", $Ucert, "-CA", $CAcert, "-CAkey", $CAkey, "-CAserial", $CAserial, - "-extfile", $Uconf, "-extensions", "v3_ee"], + "-extfile", $cnf, "-extensions", "v3_ee"], stdout => "err.ss")) && run(app([@verifycmd, "-CAfile", $CAcert, $Ucert])), 'sign user cert request'); @@ -202,7 +196,8 @@ sub testss { stdout => "err.ss")), "make a DSA key"); skip 'failure', 3 unless - ok(run(app([@reqcmd, "-new", "-config", $Uconf, + ok(run(app([@reqcmd, "-new", "-config", $cnf, + "-section", "userreq", "-out", $Dreq, "-key", $Dkey], stdout => "err.ss")), "make a DSA user cert request"); @@ -214,7 +209,7 @@ sub testss { "-out", $Dcert, "-CA", $CAcert, "-CAkey", $CAkey, "-CAserial", $CAserial, - "-extfile", $Uconf, + "-extfile", $cnf, "-extensions", "v3_ee_dsa"], stdout => "err.ss")), "sign DSA user cert request"); @@ -247,7 +242,8 @@ sub testss { "-out", "ecp.ss"])), "make EC parameters"); skip 'failure', 3 unless - ok(run(app([@reqcmd, "-config", $Uconf, + ok(run(app([@reqcmd, "-config", $cnf, + "-section", "userreq", "-out", $Ereq, "-keyout", $Ekey, "-newkey", "ec:ecp.ss"], stdout => "err.ss")), @@ -260,7 +256,7 @@ sub testss { "-out", $Ecert, "-CA", $CAcert, "-CAkey", $CAkey, "-CAserial", $CAserial, - "-extfile", $Uconf, + "-extfile", $cnf, "-extensions", "v3_ee_ec"], stdout => "err.ss")), "sign ECDSA/ECDH user cert request"); @@ -277,7 +273,7 @@ sub testss { }; skip 'failure', 5 unless - ok(run(app([@reqcmd, "-config", $P1conf, + ok(run(app([@reqcmd, "-config", $proxycnf, "-out", $P1req, "-keyout", $P1key, @req_new], stdout => "err.ss")), 'make a proxy cert request'); @@ -287,7 +283,7 @@ sub testss { ok(run(app([@x509cmd, "-CAcreateserial", "-in", $P1req, "-days", "30", "-req", "-out", $P1cert, "-CA", $Ucert, "-CAkey", $Ukey, - "-extfile", $P1conf, "-extensions", "v3_proxy"], + "-extfile", $proxycnf, "-extensions", "proxy"], stdout => "err.ss")), 'sign proxy with user cert'); @@ -300,7 +296,7 @@ sub testss { 'Certificate details'); skip 'failure', 2 unless - ok(run(app([@reqcmd, "-config", $P2conf, + ok(run(app([@reqcmd, "-config", $proxycnf, "-section", "proxy2_req", "-out", $P2req, "-keyout", $P2key, @req_new], stdout => "err.ss")), @@ -311,7 +307,7 @@ sub testss { ok(run(app([@x509cmd, "-CAcreateserial", "-in", $P2req, "-days", "30", "-req", "-out", $P2cert, "-CA", $P1cert, "-CAkey", $P1key, - "-extfile", $P2conf, "-extensions", "v3_proxy"], + "-extfile", $proxycnf, "-extensions", "proxy_2"], stdout => "err.ss")), 'sign second proxy cert request with the first proxy cert'); diff --git a/test/recipes/81-test_cmp_cli.t b/test/recipes/81-test_cmp_cli.t new file mode 100644 index 00000000..3be02c61 --- /dev/null +++ b/test/recipes/81-test_cmp_cli.t @@ -0,0 +1,291 @@ +#! /usr/bin/env perl +# Copyright 2007-2019 The OpenSSL Project Authors. All Rights Reserved. +# Copyright Nokia 2007-2019 +# Copyright Siemens AG 2015-2019 +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use POSIX; +use File::Spec::Functions qw/catfile/; +use File::Compare qw/compare_text/; +use OpenSSL::Test qw/:DEFAULT with data_file data_dir bldtop_dir/; +use OpenSSL::Test::Utils; +use Data::Dumper; # for debugging purposes only + +setup("test_cmp_cli"); + +plan skip_all => "This test is not supported in a no-cmp build" + if disabled("cmp"); +plan skip_all => "This test is not supported in a no-ec build" + if disabled("ec"); +plan skip_all => "Tests involving server not available on Windows or VMS" + if $^O =~ /^(VMS|MSWin32)$/; + +sub chop_dblquot { # chop any leading & trailing '"' (needed for Windows) + my $str = shift; + $str =~ s/^\"(.*?)\"$/$1/; + return $str; +} + +my $proxy = ""; +$proxy = chop_dblquot($ENV{http_proxy} // $ENV{HTTP_PROXY} // $proxy); +$proxy =~ s{^https?://}{}i; +my $no_proxy = $ENV{no_proxy} // $ENV{NO_PROXY}; + +my $app = "apps/openssl cmp"; + +my @cmp_basic_tests = ( + [ "show help", [ "-config", '""', "-help" ], 0 ], + [ "CLI option not starting with '-'", [ "-config", '""', "days", "1" ], 1 ], + [ "unknown CLI option", [ "-config", '""', "-dayss" ], 1 ], + [ "bad int syntax: non-digit", [ "-config", '""', "-days", "a/" ], 1 ], + [ "bad int syntax: float", [ "-config", '""', "-days", "3.14" ], 1 ], + [ "bad int syntax: trailing garbage", [ "-config", '""', "-days", "314_+" ], 1 ], + [ "bad int: out of range", [ "-config", '""', "-days", "2147483648" ], 1 ], +); + +my $rsp_cert = "signer_only.crt"; +my $outfile = "test.cert.pem"; +my $secret = "pass:test"; +my $localport = 1700; + +# this uses the mock server directly in the cmp app, without TCP +sub use_mock_srv_internally +{ + ok(run(cmd([bldtop_dir($app), + "-config", '""', + "-use_mock_srv", "-srv_ref", "mock server", + "-srv_cert", "server.crt", # used for setting sender + "-srv_secret", $secret, + "-poll_count", "1", + "-rsp_cert", $rsp_cert, + "-cmd", "cr", + "-subject", "/CN=any", + "-newkey", "signer.key", + "-recipient", "/O=openssl_cmp", # if given must be consistent with sender + "-secret", $secret, + "-ref", "client under test", + "-certout" , $outfile])) + && compare_text($outfile, $rsp_cert) == 0, + "CMP app with -use_mock_srv and -poll_count 1"); + unlink $outfile; +} + +# the CMP server configuration consists of: +my $ca_dn; # The CA's Distinguished Name +my $server_dn; # The server's Distinguished Name +my $server_host;# The server's host name or IP address +my $server_port;# The server's port +my $server_tls; # The server's TLS port, if any, or 0 +my $server_path;# The server's CMP alias +my $server_cert;# The server's cert +my $kur_port; # The server's port for kur (cert update) +my $pbm_port; # The server port to be used for PBM +my $pbm_ref; # The reference for PBM +my $pbm_secret; # The secret for PBM +my $column; # The column number of the expected result +my $sleep = 0; # The time to sleep between two requests + +# The local $server_name variables below are among others taken as the name of a +# sub-directory with server-specific certs etc. and CA-specific config section. + +sub load_config { + my $server_name = shift; + my $section = shift; + my $test_config = $ENV{OPENSSL_CMP_CONFIG} // "$server_name/test.cnf"; + open (CH, $test_config) or die "Cannot open $test_config: $!"; + my $active = 0; + while () { + if (m/\[\s*$section\s*\]/) { + $active = 1; + } elsif (m/\[\s*.*?\s*\]/) { + $active = 0; + } elsif ($active) { + $ca_dn = $1 eq "" ? '""""' : $1 if m/^\s*ca_dn\s*=\s*(.*)?\s*$/; + $server_dn = $1 eq "" ? '""""' : $1 if m/^\s*server_dn\s*=\s*(.*)?\s*$/; + $server_host = $1 eq "" ? '""""' : $1 if m/^\s*server_host\s*=\s*(\S*)?\s*(\#.*)?$/; + $server_port = $1 eq "" ? '""""' : $1 if m/^\s*server_port\s*=\s*(.*)?\s*$/; + $server_tls = $1 eq "" ? '""""' : $1 if m/^\s*server_tls\s*=\s*(.*)?\s*$/; + $server_path = $1 eq "" ? '""""' : $1 if m/^\s*server_path\s*=\s*(.*)?\s*$/; + $server_cert = $1 eq "" ? '""""' : $1 if m/^\s*server_cert\s*=\s*(.*)?\s*$/; + $kur_port = $1 eq "" ? '""""' : $1 if m/^\s*kur_port\s*=\s*(.*)?\s*$/; + $pbm_port = $1 eq "" ? '""""' : $1 if m/^\s*pbm_port\s*=\s*(.*)?\s*$/; + $pbm_ref = $1 eq "" ? '""""' : $1 if m/^\s*pbm_ref\s*=\s*(.*)?\s*$/; + $pbm_secret = $1 eq "" ? '""""' : $1 if m/^\s*pbm_secret\s*=\s*(.*)?\s*$/; + $column = $1 eq "" ? '""""' : $1 if m/^\s*column\s*=\s*(.*)?\s*$/; + $sleep = $1 eq "" ? '""""' : $1 if m/^\s*sleep\s*=\s*(.*)?\s*$/; + } + } + close CH; + die "Cannot find all CMP server config values in $test_config section [$section]\n" + if !defined $ca_dn + || !defined $server_dn || !defined $server_host + || !defined $server_port || !defined $server_tls + || !defined $server_path || !defined $server_cert + || !defined $kur_port || !defined $pbm_port + || !defined $pbm_ref || !defined $pbm_secret + || !defined $column || !defined $sleep; + $server_dn = $server_dn // $ca_dn; +} + +my @server_configurations = ("Mock"); +@server_configurations = split /\s+/, $ENV{OPENSSL_CMP_SERVER} if $ENV{OPENSSL_CMP_SERVER}; +# set env variable, e.g., OPENSSL_CMP_SERVER="Mock Insta" to include further CMP servers + +my @all_aspects = ("connection", "verification", "credentials", "commands", "enrollment"); +@all_aspects = split /\s+/, $ENV{OPENSSL_CMP_ASPECTS} if $ENV{OPENSSL_CMP_ASPECTS}; +# set env variable, e.g., OPENSSL_CMP_ASPECTS="commands enrollment" to select specific aspects + +my $faillog; +if ($ENV{HARNESS_FAILLOG}) { + my $file = $ENV{HARNESS_FAILLOG}; + open($faillog, ">", $file) or die "Cannot open $file for writing: $!"; +} + +sub test_cmp_cli { + my $server_name = shift; + my $aspect = shift; + my $n = shift; + my $i = shift; + my $title = shift; + my $params = shift; + my $expected_exit = shift; + my $path_app = bldtop_dir($app); + with({ exit_checker => sub { + my $actual_exit = shift; + my $OK = $actual_exit == $expected_exit; + if ($faillog && !$OK) { + sub quote_spc_empty(_) { $_ eq "" ? '""' : $_ =~ m/ / ? '"'.$_.'"' : $_ }; + my $invocation = ("$path_app ").join(' ', map quote_spc_empty @$params); + print $faillog "$server_name $aspect \"$title\" ($i/$n)". + " expected=$expected_exit actual=$actual_exit\n"; + print $faillog "$invocation\n\n"; + } + return $OK; } }, + sub { ok(run(cmd([$path_app, @$params,])), + $title); }); +} + +sub test_cmp_cli_aspect { + my $server_name = shift; + my $aspect = shift; + my $tests = shift; + subtest "CMP app CLI $server_name $aspect\n" => sub { + my $n = scalar @$tests; + plan tests => $n; + my $i = 1; + foreach (@$tests) { + SKIP: { + test_cmp_cli($server_name, $aspect, $n, $i++, $$_[0], $$_[1], $$_[2]); + sleep($sleep); + } + } + }; + unlink "test.cert.pem", "test.cacerts.pem", "test.extracerts.pem"; +} + +indir data_dir() => sub { + plan tests => 1 + @server_configurations * @all_aspects + + (grep(/^Mock$/, @server_configurations) + && grep(/^certstatus$/, @all_aspects) ? 0 : 1); + + test_cmp_cli_aspect("basic", "options", \@cmp_basic_tests); + + indir "Mock" => sub { + use_mock_srv_internally(); + }; + + foreach my $server_name (@server_configurations) { + $server_name = chop_dblquot($server_name); + load_config($server_name, $server_name); + my $launch_mock = $server_name eq "Mock" && !$ENV{OPENSSL_CMP_CONFIG}; + if ($launch_mock) { + indir "Mock" => sub { + stop_mock_server(); # in case a previous run did not exit properly + start_mock_server("") || die "Cannot start CMP mock server"; + } + } + foreach my $aspect (@all_aspects) { + $aspect = chop_dblquot($aspect); + next if $server_name eq "Mock" && $aspect eq "certstatus"; + load_config($server_name, $aspect); # update with any aspect-specific settings + indir $server_name => sub { + my $tests = load_tests($server_name, $aspect); + test_cmp_cli_aspect($server_name, $aspect, $tests); + }; + }; + stop_mock_server() if $launch_mock; + }; +}; + +close($faillog) if $faillog; + +sub load_tests { + my $server_name = shift; + my $aspect = shift; + my $test_config = $ENV{OPENSSL_CMP_CONFIG} // "$server_name/test.cnf"; + my $file = data_file("test_$aspect.csv"); + my @result; + + open(my $data, '<', $file) || die "Cannot open $file for reading: $!"; + LOOP: + while (my $line = <$data>) { + chomp $line; + $line =~ s{\r\n}{\n}g; # adjust line endings + $line =~ s{_CA_DN}{$ca_dn}g; + $line =~ s{_SERVER_DN}{$server_dn}g; + $line =~ s{_SERVER_HOST}{$server_host}g; + $line =~ s{_SERVER_PORT}{$server_port}g; + $line =~ s{_SERVER_TLS}{$server_tls}g; + $line =~ s{_SERVER_PATH}{$server_path}g; + $line =~ s{_SERVER_CERT}{$server_cert}g; + $line =~ s{_KUR_PORT}{$kur_port}g; + $line =~ s{_PBM_PORT}{$pbm_port}g; + $line =~ s{_PBM_REF}{$pbm_ref}g; + $line =~ s{_PBM_SECRET}{$pbm_secret}g; + my $noproxy = $line =~ m/,\s*-no_proxy\s*,(.*?)(,|$)/ ? $1 : $no_proxy; + next LOOP if $no_proxy && ($noproxy =~ $server_host) + && $line =~ m/,\s*-proxy\s*,/; + next LOOP if $server_tls == 0 && $line =~ m/,\s*-tls_used\s*,/; + $line =~ s{-section,,}{-section,,-proxy,$proxy,} unless $line =~ m/,\s*-proxy\s*,/; + $line =~ s{-section,,}{-config,../$test_config,-section,$server_name $aspect,}; + my @fields = grep /\S/, split ",", $line; + s/^$// for (@fields); # used for proxy="" + s/^\s+// for (@fields); # remove leading whitespace from elements + s/\s+$// for (@fields); # remove trailing whitespace from elements + s/^\"(\".*?\")\"$/$1/ for (@fields); # remove escaping from quotation marks from elements + my $expected_exit = $fields[$column]; + my $description = 1; + my $title = $fields[$description]; + next LOOP if (!defined($expected_exit) + || ($expected_exit ne 0 && $expected_exit ne 1)); + @fields = grep {$_ ne 'BLANK'} @fields[$description + 1 .. @fields - 1]; + push @result, [$title, \@fields, $expected_exit]; + } + close($data); + return \@result; +} + +sub mock_server_pid { + return `lsof -iTCP:$localport -sTCP:LISTEN | tail -n 1 | awk '{ print \$2 }'`; +} + +sub start_mock_server { + return 0 if mock_server_pid(); # already running + my $args = $_[0]; # optional further CLI arguments + my $dir = bldtop_dir(""); + return system("LD_LIBRARY_PATH=$dir DYLD_LIBRARY_PATH=$dir " . + bldtop_dir($app) . " -config server.cnf " . + "$args &") == 0; # start in background, check for success +} + +sub stop_mock_server { + my $pid = mock_server_pid(); + system("kill $pid") if $pid; +} diff --git a/test/recipes/81-test_cmp_cli_data/Mock/12345.txt b/test/recipes/81-test_cmp_cli_data/Mock/12345.txt new file mode 100644 index 00000000..e56e15bb --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/12345.txt @@ -0,0 +1 @@ +12345 diff --git a/test/recipes/81-test_cmp_cli_data/Mock/big_issuing.crt b/test/recipes/81-test_cmp_cli_data/Mock/big_issuing.crt new file mode 100644 index 00000000..e96f3cf7 --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/big_issuing.crt @@ -0,0 +1,1577 @@ +Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = subinterCA +-----BEGIN CERTIFICATE----- +MIIDhDCCAmygAwIBAgIJAJkv2OGshkmUMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMTB2ludGVyQ0EwHhcNMTUwNzAyMTMxODIz +WhcNMzUwNzAyMTMxODIzWjBaMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1T +dGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYDVQQD +EwpzdWJpbnRlckNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/zQj +vhbU7RWDsRaEkVUBZWR/PqZ49GoE9p3OyRN4pkt1c1yb2ARVkYZP5e9gHb04wPVz +2+FYy+2mNkl+uAZbcK5w5fWO3WJIEn57he4MkWu3ew1nJeSv3na8gyOoCheG64kW +VbA2YL92mR7QoSCo4SP7RmykLrwj6TlDxqgH6DxKSD/CpdCHE3DKAzAiri3GVc90 +OJAszYHlje4/maVIOayGROVET3xa5cbtRJl8IBgmqhMywtz4hhY/XZTvdEn290aL +857Hk7JjogA7mLKi07yKzknMxHV+k6JX7xJEttkcNQRFHONWZG1T4mRY1Drh6VbJ +Gb+0GNIldNLQqigkfwIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTp +Z30QdMGarrhMPwk+HHAV3R8aTzAfBgNVHSMEGDAWgBQY+tYjuY9dXRN9Po+okcfZ +YcAXLjANBgkqhkiG9w0BAQsFAAOCAQEAgVUsOf9rdHlQDw4clP8GMY7QahfXbvd8 +8o++P18KeInQXH6+sCg0axZXzhOmKwn+Ina3EsOP7xk4aKIYwJ4A1xBuT7fKxquQ +pbJyjkEBsNRVLC9t4gOA0FC791v5bOCZjyff5uN+hy8r0828nVxha6CKLqwrPd+E +mC7DtilSZIgO2vwbTBL6ifmw9n1dd/Bl8Wdjnl7YJqTIf0Ozc2SZSMRUq9ryn4Wq +YrjRl8NwioGb1LfjEJ0wJi2ngL3IgaN94qmDn10OJs8hlsufwP1n+Bca3fsl0m5U +gUMG+CXxbF0kdCKZ9kQb1MJE4vOk6zfyBGQndmQnxHjt5botI/xpXg== +-----END CERTIFICATE----- + +Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = interCA +-----BEGIN CERTIFICATE----- +MIIDgDCCAmigAwIBAgIJANnoWlLlEsTgMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE3MDVa +Fw0zNTA3MDIxMzE3MDVaMFcxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 +YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMT +B2ludGVyQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7s0ejvpQO +nvfwD+e4R+9WQovtrsqOTw8khiREqi5JlmAFbpDEFam18npRkt6gOcGMnjuFzuz6 +iEuQmeeyh0BqWAwpMgWMMteEzLOAaqkEl//J2+WgRbA/8pmwHfbPW/d+f3bp64Fo +D1hQAenBzXmLxVohEQ9BA+xEDRkL/cA3Y+k/O1C9ORhSQrJNsB9aE3zKbFHd9mOm +H4aNSsF8On3SqlRVOCQine5c6ACSd0HUEjYy9aObqY47ySNULbzVq5y6VOjMs0W+ +2G/XqrcVkxzf9bVqyVBrrAJrnb35/y/iK0zWgJBP+HXhwr5mMTvNuEirBeVYuz+6 +hUerUbuJhr0FAgMBAAGjUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFBj61iO5 +j11dE30+j6iRx9lhwBcuMB8GA1UdIwQYMBaAFIVWiTXinwAa4YYDC0uvdhJrM239 +MA0GCSqGSIb3DQEBCwUAA4IBAQDAU0MvL/yZpmibhxUsoSsa97UJbejn5IbxpPzZ +4WHw8lsoUGs12ZHzQJ9LxkZVeuccFXy9yFEHW56GTlkBmD2qrddlmQCfQ3m8jtZ9 +Hh5feKAyrqfmfsWF5QPjAmdj/MFdq+yMJVosDftkmUmaBHjzbvbcq1sWh/6drH8U +7pdYRpfeEY8dHSU6FHwVN/H8VaBB7vYYc2wXwtk8On7z2ocIVHn9RPkcLwmwJjb/ +e4jmcYiyZev22KXQudeHc4w6crWiEFkVspomn5PqDmza3rkdB3baXFVZ6sd23ufU +wjkiKKtwRBwU+5tCCagQZoeQ5dZXQThkiH2XEIOCOLxyD/tb +-----END CERTIFICATE----- + + + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/big_root.crt b/test/recipes/81-test_cmp_cli_data/Mock/big_root.crt new file mode 100644 index 00000000..6f0124cc --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/big_root.crt @@ -0,0 +1,1554 @@ +Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = rootCA +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIJAIhDKcvC6xWaMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE1MTFa +Fw0zNTA3MDIxMzE1MTFaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0 +YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMM +BnJvb3RDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMDxa3eIrDXf ++3NTL5KAL3QWMk31ECBvbDqO0dxr4S4+wwQPv5vEyRLR5AtFl+UGzWY64eDiK9+i +xOx70z08iv9edKCrpwNqFlteksR+W3mKadS8g16uQpJ0pSvnAMGp3NWxUwcPc/eO +rRQ+JZ7lHubMkc2VDIBEIMP9F8+RPWMQHBRb+8OowYiyd/+c2/xqRERE94XsCCzU +34Gjecn+HpuTFlO3l6u+Txql4vpGBeQNnCqkzLkeIaBsxKtZsEA5u/mIrf3fjbQL +r35B4CE8yDNFSYQvkwbu/U/tT/O8m978JV5V1XXUxXs6QDUGn8SEtGyTDK83Wq+2 +QU0mIxy4ArMCAwEAAaNQME4wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUhVaJNeKf +ABrhhgMLS692Emszbf0wHwYDVR0jBBgwFoAUhVaJNeKfABrhhgMLS692Emszbf0w +DQYJKoZIhvcNAQELBQADggEBADIKvyoK4rtPQ86I2lo5EDeAuzctXi2I3SZpnOe0 +mCCxJeZhWW0S7JuHvlfhEgXFBPEXzhS4HJLUlZUsWyiJ+3KcINMygaiF7MgIe6hZ +WzpsMatS4mbNFElc89M+YryRFrQc9d1Uqjxhl3ms5MhDNcMP/PNwHa/wnIoqkpNI +qtDoR741wcZ7bdr6XVdF8+pBjzbBPPRSf24x3bqavHBWcTjcSVcM/ZEXxeqH5SN0 +GbK2mQxrogX4UWjtl+DfYvl+ejpEcYNXKEmIabUUHtpG42544cuPtZizLW5bt/aT +JBQfpPZpvf9MUlACxUONFOLQdZ8SXpSJ0e93iX2J2Z52mSQ= +-----END CERTIFICATE----- + + + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/big_server.crt b/test/recipes/81-test_cmp_cli_data/Mock/big_server.crt new file mode 100644 index 00000000..82e46310 --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/big_server.crt @@ -0,0 +1,1550 @@ + Subject: O = openssl_cmp + Issuer: O = openssl_cmp +-----BEGIN CERTIFICATE----- +MIICpTCCAY2gAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQKDAtvcGVu +c3NsX2NtcDAeFw0xNzEyMjAxMzA0MDBaFw0xODEyMjAxMzA0MDBaMBYxFDASBgNV +BAoMC29wZW5zc2xfY21wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZAJHnq0ypW/PZccrWj +o7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVVpLicMnItNFElfCoh +BzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuWq/vWW9r96/gBKKdd +mj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SOZf9bH1olBVsmBMsU +shFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6GvZ/i5KOhaqgJCnRKd +HHzijz9cLec5p9NSOuC1OwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQDGUXpFCBkV +WgPrBfZyBwt6VCjWB/e67q4IdcKMfDa4hwSquah1AyXHI0PlC/qitnoSx2+7f7pY +TEOay/3eEPUl1J5tdPF2Vg56Dw8jdhSkMwO7bXKDEE3R6o6jaa4ECgxwQtdGHmNU +A41PgKX76yEXku803ptO39/UR7i7Ye3MbyAmWE+PvixJYUbxd3fqz5fsaJqTCzAy +AT9hrr4uu8J7m3LYaYXo4LVL4jw5UsP5bIYtpmmEBfy9GhpUqH5/LzBNij7y3ziE +T59wHkzawAQDHsBPuCe07DFtlzqWWvaih0TQAw9MZ2tbyK9jt7P80Rqt9CwpM/i9 +jQYqSl/ix5hn +-----END CERTIFICATE----- + + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/big_trusted.crt b/test/recipes/81-test_cmp_cli_data/Mock/big_trusted.crt new file mode 100644 index 00000000..3bd3458e --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/big_trusted.crt @@ -0,0 +1,1552 @@ + Subject: O = openssl_cmp + Issuer: O = openssl_cmp +-----BEGIN CERTIFICATE----- +MIICpTCCAY2gAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQKDAtvcGVu +c3NsX2NtcDAeFw0xNzEyMjAxMzA0MDBaFw0xODEyMjAxMzA0MDBaMBYxFDASBgNV +BAoMC29wZW5zc2xfY21wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZAJHnq0ypW/PZccrWj +o7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVVpLicMnItNFElfCoh +BzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuWq/vWW9r96/gBKKdd +mj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SOZf9bH1olBVsmBMsU +shFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6GvZ/i5KOhaqgJCnRKd +HHzijz9cLec5p9NSOuC1OwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQDGUXpFCBkV +WgPrBfZyBwt6VCjWB/e67q4IdcKMfDa4hwSquah1AyXHI0PlC/qitnoSx2+7f7pY +TEOay/3eEPUl1J5tdPF2Vg56Dw8jdhSkMwO7bXKDEE3R6o6jaa4ECgxwQtdGHmNU +A41PgKX76yEXku803ptO39/UR7i7Ye3MbyAmWE+PvixJYUbxd3fqz5fsaJqTCzAy +AT9hrr4uu8J7m3LYaYXo4LVL4jw5UsP5bIYtpmmEBfy9GhpUqH5/LzBNij7y3ziE +T59wHkzawAQDHsBPuCe07DFtlzqWWvaih0TQAw9MZ2tbyK9jt7P80Rqt9CwpM/i9 +jQYqSl/ix5hn +-----END CERTIFICATE----- + + + + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT +AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu +ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 +YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j +b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT +wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 +g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY +fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud +JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB +h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f +BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l +dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH +AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds +ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC +GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 +dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 +b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t +ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy +bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl +LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv +b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh +cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n +b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC +CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl +LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv +b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL +Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu +Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv +b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL +Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n +bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n +bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n +bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n +bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n +bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n +bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n +bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n +bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n +bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v +Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou +Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC +DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u +YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j +b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds +ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv +b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q +Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp +gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t +Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu +Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n +bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n +b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP +Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u +aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv +bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl +LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v +Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou +Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC +DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u +c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j +b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds +ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv +b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu +ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v +Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq +Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n +ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n +bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou +Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 +ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v +Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv +ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v +Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq +Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s +dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n +bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou +Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 +ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv +b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC +CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv +b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL +Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu +cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v +Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq +Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 +Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n +bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou +Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 +ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ +Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n +bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i +ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln +b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n +bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j +aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn +b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu +Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC +DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds +ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s +c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v +Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv +LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn +b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu +Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t +LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo +gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n +b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n +bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu +Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t +LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo +gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n +b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n +bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu +Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t +Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m +gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n +b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n +bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu +Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t +LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi +gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n +b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n +bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu +Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC +CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v +Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu +ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ +Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n +bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o +coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn +b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v +Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv +b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl +Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC +CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v +Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu +bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q +cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ +Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ +Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n +bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z +ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln +b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds +ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu +gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv +b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG +9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD +LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 +KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +-----END CERTIFICATE----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/empty.txt b/test/recipes/81-test_cmp_cli_data/Mock/empty.txt new file mode 100644 index 00000000..e69de29b diff --git a/test/recipes/81-test_cmp_cli_data/Mock/issuing.crt b/test/recipes/81-test_cmp_cli_data/Mock/issuing.crt new file mode 100644 index 00000000..ebecbb79 --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/issuing.crt @@ -0,0 +1,45 @@ +Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = subinterCA +-----BEGIN CERTIFICATE----- +MIIDhDCCAmygAwIBAgIJAJkv2OGshkmUMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMTB2ludGVyQ0EwHhcNMTUwNzAyMTMxODIz +WhcNMzUwNzAyMTMxODIzWjBaMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1T +dGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYDVQQD +EwpzdWJpbnRlckNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/zQj +vhbU7RWDsRaEkVUBZWR/PqZ49GoE9p3OyRN4pkt1c1yb2ARVkYZP5e9gHb04wPVz +2+FYy+2mNkl+uAZbcK5w5fWO3WJIEn57he4MkWu3ew1nJeSv3na8gyOoCheG64kW +VbA2YL92mR7QoSCo4SP7RmykLrwj6TlDxqgH6DxKSD/CpdCHE3DKAzAiri3GVc90 +OJAszYHlje4/maVIOayGROVET3xa5cbtRJl8IBgmqhMywtz4hhY/XZTvdEn290aL +857Hk7JjogA7mLKi07yKzknMxHV+k6JX7xJEttkcNQRFHONWZG1T4mRY1Drh6VbJ +Gb+0GNIldNLQqigkfwIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTp +Z30QdMGarrhMPwk+HHAV3R8aTzAfBgNVHSMEGDAWgBQY+tYjuY9dXRN9Po+okcfZ +YcAXLjANBgkqhkiG9w0BAQsFAAOCAQEAgVUsOf9rdHlQDw4clP8GMY7QahfXbvd8 +8o++P18KeInQXH6+sCg0axZXzhOmKwn+Ina3EsOP7xk4aKIYwJ4A1xBuT7fKxquQ +pbJyjkEBsNRVLC9t4gOA0FC791v5bOCZjyff5uN+hy8r0828nVxha6CKLqwrPd+E +mC7DtilSZIgO2vwbTBL6ifmw9n1dd/Bl8Wdjnl7YJqTIf0Ozc2SZSMRUq9ryn4Wq +YrjRl8NwioGb1LfjEJ0wJi2ngL3IgaN94qmDn10OJs8hlsufwP1n+Bca3fsl0m5U +gUMG+CXxbF0kdCKZ9kQb1MJE4vOk6zfyBGQndmQnxHjt5botI/xpXg== +-----END CERTIFICATE----- + +Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = interCA +-----BEGIN CERTIFICATE----- +MIIDgDCCAmigAwIBAgIJANnoWlLlEsTgMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE3MDVa +Fw0zNTA3MDIxMzE3MDVaMFcxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 +YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMT +B2ludGVyQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7s0ejvpQO +nvfwD+e4R+9WQovtrsqOTw8khiREqi5JlmAFbpDEFam18npRkt6gOcGMnjuFzuz6 +iEuQmeeyh0BqWAwpMgWMMteEzLOAaqkEl//J2+WgRbA/8pmwHfbPW/d+f3bp64Fo +D1hQAenBzXmLxVohEQ9BA+xEDRkL/cA3Y+k/O1C9ORhSQrJNsB9aE3zKbFHd9mOm +H4aNSsF8On3SqlRVOCQine5c6ACSd0HUEjYy9aObqY47ySNULbzVq5y6VOjMs0W+ +2G/XqrcVkxzf9bVqyVBrrAJrnb35/y/iK0zWgJBP+HXhwr5mMTvNuEirBeVYuz+6 +hUerUbuJhr0FAgMBAAGjUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFBj61iO5 +j11dE30+j6iRx9lhwBcuMB8GA1UdIwQYMBaAFIVWiTXinwAa4YYDC0uvdhJrM239 +MA0GCSqGSIb3DQEBCwUAA4IBAQDAU0MvL/yZpmibhxUsoSsa97UJbejn5IbxpPzZ +4WHw8lsoUGs12ZHzQJ9LxkZVeuccFXy9yFEHW56GTlkBmD2qrddlmQCfQ3m8jtZ9 +Hh5feKAyrqfmfsWF5QPjAmdj/MFdq+yMJVosDftkmUmaBHjzbvbcq1sWh/6drH8U +7pdYRpfeEY8dHSU6FHwVN/H8VaBB7vYYc2wXwtk8On7z2ocIVHn9RPkcLwmwJjb/ +e4jmcYiyZev22KXQudeHc4w6crWiEFkVspomn5PqDmza3rkdB3baXFVZ6sd23ufU +wjkiKKtwRBwU+5tCCagQZoeQ5dZXQThkiH2XEIOCOLxyD/tb +-----END CERTIFICATE----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/new.key b/test/recipes/81-test_cmp_cli_data/Mock/new.key new file mode 100755 index 00000000..a1b17212 --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/new.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAv0Qo9WC/BKA70LtQJdwVGSXqr9dut3cQmiFzTb/SaWldjOT1 +sRNDFxSzdTJjU/8cIDEZvaTIwRxP/dtVQLjc+4jzrUwz93NuZYlsEWUEUg4Lrnfs +0Nz50yHk4rJhVxWjb8Ii/wRBViWHFExP7CwTkXiTclC1bCqTuWkjxF3thTfTsttR +yY7qNkz2JpNx0guD8v4otQoYjA5AEZvK4IXLwOwxol5xBTMvIrvvff2kkh+c7OC2 +QVbUTow/oppjqIKCx2maNHCtLFTJELf3fwtRJLJsy4fKGP0/6kpZc8Sp88WK4B4F +auF9IV1CmoAJUC1vJxhagHIKfVtFjUWs8GPobQIDAQABAoIBAB1fCiskQDElqgnT +uesWcOb7u55lJstlrVb97Ab0fgtR8tvADTq0Colw1F4a7sXnVxpab+l/dJSzFFWX +aPAXc1ftH/5sxU4qm7lb8Qx6xr8TCRgxslwgkvypJ8zoN6p32DFBTr56mM3x1Vx4 +m41Y92hPa9USL8n8f9LpImT1R5Q9ShI/RUCowPyzhC6OGkFSBJu72nyA3WK0znXn +q5TNsTRdJLOug7eoJJvhOPfy3neNQV0f2jQ+2wDKCYvn6i4j9FSLgYC/vorqofEd +vFBHxl374117F6DXdBChyD4CD5vsplB0zcExRUCT5+iBqf5uc8CbLHeyNk6vSaf5 +BljHWsECgYEA93QnlKsVycgCQqHt2q8EIZ5p7ksGYRVfBEzgetsNdpxvSwrLyLQE +L5AKG3upndOofCeJnLuQF1j954FjCs5Y+8Sy2H1D1EPrHSBp4ig2F5aOxT3vYROd +v+/mF4ZUzlIlv3jNDz5IoLaxm9vhXTtLLUtQyTueGDmqwlht0Kr3/gcCgYEAxd86 +Q23jT4DmJqUl+g0lWdc2dgej0jwFfJ2BEw/Q55vHjqj96oAX5QQZFOUhZU8Otd/D +lLzlsFn0pOaSW/RB4l5Kv8ab+ZpxfAV6Gq47nlfzmEGGx4wcoL0xkHufiXg0sqaG +UtEMSKFhxPQZhWojUimK/+YIF69molxA6G9miOsCgYEA8mICSytxwh55qE74rtXz +1AJZfKJcc0f9tDahQ3XBsEb29Kh0h/lciEIsxFLTB9dFF6easb0/HL98pQElxHXu +z14SWOAKSqbka7lOPcppgZ1l52oNSiduw4z28mAQPbBVbUGkiqPVfCa3vhUYoLvt +nUZCsXoGF3CVBJydpGFzXI0CgYEAtt3Jg72PoM8YZEimI0R462F4xHXlEYtE6tjJ +C+vG/fU65P4Kw+ijrJQv9d6YEX+RscXdg51bjLJl5OvuAStopCLOZBPR3Ei+bobF +RNkW4gyYZHLSc6JqZqbSopuNYkeENEKvyuPFvW3f5FxPJbxkbi9UdZCKlBEXAh/O +IMGregcCgYBC8bS7zk6KNDy8q2uC/m/g6LRMxpb8G4jsrcLoyuJs3zDckBjQuLJQ +IOMXcQBWN1h+DKekF2ecr3fJAJyEv4pU4Ct2r/ZTYFMdJTyAbjw0mqOjUR4nsdOh +t/vCbt0QW3HXYTcVdCnFqBtelKnI12KoC0jAO9EAJGZ6kE/NwG6dQg== +-----END RSA PRIVATE KEY----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/new_pass_12345.key b/test/recipes/81-test_cmp_cli_data/Mock/new_pass_12345.key new file mode 100644 index 00000000..e1aabfeb --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/new_pass_12345.key @@ -0,0 +1,30 @@ +-----BEGIN ENCRYPTED PRIVATE KEY----- +MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIuH8X1xWl9ygCAggA +MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBCw27UHDuBtxWa928AXEEb1BIIE +0A/aH/nMGoifA4TKpLg1SobskugzWV7+N2qh3j9LZrz6GxB9jR64JBx8+eKBu5lv +VeMp/cIuGZscJ56QFZ01tTEyIiP1eeD68eQol2n7KEwk9DKkR2QbQuLDOaR4voqM +rm02uehLnNPJ7d81CrgfqIRi5OF4cWVV20jN7pQMxn8KqW4OYPdOrV1i6mTnsbNz +M5hL9YMud4wppWwA93MLD4TGvQBQSTvreYtLNy1atq1uK4k2KZh2tw/CTNiCo47R +N6Ft+CDJblikodpj/a6ZPJ84qBMonTbc7IMvkeWP0mnzA25ohOW7RfhgWzz/mfx3 +/ypX8xqLd8JzmdRFOcc5MFdVcYPmgFzFVtEJ0bBZx6WCW+6OszLkt/7p7raRKirA +/zJJSBmEvQKvwtZ6I/rG6SqMFiTseRuWq0sXa1NX2zlH9y+g68K+7Bt5816l93WD +p0GQgWxXV2J+QJ3fGvxMdQG7qmGWx6dc6yZkFw9e94sTHH74fShTv53OekCgWg2B +58pFBTK9NGtiG5LawtDKMqlYcSKvfqjvKwDokQS104DwM+om0QBLTH+RRxh05jYv +2hx1uwSXoo8oO+AYaYsEQE8z7mYxQr5Ea1gKbtyYPE0Eo5rrH9fYzXN8A1LH7wbL +ywQIZq/lthuJGarTPCFjoHrPW9O+FiQBLsn5Ej2VVm2MQpS3v6m7SnHTWBaPZvkq +GEGw/MZiwkzyULsg7zRKfnNhYBfxdg+gmwIR6x1e4vT6hAFjZbvn1eOlFTLqIBpE +XQCqxaITtW6bCEhvl/c0AKkAWM39XEs/ff1giYza+6SLgLQObHApp+Q/Hk3PaUDq +Wnm/5w8IyQcGDAik0f6JqbQ+licBk5lHlOifO0GFKqePlKLY/Mvx9al2UflzOydG +u9BpXx8sLooLuyycXFhgpZZLp19+79KgPm+ZrXKlKKwTDQwuB+eGxr2wKWCbJb2y +gmnBCtml5apTQx+l630GldMjkhwxOSZJoXy6XKQew85L/J9Jknta3bjGbyL2lEeW +/gfT+L6WrmG3Hf4xGhpkkx6UITzujJbE2/YyxJ+sXlRuYd4ld0Hfn6Ihsajknj8G +jvLb77FvgNndf5SXlqU3sMGcOPizQkMr/AmtHPzBLT8O6OxpeAOWzG3jOvznRsmZ +27nmW4cM/6t/86PvnAssPETFcrC3GqFYWnzdVaWunCz5zn4xIot3633VGR1lbxX4 +kTQLBzgBjKuajgVim5Q4obfaqnJEvHkbJaAFJg0y6uId2RIzYo5/onHrVOQR5ulB +qyR8YJjWu3pyq8t5q9Iw3L+pWDOh4AH7/ay0IBu/qxapvybqEXyol3kAJIsY0AKZ +Y5dPA4duWjW0MHNDgliAssKr2t3CTALU9nrBVX1fEPR4Y05JZ9f4OIueu/IGdDIE +snLdqtkY0sOTma9FhKDv1RwsumT/UfOqUJ3ZSJCaKgE/RnzS3YN+j5BYv788micZ +S9nl5KX+q/VSVXxial0nxkGiqs73mASF5JP4iarRihSntGMvn4PPB7Oid5SVLrqk +JFFy7pjL8xuERx0hlShUl2q8/C3DSi0u+QkIhNrUBKZRADzNDkJcfWmKwbhq7HPp +ghzvaDrFtH/4o8t7kd+TVdKjnS0cna43Sj94w3J5/y5Y +-----END ENCRYPTED PRIVATE KEY----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/random.bin b/test/recipes/81-test_cmp_cli_data/Mock/random.bin new file mode 100644 index 00000000..1df23d4d Binary files /dev/null and b/test/recipes/81-test_cmp_cli_data/Mock/random.bin differ diff --git a/test/recipes/81-test_cmp_cli_data/Mock/root.crt b/test/recipes/81-test_cmp_cli_data/Mock/root.crt new file mode 100644 index 00000000..30fb8317 --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/root.crt @@ -0,0 +1,22 @@ +Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = rootCA +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIJAIhDKcvC6xWaMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE1MTFa +Fw0zNTA3MDIxMzE1MTFaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0 +YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMM +BnJvb3RDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMDxa3eIrDXf ++3NTL5KAL3QWMk31ECBvbDqO0dxr4S4+wwQPv5vEyRLR5AtFl+UGzWY64eDiK9+i +xOx70z08iv9edKCrpwNqFlteksR+W3mKadS8g16uQpJ0pSvnAMGp3NWxUwcPc/eO +rRQ+JZ7lHubMkc2VDIBEIMP9F8+RPWMQHBRb+8OowYiyd/+c2/xqRERE94XsCCzU +34Gjecn+HpuTFlO3l6u+Txql4vpGBeQNnCqkzLkeIaBsxKtZsEA5u/mIrf3fjbQL +r35B4CE8yDNFSYQvkwbu/U/tT/O8m978JV5V1XXUxXs6QDUGn8SEtGyTDK83Wq+2 +QU0mIxy4ArMCAwEAAaNQME4wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUhVaJNeKf +ABrhhgMLS692Emszbf0wHwYDVR0jBBgwFoAUhVaJNeKfABrhhgMLS692Emszbf0w +DQYJKoZIhvcNAQELBQADggEBADIKvyoK4rtPQ86I2lo5EDeAuzctXi2I3SZpnOe0 +mCCxJeZhWW0S7JuHvlfhEgXFBPEXzhS4HJLUlZUsWyiJ+3KcINMygaiF7MgIe6hZ +WzpsMatS4mbNFElc89M+YryRFrQc9d1Uqjxhl3ms5MhDNcMP/PNwHa/wnIoqkpNI +qtDoR741wcZ7bdr6XVdF8+pBjzbBPPRSf24x3bqavHBWcTjcSVcM/ZEXxeqH5SN0 +GbK2mQxrogX4UWjtl+DfYvl+ejpEcYNXKEmIabUUHtpG42544cuPtZizLW5bt/aT +JBQfpPZpvf9MUlACxUONFOLQdZ8SXpSJ0e93iX2J2Z52mSQ= +-----END CERTIFICATE----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/server.cnf b/test/recipes/81-test_cmp_cli_data/Mock/server.cnf new file mode 100644 index 00000000..af0f0f0c --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/server.cnf @@ -0,0 +1,16 @@ +[cmp] # mock server configuration + +port = 1700 +srv_secret = pass:test +srv_cert = server.crt +srv_key = server.key + +#accept_unprotected +no_check_time = 1 +srv_trusted = signer_root.crt + +rsp_cert = signer_only.crt +rsp_capubs = signer_root.crt +rsp_extracerts = signer_issuing.crt + + diff --git a/test/recipes/81-test_cmp_cli_data/Mock/server.crt b/test/recipes/81-test_cmp_cli_data/Mock/server.crt new file mode 100644 index 00000000..31d9cc9c --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/server.crt @@ -0,0 +1,19 @@ + Subject: O = openssl_cmp + Issuer: O = openssl_cmp +-----BEGIN CERTIFICATE----- +MIICpTCCAY2gAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQKDAtvcGVu +c3NsX2NtcDAeFw0xNzEyMjAxMzA0MDBaFw0xODEyMjAxMzA0MDBaMBYxFDASBgNV +BAoMC29wZW5zc2xfY21wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZAJHnq0ypW/PZccrWj +o7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVVpLicMnItNFElfCoh +BzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuWq/vWW9r96/gBKKdd +mj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SOZf9bH1olBVsmBMsU +shFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6GvZ/i5KOhaqgJCnRKd +HHzijz9cLec5p9NSOuC1OwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQDGUXpFCBkV +WgPrBfZyBwt6VCjWB/e67q4IdcKMfDa4hwSquah1AyXHI0PlC/qitnoSx2+7f7pY +TEOay/3eEPUl1J5tdPF2Vg56Dw8jdhSkMwO7bXKDEE3R6o6jaa4ECgxwQtdGHmNU +A41PgKX76yEXku803ptO39/UR7i7Ye3MbyAmWE+PvixJYUbxd3fqz5fsaJqTCzAy +AT9hrr4uu8J7m3LYaYXo4LVL4jw5UsP5bIYtpmmEBfy9GhpUqH5/LzBNij7y3ziE +T59wHkzawAQDHsBPuCe07DFtlzqWWvaih0TQAw9MZ2tbyK9jt7P80Rqt9CwpM/i9 +jQYqSl/ix5hn +-----END CERTIFICATE----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/server.key b/test/recipes/81-test_cmp_cli_data/Mock/server.key new file mode 100644 index 00000000..23242667 --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZA +JHnq0ypW/PZccrWjo7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVV +pLicMnItNFElfCohBzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuW +q/vWW9r96/gBKKddmj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SO +Zf9bH1olBVsmBMsUshFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6Gv +Z/i5KOhaqgJCnRKdHHzijz9cLec5p9NSOuC1OwIDAQABAoIBAGiYVO+rIfqc38jG +sMxJED2NSBFnvE7k2LoeEgktBA0daxQgziYXtIkOXC3jkwAw1RXLuGH5RTDuJt3/ +LX6nsCW3NCCB6lTGERNaJyKg4dLHpzA+juY3/2P/MKHD1bGncpV7jNk2fpV7gBY1 +pu0wld1Oi+S3DPCaxs3w6Zl39Y4Z7oSNf6DRO5lGN3Asc8TSVjIOWpAl8LIg+P2B +ZvFeHRANVXaV9YmF2uEi7iMgH4vGrK2svsmM9VThVO4ArGcTRTvGYn7aw3/H4Pt+ +lYuhERdpkKBT0tCgIpO5IJXMl4/5RSDTtcBwiJcReN5IHUAItBIPSHcMflNSKG/I +aQf4u0ECgYEA8+PAyzn096Y2UrKzE75yuadCveLjsUWx2NN5ZMohQru99F4k7Pab +/Te4qOe5zlxHAPK3LRwvbwUWo5mLfs45wFrSgZoRlYcCuL+JaX0y2oXMMF9E+UkY +tljMt/HpLo1SfSjN2Sae4LVhC7rWJ43LtyRepptzBPGqd26eLPGAMr8CgYEA7P8u +RGkMOrMzEKAb0A9smrzq2xW88T1VejqEt6R8mUcNt8PFHMgjuzVU4zDysrlb7G/0 +VSkQWnJxBh1yNGc1Av7YgwicIgApr4ty0hZhLcnKX2VrNw+L/sSe/cnwVAc6RtPK +RR6xQubuLlrCGcbYXmyn5Jv+nlY0S3uCyDFHqIUCgYAwtpLxhJf7RwWeqva9wNJl +ZpUcHE9iPwtwxXx/tyfBjoI4Zv11HyS1BQYrJm2kXCYKeHBB4FlREXEeKDMGluZO +F1XocP+GIDtY71jg6xLXNtY76yt5pzH6ae4p53WtyKhrO1UyRFaDh3bkwuK3b8j6 +wZbuLCpjGGn2BPAvBeWXPQKBgEewKN6op/pZmmi9Bay5/bAQ1TnQKYcPdnuyl9K0 +/ruespeTsFw0bhqC11qhw8gsKZIri0z3TusNEwM2hQU08uQlEnkQcaoXQoTHOcQy +4NJo575Tf0r4ePBnqXA7VWcViJtEFTszPYtvLzz2VyBU9b4aP+73AN4EVW0/vx+v +SG3BAoGBAMzESFA2TXwUFmozK5zowIszc995Xqpi7mXKk77WESOpoS1dQ1wF1dSg +XOwxzFoYovLxcc1K9lqOrod8BV+qGuEfc/PIJ2aiXjvEDeZYX2eWaANNmj4OSLoJ +MNYj9tZxbq56slD7snf7AgUBnwKz0Pj6H6UsbE3gdJqZWCDyw/bB +-----END RSA PRIVATE KEY----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/signer.crt b/test/recipes/81-test_cmp_cli_data/Mock/signer.crt new file mode 100644 index 00000000..cb72e33b --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/signer.crt @@ -0,0 +1,68 @@ +Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = leaf +-----BEGIN CERTIFICATE----- +MIIDfjCCAmagAwIBAgIJAKRNsDKacUqNMA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxEzARBgNVBAMTCnN1YmludGVyQ0EwHhcNMTUwNzAyMTMx +OTQ5WhcNMzUwNzAyMTMxOTQ5WjBUMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29t +ZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ0wCwYD +VQQDEwRsZWFmMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv0Qo9WC/ +BKA70LtQJdwVGSXqr9dut3cQmiFzTb/SaWldjOT1sRNDFxSzdTJjU/8cIDEZvaTI +wRxP/dtVQLjc+4jzrUwz93NuZYlsEWUEUg4Lrnfs0Nz50yHk4rJhVxWjb8Ii/wRB +ViWHFExP7CwTkXiTclC1bCqTuWkjxF3thTfTsttRyY7qNkz2JpNx0guD8v4otQoY +jA5AEZvK4IXLwOwxol5xBTMvIrvvff2kkh+c7OC2QVbUTow/oppjqIKCx2maNHCt +LFTJELf3fwtRJLJsy4fKGP0/6kpZc8Sp88WK4B4FauF9IV1CmoAJUC1vJxhagHIK +fVtFjUWs8GPobQIDAQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBQcHcT+8SVG +IRlN9YTuM9rlz7UZfzAfBgNVHSMEGDAWgBTpZ30QdMGarrhMPwk+HHAV3R8aTzAN +BgkqhkiG9w0BAQsFAAOCAQEAGjmSkF8is+v0/RLcnSRiCXENz+yNi4pFCAt6dOtT +6Gtpqa1tY5It9lVppfWb26JrygMIzOr/fB0r1Q7FtZ/7Ft3P6IXVdk3GDO0QsORD +2dRAejhYpc5c7joHxAw9oRfKrEqE+ihVPUTcfcIuBaalvuhkpQRmKP71ws5DVzOw +QhnMd0TtIrbKHaNQ4kNsmSY5fQolwB0LtNfTus7OEFdcZWhOXrWImKXN9jewPKdV +mSG34NfXOnA6qx0eQg06z+TkdrptH6j1Va2vS1/bL+h1GxjpTHlvTGaZYxaloIjw +y/EzY5jygRoABnR3eBm15CYZwwKL9izIq1H3OhymEi/Ycg== +-----END CERTIFICATE----- + +Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = subinterCA +-----BEGIN CERTIFICATE----- +MIIDhDCCAmygAwIBAgIJAJkv2OGshkmUMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMTB2ludGVyQ0EwHhcNMTUwNzAyMTMxODIz +WhcNMzUwNzAyMTMxODIzWjBaMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1T +dGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYDVQQD +EwpzdWJpbnRlckNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/zQj +vhbU7RWDsRaEkVUBZWR/PqZ49GoE9p3OyRN4pkt1c1yb2ARVkYZP5e9gHb04wPVz +2+FYy+2mNkl+uAZbcK5w5fWO3WJIEn57he4MkWu3ew1nJeSv3na8gyOoCheG64kW +VbA2YL92mR7QoSCo4SP7RmykLrwj6TlDxqgH6DxKSD/CpdCHE3DKAzAiri3GVc90 +OJAszYHlje4/maVIOayGROVET3xa5cbtRJl8IBgmqhMywtz4hhY/XZTvdEn290aL +857Hk7JjogA7mLKi07yKzknMxHV+k6JX7xJEttkcNQRFHONWZG1T4mRY1Drh6VbJ +Gb+0GNIldNLQqigkfwIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTp +Z30QdMGarrhMPwk+HHAV3R8aTzAfBgNVHSMEGDAWgBQY+tYjuY9dXRN9Po+okcfZ +YcAXLjANBgkqhkiG9w0BAQsFAAOCAQEAgVUsOf9rdHlQDw4clP8GMY7QahfXbvd8 +8o++P18KeInQXH6+sCg0axZXzhOmKwn+Ina3EsOP7xk4aKIYwJ4A1xBuT7fKxquQ +pbJyjkEBsNRVLC9t4gOA0FC791v5bOCZjyff5uN+hy8r0828nVxha6CKLqwrPd+E +mC7DtilSZIgO2vwbTBL6ifmw9n1dd/Bl8Wdjnl7YJqTIf0Ozc2SZSMRUq9ryn4Wq +YrjRl8NwioGb1LfjEJ0wJi2ngL3IgaN94qmDn10OJs8hlsufwP1n+Bca3fsl0m5U +gUMG+CXxbF0kdCKZ9kQb1MJE4vOk6zfyBGQndmQnxHjt5botI/xpXg== +-----END CERTIFICATE----- + +Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = interCA +-----BEGIN CERTIFICATE----- +MIIDgDCCAmigAwIBAgIJANnoWlLlEsTgMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE3MDVa +Fw0zNTA3MDIxMzE3MDVaMFcxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 +YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMT +B2ludGVyQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7s0ejvpQO +nvfwD+e4R+9WQovtrsqOTw8khiREqi5JlmAFbpDEFam18npRkt6gOcGMnjuFzuz6 +iEuQmeeyh0BqWAwpMgWMMteEzLOAaqkEl//J2+WgRbA/8pmwHfbPW/d+f3bp64Fo +D1hQAenBzXmLxVohEQ9BA+xEDRkL/cA3Y+k/O1C9ORhSQrJNsB9aE3zKbFHd9mOm +H4aNSsF8On3SqlRVOCQine5c6ACSd0HUEjYy9aObqY47ySNULbzVq5y6VOjMs0W+ +2G/XqrcVkxzf9bVqyVBrrAJrnb35/y/iK0zWgJBP+HXhwr5mMTvNuEirBeVYuz+6 +hUerUbuJhr0FAgMBAAGjUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFBj61iO5 +j11dE30+j6iRx9lhwBcuMB8GA1UdIwQYMBaAFIVWiTXinwAa4YYDC0uvdhJrM239 +MA0GCSqGSIb3DQEBCwUAA4IBAQDAU0MvL/yZpmibhxUsoSsa97UJbejn5IbxpPzZ +4WHw8lsoUGs12ZHzQJ9LxkZVeuccFXy9yFEHW56GTlkBmD2qrddlmQCfQ3m8jtZ9 +Hh5feKAyrqfmfsWF5QPjAmdj/MFdq+yMJVosDftkmUmaBHjzbvbcq1sWh/6drH8U +7pdYRpfeEY8dHSU6FHwVN/H8VaBB7vYYc2wXwtk8On7z2ocIVHn9RPkcLwmwJjb/ +e4jmcYiyZev22KXQudeHc4w6crWiEFkVspomn5PqDmza3rkdB3baXFVZ6sd23ufU +wjkiKKtwRBwU+5tCCagQZoeQ5dZXQThkiH2XEIOCOLxyD/tb +-----END CERTIFICATE----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/signer.key b/test/recipes/81-test_cmp_cli_data/Mock/signer.key new file mode 100755 index 00000000..a1b17212 --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/signer.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAv0Qo9WC/BKA70LtQJdwVGSXqr9dut3cQmiFzTb/SaWldjOT1 +sRNDFxSzdTJjU/8cIDEZvaTIwRxP/dtVQLjc+4jzrUwz93NuZYlsEWUEUg4Lrnfs +0Nz50yHk4rJhVxWjb8Ii/wRBViWHFExP7CwTkXiTclC1bCqTuWkjxF3thTfTsttR +yY7qNkz2JpNx0guD8v4otQoYjA5AEZvK4IXLwOwxol5xBTMvIrvvff2kkh+c7OC2 +QVbUTow/oppjqIKCx2maNHCtLFTJELf3fwtRJLJsy4fKGP0/6kpZc8Sp88WK4B4F +auF9IV1CmoAJUC1vJxhagHIKfVtFjUWs8GPobQIDAQABAoIBAB1fCiskQDElqgnT +uesWcOb7u55lJstlrVb97Ab0fgtR8tvADTq0Colw1F4a7sXnVxpab+l/dJSzFFWX +aPAXc1ftH/5sxU4qm7lb8Qx6xr8TCRgxslwgkvypJ8zoN6p32DFBTr56mM3x1Vx4 +m41Y92hPa9USL8n8f9LpImT1R5Q9ShI/RUCowPyzhC6OGkFSBJu72nyA3WK0znXn +q5TNsTRdJLOug7eoJJvhOPfy3neNQV0f2jQ+2wDKCYvn6i4j9FSLgYC/vorqofEd +vFBHxl374117F6DXdBChyD4CD5vsplB0zcExRUCT5+iBqf5uc8CbLHeyNk6vSaf5 +BljHWsECgYEA93QnlKsVycgCQqHt2q8EIZ5p7ksGYRVfBEzgetsNdpxvSwrLyLQE +L5AKG3upndOofCeJnLuQF1j954FjCs5Y+8Sy2H1D1EPrHSBp4ig2F5aOxT3vYROd +v+/mF4ZUzlIlv3jNDz5IoLaxm9vhXTtLLUtQyTueGDmqwlht0Kr3/gcCgYEAxd86 +Q23jT4DmJqUl+g0lWdc2dgej0jwFfJ2BEw/Q55vHjqj96oAX5QQZFOUhZU8Otd/D +lLzlsFn0pOaSW/RB4l5Kv8ab+ZpxfAV6Gq47nlfzmEGGx4wcoL0xkHufiXg0sqaG +UtEMSKFhxPQZhWojUimK/+YIF69molxA6G9miOsCgYEA8mICSytxwh55qE74rtXz +1AJZfKJcc0f9tDahQ3XBsEb29Kh0h/lciEIsxFLTB9dFF6easb0/HL98pQElxHXu +z14SWOAKSqbka7lOPcppgZ1l52oNSiduw4z28mAQPbBVbUGkiqPVfCa3vhUYoLvt +nUZCsXoGF3CVBJydpGFzXI0CgYEAtt3Jg72PoM8YZEimI0R462F4xHXlEYtE6tjJ +C+vG/fU65P4Kw+ijrJQv9d6YEX+RscXdg51bjLJl5OvuAStopCLOZBPR3Ei+bobF +RNkW4gyYZHLSc6JqZqbSopuNYkeENEKvyuPFvW3f5FxPJbxkbi9UdZCKlBEXAh/O +IMGregcCgYBC8bS7zk6KNDy8q2uC/m/g6LRMxpb8G4jsrcLoyuJs3zDckBjQuLJQ +IOMXcQBWN1h+DKekF2ecr3fJAJyEv4pU4Ct2r/ZTYFMdJTyAbjw0mqOjUR4nsdOh +t/vCbt0QW3HXYTcVdCnFqBtelKnI12KoC0jAO9EAJGZ6kE/NwG6dQg== +-----END RSA PRIVATE KEY----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/signer.p12 b/test/recipes/81-test_cmp_cli_data/Mock/signer.p12 new file mode 100644 index 00000000..6eab305f Binary files /dev/null and b/test/recipes/81-test_cmp_cli_data/Mock/signer.p12 differ diff --git a/test/recipes/81-test_cmp_cli_data/Mock/signer_issuing.crt b/test/recipes/81-test_cmp_cli_data/Mock/signer_issuing.crt new file mode 100644 index 00000000..ebecbb79 --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/signer_issuing.crt @@ -0,0 +1,45 @@ +Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = subinterCA +-----BEGIN CERTIFICATE----- +MIIDhDCCAmygAwIBAgIJAJkv2OGshkmUMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMTB2ludGVyQ0EwHhcNMTUwNzAyMTMxODIz +WhcNMzUwNzAyMTMxODIzWjBaMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1T +dGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYDVQQD +EwpzdWJpbnRlckNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/zQj +vhbU7RWDsRaEkVUBZWR/PqZ49GoE9p3OyRN4pkt1c1yb2ARVkYZP5e9gHb04wPVz +2+FYy+2mNkl+uAZbcK5w5fWO3WJIEn57he4MkWu3ew1nJeSv3na8gyOoCheG64kW +VbA2YL92mR7QoSCo4SP7RmykLrwj6TlDxqgH6DxKSD/CpdCHE3DKAzAiri3GVc90 +OJAszYHlje4/maVIOayGROVET3xa5cbtRJl8IBgmqhMywtz4hhY/XZTvdEn290aL +857Hk7JjogA7mLKi07yKzknMxHV+k6JX7xJEttkcNQRFHONWZG1T4mRY1Drh6VbJ +Gb+0GNIldNLQqigkfwIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTp +Z30QdMGarrhMPwk+HHAV3R8aTzAfBgNVHSMEGDAWgBQY+tYjuY9dXRN9Po+okcfZ +YcAXLjANBgkqhkiG9w0BAQsFAAOCAQEAgVUsOf9rdHlQDw4clP8GMY7QahfXbvd8 +8o++P18KeInQXH6+sCg0axZXzhOmKwn+Ina3EsOP7xk4aKIYwJ4A1xBuT7fKxquQ +pbJyjkEBsNRVLC9t4gOA0FC791v5bOCZjyff5uN+hy8r0828nVxha6CKLqwrPd+E +mC7DtilSZIgO2vwbTBL6ifmw9n1dd/Bl8Wdjnl7YJqTIf0Ozc2SZSMRUq9ryn4Wq +YrjRl8NwioGb1LfjEJ0wJi2ngL3IgaN94qmDn10OJs8hlsufwP1n+Bca3fsl0m5U +gUMG+CXxbF0kdCKZ9kQb1MJE4vOk6zfyBGQndmQnxHjt5botI/xpXg== +-----END CERTIFICATE----- + +Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = interCA +-----BEGIN CERTIFICATE----- +MIIDgDCCAmigAwIBAgIJANnoWlLlEsTgMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE3MDVa +Fw0zNTA3MDIxMzE3MDVaMFcxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 +YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMT +B2ludGVyQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7s0ejvpQO +nvfwD+e4R+9WQovtrsqOTw8khiREqi5JlmAFbpDEFam18npRkt6gOcGMnjuFzuz6 +iEuQmeeyh0BqWAwpMgWMMteEzLOAaqkEl//J2+WgRbA/8pmwHfbPW/d+f3bp64Fo +D1hQAenBzXmLxVohEQ9BA+xEDRkL/cA3Y+k/O1C9ORhSQrJNsB9aE3zKbFHd9mOm +H4aNSsF8On3SqlRVOCQine5c6ACSd0HUEjYy9aObqY47ySNULbzVq5y6VOjMs0W+ +2G/XqrcVkxzf9bVqyVBrrAJrnb35/y/iK0zWgJBP+HXhwr5mMTvNuEirBeVYuz+6 +hUerUbuJhr0FAgMBAAGjUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFBj61iO5 +j11dE30+j6iRx9lhwBcuMB8GA1UdIwQYMBaAFIVWiTXinwAa4YYDC0uvdhJrM239 +MA0GCSqGSIb3DQEBCwUAA4IBAQDAU0MvL/yZpmibhxUsoSsa97UJbejn5IbxpPzZ +4WHw8lsoUGs12ZHzQJ9LxkZVeuccFXy9yFEHW56GTlkBmD2qrddlmQCfQ3m8jtZ9 +Hh5feKAyrqfmfsWF5QPjAmdj/MFdq+yMJVosDftkmUmaBHjzbvbcq1sWh/6drH8U +7pdYRpfeEY8dHSU6FHwVN/H8VaBB7vYYc2wXwtk8On7z2ocIVHn9RPkcLwmwJjb/ +e4jmcYiyZev22KXQudeHc4w6crWiEFkVspomn5PqDmza3rkdB3baXFVZ6sd23ufU +wjkiKKtwRBwU+5tCCagQZoeQ5dZXQThkiH2XEIOCOLxyD/tb +-----END CERTIFICATE----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/signer_only.crt b/test/recipes/81-test_cmp_cli_data/Mock/signer_only.crt new file mode 100755 index 00000000..bb94d126 --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/signer_only.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDfjCCAmagAwIBAgIJAKRNsDKacUqNMA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxEzARBgNVBAMTCnN1YmludGVyQ0EwHhcNMTUwNzAyMTMx +OTQ5WhcNMzUwNzAyMTMxOTQ5WjBUMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29t +ZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ0wCwYD +VQQDEwRsZWFmMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv0Qo9WC/ +BKA70LtQJdwVGSXqr9dut3cQmiFzTb/SaWldjOT1sRNDFxSzdTJjU/8cIDEZvaTI +wRxP/dtVQLjc+4jzrUwz93NuZYlsEWUEUg4Lrnfs0Nz50yHk4rJhVxWjb8Ii/wRB +ViWHFExP7CwTkXiTclC1bCqTuWkjxF3thTfTsttRyY7qNkz2JpNx0guD8v4otQoY +jA5AEZvK4IXLwOwxol5xBTMvIrvvff2kkh+c7OC2QVbUTow/oppjqIKCx2maNHCt +LFTJELf3fwtRJLJsy4fKGP0/6kpZc8Sp88WK4B4FauF9IV1CmoAJUC1vJxhagHIK +fVtFjUWs8GPobQIDAQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBQcHcT+8SVG +IRlN9YTuM9rlz7UZfzAfBgNVHSMEGDAWgBTpZ30QdMGarrhMPwk+HHAV3R8aTzAN +BgkqhkiG9w0BAQsFAAOCAQEAGjmSkF8is+v0/RLcnSRiCXENz+yNi4pFCAt6dOtT +6Gtpqa1tY5It9lVppfWb26JrygMIzOr/fB0r1Q7FtZ/7Ft3P6IXVdk3GDO0QsORD +2dRAejhYpc5c7joHxAw9oRfKrEqE+ihVPUTcfcIuBaalvuhkpQRmKP71ws5DVzOw +QhnMd0TtIrbKHaNQ4kNsmSY5fQolwB0LtNfTus7OEFdcZWhOXrWImKXN9jewPKdV +mSG34NfXOnA6qx0eQg06z+TkdrptH6j1Va2vS1/bL+h1GxjpTHlvTGaZYxaloIjw +y/EzY5jygRoABnR3eBm15CYZwwKL9izIq1H3OhymEi/Ycg== +-----END CERTIFICATE----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/signer_root.crt b/test/recipes/81-test_cmp_cli_data/Mock/signer_root.crt new file mode 100644 index 00000000..30fb8317 --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/signer_root.crt @@ -0,0 +1,22 @@ +Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = rootCA +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIJAIhDKcvC6xWaMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE1MTFa +Fw0zNTA3MDIxMzE1MTFaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0 +YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMM +BnJvb3RDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMDxa3eIrDXf ++3NTL5KAL3QWMk31ECBvbDqO0dxr4S4+wwQPv5vEyRLR5AtFl+UGzWY64eDiK9+i +xOx70z08iv9edKCrpwNqFlteksR+W3mKadS8g16uQpJ0pSvnAMGp3NWxUwcPc/eO +rRQ+JZ7lHubMkc2VDIBEIMP9F8+RPWMQHBRb+8OowYiyd/+c2/xqRERE94XsCCzU +34Gjecn+HpuTFlO3l6u+Txql4vpGBeQNnCqkzLkeIaBsxKtZsEA5u/mIrf3fjbQL +r35B4CE8yDNFSYQvkwbu/U/tT/O8m978JV5V1XXUxXs6QDUGn8SEtGyTDK83Wq+2 +QU0mIxy4ArMCAwEAAaNQME4wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUhVaJNeKf +ABrhhgMLS692Emszbf0wHwYDVR0jBBgwFoAUhVaJNeKfABrhhgMLS692Emszbf0w +DQYJKoZIhvcNAQELBQADggEBADIKvyoK4rtPQ86I2lo5EDeAuzctXi2I3SZpnOe0 +mCCxJeZhWW0S7JuHvlfhEgXFBPEXzhS4HJLUlZUsWyiJ+3KcINMygaiF7MgIe6hZ +WzpsMatS4mbNFElc89M+YryRFrQc9d1Uqjxhl3ms5MhDNcMP/PNwHa/wnIoqkpNI +qtDoR741wcZ7bdr6XVdF8+pBjzbBPPRSf24x3bqavHBWcTjcSVcM/ZEXxeqH5SN0 +GbK2mQxrogX4UWjtl+DfYvl+ejpEcYNXKEmIabUUHtpG42544cuPtZizLW5bt/aT +JBQfpPZpvf9MUlACxUONFOLQdZ8SXpSJ0e93iX2J2Z52mSQ= +-----END CERTIFICATE----- diff --git a/test/recipes/81-test_cmp_cli_data/Mock/test.cnf b/test/recipes/81-test_cmp_cli_data/Mock/test.cnf new file mode 100644 index 00000000..fed079fe --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/test.cnf @@ -0,0 +1,140 @@ +[default] +batch = 1 # do not use stdin +total_timeout = 8 # prevent, e.g., infinite polling due to error +trusted = trusted.crt +newkey = new.key +newkeypass = +cmd = ir +out_trusted = root.crt +certout = test.cert.pem +policies = certificatePolicies +#policy_oids = 1.2.3.4 +#policy_oids_critical = 1 +#verbosity = 7 + +############################# server configurations + +[Mock] # the built-in OpenSSL CMP mock server +no_check_time = 1 +server_host = 127.0.0.1 # localhost +server_port = 1700 +server_tls = 0 +server_cert = server.crt +server = $server_host:$server_port +server_path = pkix/ +path = $server_path +ca_dn = /O=openssl_cmp +recipient = $ca_dn +server_dn = /O=openssl_cmp +expect_sender = $server_dn +subject = "/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=leaf" +newkey = signer.key +out_trusted = signer_root.crt +kur_port = 1700 +pbm_port = 1700 +pbm_ref = +pbm_secret = pass:test +cert = signer.crt +key = signer.p12 +keypass = pass:12345 +ignore_keyusage = 0 +column = 0 +sleep = 0 + +############################# aspects + +[connection] +msg_timeout = 5 +total_timeout = +# reset any TLS options to default: +tls_used = +tls_cert = +tls_key = +tls_keypass = +tls_trusted = +tls_host = + +[tls] +server = +tls_used = +tls_cert = +tls_key = +tls_keypass = +tls_trusted = +tls_host = + +[credentials] +ref = +secret = +cert = +key = +keypass = +extracerts = +digest = +unprotected_requests = + +[verification] +#expect_sender = +srvcert = +trusted = +untrusted = +#unprotected_errors = +extracertsout = + +[commands] +cmd = +cacertsout = +infotype = +oldcert = +revreason = +geninfo = + +[enrollment] +cmd = +newkey = +newkeypass = +#subject = +issuer = +days = +reqexts = +sans = +san_nodefault = 0 +#popo = +implicit_confirm = 0 +disable_confirm = 0 +certout = +out_trusted = +oldcert = +csr = + +############################# extra cert template contents + +[certificatePolicies] +certificatePolicies = "critical, @pkiPolicy" + +[pkiPolicy] +policyIdentifier = 1.2.3.4 + +[reqexts] +basicConstraints = CA:FALSE +#basicConstraints = critical, CA:TRUE +keyUsage = critical, digitalSignature # keyAgreement, keyEncipherment, nonRepudiation +extendedKeyUsage = critical, clientAuth # serverAuth, codeSigning +#crlDistributionPoints = URI:http: +#authorityInfoAccess = URI:http: +subjectAltName = @alt_names + +[alt_names] +DNS.0 = localhost +IP.0 = 127.0.0.1 +IP.1 = 192.168.1.1 +URI.0 = http://192.168.0.2 + +[reqexts_invalidkey] +subjectAltName = @alt_names_3 + +[alt_names_3] +DNS.0 = localhost +DNS.1 = example.com +DNS.2 = example2.com +DNS__3 = example3.com diff --git a/test/recipes/81-test_cmp_cli_data/Mock/trusted.crt b/test/recipes/81-test_cmp_cli_data/Mock/trusted.crt new file mode 100644 index 00000000..31d9cc9c --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/Mock/trusted.crt @@ -0,0 +1,19 @@ + Subject: O = openssl_cmp + Issuer: O = openssl_cmp +-----BEGIN CERTIFICATE----- +MIICpTCCAY2gAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQKDAtvcGVu +c3NsX2NtcDAeFw0xNzEyMjAxMzA0MDBaFw0xODEyMjAxMzA0MDBaMBYxFDASBgNV +BAoMC29wZW5zc2xfY21wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZAJHnq0ypW/PZccrWj +o7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVVpLicMnItNFElfCoh +BzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuWq/vWW9r96/gBKKdd +mj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SOZf9bH1olBVsmBMsU +shFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6GvZ/i5KOhaqgJCnRKd +HHzijz9cLec5p9NSOuC1OwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQDGUXpFCBkV +WgPrBfZyBwt6VCjWB/e67q4IdcKMfDa4hwSquah1AyXHI0PlC/qitnoSx2+7f7pY +TEOay/3eEPUl1J5tdPF2Vg56Dw8jdhSkMwO7bXKDEE3R6o6jaa4ECgxwQtdGHmNU +A41PgKX76yEXku803ptO39/UR7i7Ye3MbyAmWE+PvixJYUbxd3fqz5fsaJqTCzAy +AT9hrr4uu8J7m3LYaYXo4LVL4jw5UsP5bIYtpmmEBfy9GhpUqH5/LzBNij7y3ziE +T59wHkzawAQDHsBPuCe07DFtlzqWWvaih0TQAw9MZ2tbyK9jt7P80Rqt9CwpM/i9 +jQYqSl/ix5hn +-----END CERTIFICATE----- diff --git a/test/recipes/81-test_cmp_cli_data/test_commands.csv b/test/recipes/81-test_cmp_cli_data/test_commands.csv new file mode 100644 index 00000000..70389be5 --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/test_commands.csv @@ -0,0 +1,54 @@ +expected,description, -section,val, -cmd,val,val2, -cacertsout,val,val2, -infotype,val,, -oldcert,val, -revreason,int, -geninfo,val +,,,,,Generic,message options:,,,,,,,,Misc,request options:,, +,,,,,,,,,,,,,,,,, +0,minimum options, -section,, -cmd,ir,,BLANK,,,BLANK,,,BLANK,,BLANK, +,,,,,,,,,,,,,,,,, +1,no cmd, -section,,BLANK,,,BLANK,,,BLANK,,,BLANK,,BLANK, +1,cmd missing arg, -section,, -cmd,,,BLANK,,,BLANK,,,BLANK,,BLANK, +1,cmd undefined , -section,, -cmd,abc,,BLANK,,,BLANK,,,BLANK,,BLANK, +1,cmd incomplete, -section,, -cmd,i,,BLANK,,,BLANK,,,BLANK,,BLANK, +,,,,,,,,,,,,,,,,, +0,no cacertsout, -section,, -cmd,ir,,BLANK,,,BLANK,,,BLANK,,BLANK, +0,cacertsout given, -section,, -cmd,ir,, -cacertsout,test.cacerts.pem,,BLANK,,,BLANK,,BLANK, +1,cacertsout missing arg, -section,, -cmd,ir,, -cacertsout,,,BLANK,,,BLANK,,BLANK, +,,,,,,,,,,,,,,,,, +0, --- get certificate for revocation ----, -section,, -cmd,cr,,BLANK,,,BLANK,,,BLANK,,BLANK, +0,revreason unspecified, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,0 +0, --- get certificate for revocation ----, -section,, -cmd,cr,,BLANK,,,BLANK,,,BLANK,,BLANK, +0,revreason keyCompromise, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,1 +0, --- get certificate for revocation ----, -section,, -cmd,cr,,BLANK,,,BLANK,,,BLANK,,BLANK, +0,revreason CACompromise, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,2 +0, --- get certificate for revocation ----, -section,, -cmd,cr,,BLANK,,,BLANK,,,BLANK,,BLANK, +0,revreason affiliationChanged, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,3 +0, --- get certificate for revocation ----, -section,, -cmd,cr,,BLANK,,,BLANK,,,BLANK,,BLANK, +0,revreason superseded, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,4 +0, --- get certificate for revocation ----, -section,, -cmd,cr,,BLANK,,,BLANK,,,BLANK,,BLANK, +0,revreason cessationOfOperation, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,5 +0, --- get certificate for revocation ----, -section,, -cmd,cr,,BLANK,,,BLANK,,,BLANK,,BLANK, +0,revreason certificateHold, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,6 +0,revreason removeFromCRL, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,8 +1,revreason 7 (invalid), -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,7 +0, --- get certificate for revocation ----, -section,, -cmd,cr,,BLANK,,,BLANK,,,BLANK,,BLANK, +0,revreason priviligeWithdrawn, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,9 +0, --- get certificate for revocation ----, -section,, -cmd,cr,,BLANK,,,BLANK,,,BLANK,,BLANK, +0,revreason AACompromise, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,10 +0, --- get certificate for revocation ----, -section,, -cmd,cr,,BLANK,,,BLANK,,,BLANK,,BLANK, +1,without oldcert, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,,BLANK, +1,oldcert is directory, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,dir/,BLANK, +1,oldcert file nonexistent, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,idontexist,BLANK, +1,empty oldcert file, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,empty.txt,BLANK, +1,oldcert and key do not match, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,trusted.crt, -revreason,0 +1,revreason 11 (invalid), -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,11 +1,revreason string, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,abc +1,revreason out of integer range, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,test.cert.pem, -revreason,010000000000000000000 +,,,,,,,,,,,,,,,,, +0,ir + infotype, -section,, -cmd,ir,,BLANK,,, -infotype,signKeyPairTypes,,BLANK,,BLANK, +1,genm with missing infotype value, -section,, -cmd,genm,,BLANK,,, -infotype,,,BLANK,,BLANK, +1,genm with invalid infotype value, -section,, -cmd,genm,,BLANK,,, -infotype,asdf,,BLANK,,BLANK, +,,,,,,,,,,,,,,,,,,,,,, +0,geninfo, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -geninfo,1.2.3:int:987,BLANK,,BLANK, +1,geninfo missing argument, -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -geninfo,,,,, +1,geninfo bad syntax: leading '.', -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -geninfo,.1.2.3:int:987,BLANK,,BLANK, +1,geninfo bad syntax: missing ':', -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -geninfo,1.2.3:int987,,,, +1,geninfo bad syntax: double ':', -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -geninfo,1.2.3:int::987,,,, +1,geninfo bad syntax: missing ':int', -section,, -cmd,cr,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,, -geninfo,1.2.3,,,, diff --git a/test/recipes/81-test_cmp_cli_data/test_connection.csv b/test/recipes/81-test_cmp_cli_data/test_connection.csv new file mode 100644 index 00000000..eceac6eb --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/test_connection.csv @@ -0,0 +1,43 @@ +expected,description, -section,val, -server,val, -proxy,val, -path,val, -msg_timeout,int, -total_timeout,int, -tls_used,noarg, -no_proxy,val +,Message transfer options:,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,, +0,default config, -section,,,,,,,,BLANK,,BLANK,,BLANK,,BLANK, +TBD,Domain name, -section,, -server,_SERVER_CN:_SERVER_PORT,,,, +TBD,IP address, -section,, -server,_SERVER_IP:_SERVER_PORT,,,, +,,,,,,,,,,,,,,,,,,,,,,,,, +1,wrong server, -section,, -server,example.com:_SERVER_PORT,,,,, -msg_timeout,1,BLANK,,BLANK,,BLANK, +1,wrong server port, -section,, -server,_SERVER_HOST:99,,,,, -msg_timeout,1,BLANK,,BLANK,,BLANK, +1,server default port, -section,, -server,_SERVER_HOST,,,,, -msg_timeout,1,BLANK,,BLANK,,BLANK, +1,server port out of range, -section,, -server,_SERVER_HOST:65536,,,,,BLANK,,BLANK,,BLANK,,BLANK, +1,server port negative, -section,, -server,_SERVER_HOST:-10,,,,,BLANK,,BLANK,,BLANK,,BLANK, +1,server missing argument, -section,, -server,,,,,,BLANK,,BLANK,,BLANK,,BLANK, +1,server with default port, -section,, -server,_SERVER_HOST,,,,,BLANK,,BLANK,,BLANK,,BLANK, +1,server IP address bad syntax: double '.', -section,, -server,127.0.0..1:_SERVER_PORT,,,,,BLANK,,BLANK,,BLANK,,BLANK, +1,server domain bad syntax: double '.', -section,, -server,_SERVER_HOST..com:_SERVER_PORT,,,,,BLANK,,BLANK,,BLANK,,BLANK, +1,server port bad syntax: missing ':', -section,, -server,_SERVER_HOST.80,,,,,BLANK,,BLANK,,BLANK,,BLANK, +1,server port bad synatx: trailing garbage, -section,, -server,_SERVER_HOST:_SERVER_PORT+/x.,,,,,BLANK,,BLANK,,BLANK,,BLANK, +1,server with TLS port, -section,, -server,_SERVER_HOST:_SERVER_TLS,,,,,BLANK,,BLANK,,BLANK,,BLANK, +TBD,server IP address with TLS port, -section,, -server,_SERVER_IP:_SERVER_TLS,,,,,BLANK,,BLANK,,BLANK,,BLANK, +,,,,,,,,,,,,,,,,,,,,,,,,, +1,proxy bad ipv4 address syntax: extra cell, -section,, -server,_SERVER_HOST:_SERVER_PORT, -proxy,127.0.0.0.0:8888,,,BLANK,,BLANK,,BLANK,,BLANK, -no_proxy,nonmatch.com +1,proxy port out of range, -section,, -server,_SERVER_HOST:_SERVER_PORT, -proxy,127.0.0.1:65536,,,BLANK,,BLANK,,BLANK,,BLANK, -no_proxy,nonmatch.com +1,proxy IP address bad syntax: double '.', -section,, -server,_SERVER_HOST:_SERVER_PORT, -proxy,127.0.0..1:8888,,,BLANK,,BLANK,,BLANK,,BLANK, -no_proxy,nonmatch.com +1,proxy default port, -section,, -server,_SERVER_HOST:_SERVER_PORT, -proxy,127.0.0.1,,,BLANK,,BLANK,,BLANK,,BLANK, -no_proxy,nonmatch.com +1,proxy missing argument, -section,, -server,_SERVER_HOST:_SERVER_PORT, -proxy,,,,BLANK,,BLANK,,BLANK,,BLANK, -no_proxy,nonmatch.com +,,,,,,,,,,,,,,,,,,,,,,,,, +1,path missing argument, -section,,,,,, -path,,BLANK,,BLANK,,BLANK,,BLANK, +1,path wrong, -section,,,,,, -path,/publicweb/cmp/example,BLANK,,BLANK,,BLANK,,BLANK, +0,path with additional '/'s fine according to RFC 3986, -section,,,,,, -path,/_SERVER_PATH////,BLANK,,BLANK,,BLANK,,BLANK +1,path mixed case, -section,,,,,, -path,pKiX/,BLANK,,BLANK,,BLANK,,BLANK, +1,path upper case, -section,,,,,, -path,PKIX/,BLANK,,BLANK,,BLANK,,BLANK, +,,,,,,,,,,,,,,,,,,,,,,,,, +1,msg_timeout missing argument, -section,,,,,,,, -msg_timeout,,BLANK,,BLANK,,BLANK, +1,msg_timeout negative, -section,,,,,,,, -msg_timeout,-5,BLANK,,BLANK,,BLANK, +0,msg_timeout 5, -section,,,,,,,, -msg_timeout,5,BLANK,,BLANK,,BLANK, +0,msg_timeout 0, -section,,,,,,,, -msg_timeout,0,BLANK,,BLANK,,BLANK, +,,,,,,,,,,,,,,,,,,,,,,,,, +1,total_timeout missing argument, -section,,,,,,,,BLANK,, -total_timeout,,BLANK,,BLANK, +1,total_timeout negative, -section,,,,,,,,BLANK,, -total_timeout,-5,BLANK,,BLANK, +0,total_timeout 10, -section,,,,,,,,BLANK,, -total_timeout,10,BLANK,,BLANK, +0,total_timeout 0, -section,,,,,,,,BLANK,, -total_timeout,0,BLANK,,BLANK, +,,,,,,,,,,,,,,,,,,,,,,,,, diff --git a/test/recipes/81-test_cmp_cli_data/test_credentials.csv b/test/recipes/81-test_cmp_cli_data/test_credentials.csv new file mode 100644 index 00000000..b54862ba --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/test_credentials.csv @@ -0,0 +1,46 @@ +expected,description, -section,val, -ref,val, -secret,val, -cert,val, -key,val, -keypass,val, -extracerts,val, BLANK, BLANK, -digest,val, -unprotected_requests,noarg +,,,,,,,,,,,,,,,,,,,,,, +0,valid secret - wrong cert/key ignored, -section,, -ref,_PBM_REF, -secret,_PBM_SECRET, -cert,root.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK,-server,_SERVER_HOST:_PBM_PORT,-expect_sender,"""" +1,secret missing arg, -section,,BLANK,, -secret,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK, +1,wrong secret without ref, -section,,BLANK,, -secret,pass:wrong,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK, +1,wrong secret - correct cert, -section,,BLANK,, -secret,pass:wrong, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK,-server,_SERVER_HOST:_PBM_PORT,-expect_sender,"""" +,,,,,,,,,,,,,,,,,,,,,, +1,ref missing arg, -section,, -ref,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK, +0,empty ref but correct cert, -section,, -ref,"""",BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +0,wrong ref but correct cert, -section,, -ref,wrong,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +,,,,,,,,,,,,,,,,,,,,,, +0,valid cert and key and keypass, -section,,BLANK,,-secret,"""", -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +1,cert missing arg, -section,,BLANK,,BLANK,, -cert,, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +1,key missing arg, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +1,keypass missing arg, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,,BLANK,,BLANK,,BLANK,,BLANK, +1,keypass empty string, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:,BLANK,,BLANK,,BLANK,,BLANK, +0,keypass no prefix, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,12345,BLANK,,BLANK,,BLANK,,BLANK, +1,keypass prefix wrong, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,:12345,BLANK,,BLANK,,BLANK,,BLANK, +1,wrong keypass, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:123456,BLANK,,BLANK,,BLANK,,BLANK, +,,,,,,,,,,,,,,,,,,,,,, +1,no cert, -section,,BLANK,,BLANK,,BLANK,, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +1,no key, -section,,BLANK,,BLANK,, -cert,signer.crt,BLANK,, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +1,no keypass, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12,BLANK,,BLANK,,BLANK,,BLANK,,BLANK, +1,wrong cert, -section,,BLANK,,BLANK,, -cert,trusted.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +1,cert file does not exist, -section,,BLANK,,BLANK,, -cert,idontexist, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +1,cert file random content, -section,,BLANK,,BLANK,, -cert,random.bin, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +1,empty cert file, -section,,BLANK,,BLANK,, -cert,empty.txt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +1,key file random content, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,random.bin, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +1,random keypass file, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,file:random.bin,BLANK,,BLANK,,BLANK,,BLANK, +,,,,,,,,,,,,,,,,,,,,,, +0,correct extraCerts, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345, -extracerts,issuing.crt,BLANK,,BLANK,,BLANK, +0,extracerts big file, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345, -extracerts,big_issuing.crt,BLANK,,BLANK,,BLANK, +1,extracerts missing arg, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345, -extracerts,,BLANK,,BLANK,,BLANK, +1,extracerts empty file, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345, -extracerts,empty.txt,BLANK,,BLANK,,BLANK, +1,extracerts random content, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345, -extracerts,random.bin,BLANK,,BLANK,,BLANK, +1,extracerts file does not exist, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345, -extracerts,idontexist,BLANK,,BLANK,,BLANK, +,,,,,,,,,,,,,,,,,,,,,, +0,default sha256, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,,BLANK,,BLANK, +0,digest sha256, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,, -digest,sha256,BLANK, +0,digest sha512, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,, -digest,sha512,BLANK, +1,digest missing arg, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,, -digest,,BLANK, +1,digest non-existing, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,, -digest,sha7,BLANK, +1,digest obsolete, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,, -digest,md2,BLANK, +1,multiple digests, -section,,BLANK,,BLANK,, -cert,signer.crt, -key,signer.p12, -keypass,pass:12345,BLANK,,BLANK,, -digest,sha256 sha512,BLANK, +,,,,,,,,,,,,,,,,,,,,,, +1,unprotected request, -section,,BLANK,,BLANK,, -cert,"""", -key,"""", -keypass,"""",BLANK,,BLANK,,BLANK,, -unprotected_requests, diff --git a/test/recipes/81-test_cmp_cli_data/test_enrollment.csv b/test/recipes/81-test_cmp_cli_data/test_enrollment.csv new file mode 100644 index 00000000..64fb3fdc --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/test_enrollment.csv @@ -0,0 +1,112 @@ +expected,description, -section,val, -cmd,val, -newkey,val,val, -newkeypass,val, -subject,val, -issuer,val, -days,int, -reqexts,val, -sans,spec, -san_nodefault,noarg, -popo,int, -implicit_confirm,noarg, -disable_confirm,noarg, -certout,val,val2, -out_trusted,val,val2, -oldcert,val, -csr,val, -revreason,val +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,Misc,request options:,,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,newkey, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,newkey missing arg, -section,, -cmd,ir, -newkey,,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,newkey is directory, -section,, -cmd,ir, -newkey,dir/,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,newkey too many parameters, -section,, -cmd,ir, -newkey,abc,def, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,newkey is an RSA key, -section,, -cmd,ir, -newkey,test.RSA2048.pem,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,newkeypass, -section,, -cmd,ir, -newkey,new_pass_12345.key,, -newkeypass,pass:12345,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,no newkeypass, -section,, -cmd,ir, -newkey,new_pass_12345.key,,BLANK,,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,read newkeypass from file, -section,, -cmd,ir, -newkey,new_pass_12345.key,, -newkeypass,file:12345.txt,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,missing newkeypass parameter, -section,, -cmd,ir, -newkey,new_pass_12345.key,, -newkeypass,,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,colon missing and no passwd, -section,, -cmd,ir, -newkey,new_pass_12345.key,, -newkeypass,pass,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,newkeypass double colon, -section,, -cmd,ir, -newkey,new_pass_12345.key,, -newkeypass,pass::12345,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,newkeypass double passwd, -section,, -cmd,ir, -newkey,new_pass_12345.key,, -newkeypass,pass:12345:12345,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,newkeypass wrongfile, -section,, -cmd,ir, -newkey,new_pass_12345.key,, -newkeypass,file:random.bin,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,wrong password for encrypted pem, -section,, -cmd,ir, -newkey,cmp --help ,, -newkeypass,pass:wrong,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,newkeypass ignored, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,abcdefghijklmnop,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,newkeypass invalid, -section,, -cmd,ir, -newkey,new_pass_12345.key,, -newkeypass,fp:4,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,newkeypass no prefix, -section,, -cmd,ir, -newkey,new_pass_12345.key,, -newkeypass,12345,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +1,subject argument missing, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:, -subject,BLANK,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,issuer, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,, -issuer,_CA_DN,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,issuer missing arg, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,, -issuer,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,days 1, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,, -days,1,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,days 0, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,, -days,0,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,days 36500, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,, -days,36500,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,days missing arg, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,, -days,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,days negative, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,, -days,-10,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,days no not integer, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,, -days,1.5,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,days out of range, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,, -days,0x10000000000000000,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,reqexts, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,,, -reqexts,reqexts,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,reqexts missing arg, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,, -reqexts,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,reqexts non-exisitng section, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,, -reqexts,invalid,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,reqexts malformed section, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,, -reqexts,reqexts_invalidkey,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,reqexts and sans, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,,, -reqexts,reqexts, -sans,localhost,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,sans 1 dns, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,,,BLANK,, -sans,localhost,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,sans 1 dns critical, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,,,BLANK,, -sans,localhost critical,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,sans critical, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,,,BLANK,, -sans,critical,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,sans 2 dns, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,,,BLANK,, -sans,localhost test,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,sans 1 dns 1 ip, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,,,BLANK,, -sans,localhost 127.0.0.1,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,sans 2 ip, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,,,BLANK,, -sans,127.0.0.1 1.2.3.4,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,sans 1 uri, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,,,BLANK,, -sans,https://www.sample.com,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,san_nodefault, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,,,BLANK,, -sans,127.0.0.1 1.2.3.4, -san_nodefault,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +0,san default test.cert.pem, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,,,BLANK,, -sans,127.0.0.1 1.2.3.4,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,test.cert.pem,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,popo SIGNATURE, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -popo,1,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,popo RAVERIFIED, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -popo,0,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,popo missing arg, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -popo,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,popo too large, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -popo,3,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,popo too small, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -popo,-3,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,popo NONE, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -popo,-1,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,popo KEYENC not supported, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -popo,2,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,implicit confirm, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -implicit_confirm,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,implicit confirm with parameter, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -implicit_confirm,abc,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,disable_confirm, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -disable_confirm,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,disable_confirm with parameter, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -disable_confirm,abc, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +1,no certout, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,certout missing arg, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,certout is directory, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,dir/,, -out_trusted,root.crt,,BLANK,,BLANK,,, +1,certout too many parameters, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,abc,def, -out_trusted,root.crt,,BLANK,,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,no out_trusted, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,,BLANK,,,BLANK,,BLANK,,, +0,out_trusted bigcert, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,big_root.crt,,BLANK,,BLANK,,, +1,out_trusted missing arg, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,,,BLANK,,BLANK,,, +1,out_trusted is directory, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,dir/,,BLANK,,BLANK,,, +1,out_trusted too many parameters, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,abc,def,BLANK,,BLANK,,, +1,out_trusted empty certificate file, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,empty.txt,,BLANK,,BLANK,,, +1,out_trusted expired ca certificate, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root_expired.crt,,BLANK,,BLANK,,, +1,out_trusted wrong ca, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,signer.crt,,BLANK,,BLANK,,, +1,out_trusted random input, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,random.bin,,BLANK,,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,oldcert ignored, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,test.cert.pem,BLANK,,, +1,oldcert missing arg, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,,BLANK,,, +1,oldcert directory, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,dir/,BLANK,,, +1,oldcert non existing file, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,idontexist,BLANK,,, +1,oldcert empty file, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,empty.txt,BLANK,,, +0,oldcert wrong cert, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,trusted.crt,BLANK,,, +1,oldcert random contents, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,random.bin,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,csr ignored for ir, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,, -csr,test.csr.pem,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +1,p10cr csr missing arg, -section,, -cmd,p10cr, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,, -csr,,, +1,p10cr csr directory, -section,, -cmd,p10cr, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,, -csr,,, +1,p10cr csr non-existing file, -section,, -cmd,p10cr, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,, -csr,idontexist,, +1,p10cr csr empty file, -section,, -cmd,p10cr, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,, -csr,empty.txt,, +1,p10cr wrong csr, -section,, -cmd,p10cr, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,, -csr,wrong.csr.pem,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,ir + ignored revocation, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,,, -revreason,5 +1,ir + invalid revreason, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,,, -revreason,11 +1,ir + revreason not an integer, -section,, -cmd,ir, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,,, -revreason,abc +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,cr command, -section,, -cmd,cr, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,,BLANK,,BLANK,,, +,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +0,kur command explicit options, -section,, -cmd,kur, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,test.cert.pem,BLANK,,,,,-server,_SERVER_HOST:_KUR_PORT, -cert,test.cert.pem, -key,new.key, -extracerts,issuing.crt +0,kur command minimal options, -section,, -cmd,kur,BLANK,,BLANK,, -subject,"""",BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,,BLANK,,, -oldcert,test.cert.pem,BLANK,,,,,-server,_SERVER_HOST:_KUR_PORT, -cert,test.cert.pem, -key,new.key, -extracerts,issuing.crt, -secret,"""" +1,kur newkey value missing, -section,, -cmd,kur, -newkey,,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,test.cert.pem,BLANK,,,,,-server,_SERVER_HOST:_KUR_PORT +1,kur newkey is directory, -section,, -cmd,kur, -newkey,dir/,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,test.cert.pem,BLANK,,,,,-server,_SERVER_HOST:_KUR_PORT +1,kur newkey parameter count no match, -section,, -cmd,kur, -newkey,abc,def, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,test.cert.pem,BLANK,,,,,-server,_SERVER_HOST:_KUR_PORT +1,kur newkey missing argument, -section,, -cmd,kur, -newkey,BLANK,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,test.cert.pem,BLANK,,,,,-server,_SERVER_HOST:_KUR_PORT +1,kur oldcert is directory, -section,, -cmd,kur, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,dir/,BLANK,,,,,-server,_SERVER_HOST:_KUR_PORT +1,kur oldcert not existing, -section,, -cmd,kur, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,idontexist,BLANK,,,,,-server,_SERVER_HOST:_KUR_PORT +1,kur empty oldcert file, -section,, -cmd,kur, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -oldcert,empty.txt,BLANK,,,,,-server,_SERVER_HOST:_KUR_PORT +1,kur command without cert and oldcert, -section,, -cmd,kur, -newkey,new.key,, -newkeypass,pass:,,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,,BLANK,, -certout,test.cert.pem,, -out_trusted,root.crt,, -cert,"""",BLANK,,,,,-server,_SERVER_HOST:_KUR_PORT diff --git a/test/recipes/81-test_cmp_cli_data/test_verification.csv b/test/recipes/81-test_cmp_cli_data/test_verification.csv new file mode 100644 index 00000000..b53e518c --- /dev/null +++ b/test/recipes/81-test_cmp_cli_data/test_verification.csv @@ -0,0 +1,51 @@ +expected,description, -section,val, -recipient,val, -expect_sender,val, -srvcert,val, -trusted,val, -untrusted,val, -ignore_keyusage, -unprotected_errors, -extracertsout,val,val2, -opt1,arg1, -opt2,arg2, -opt3,arg3 +,,,,,Recipient,options:,,,,,,,,,,,,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,, +0,default test, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,, +1,recipient missing arg, -section,, -recipient,,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +0,unknown attribute in recipient name, -section,, -recipient,_CA_DN/ABC=123,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,wrong syntax in recipient name: trailing double '/' after value, -section,, -recipient,_CA_DN//,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,wrong syntax in recipient name: missing '=', -section,, -recipient,/CDE,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,wrong syntax in recipient name: C too long, -section,, -recipient,/CN=ECC Issuing CA v10/OU=For test purpose only/O=CMPforOpenSSL/C=DEE,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,, +0,config default with expected sender, -section,, -recipient,_CA_DN, -expect_sender,_SERVER_DN,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,expected sender missing arg, -section,, -recipient,_CA_DN, -expect_sender,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,wrong expected sender, -section,, -recipient,_CA_DN, -expect_sender,/CN=Sample Cert/OU=R&D/O=Company Ltd./L=Dublin 4/C=IE,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +0,unknown attribute in expected sender, -section,, -recipient,_CA_DN, -expect_sender,_SERVER_DN/ABC=123,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,extra attribute in expected sender, -section,, -recipient,_CA_DN, -expect_sender,_SERVER_DN/serialNumber=123,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,double attribute in expected sender, -section,, -recipient,_CA_DN, -expect_sender,/CN=ECC Issuing CA v10_SERVER_DN,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,missing attribute in expected sender, -section,, -recipient,_CA_DN, -expect_sender,/CN=ECC Issuing CA v10/OU=For test purpose only/C=DE,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,bad syntax in expected sender name: leading double '/', -section,, -recipient,_CA_DN, -expect_sender,//_CA_DN,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,bad syntax in expected sender name: trailing double '/', -section,, -recipient,_CA_DN, -expect_sender,_CA_DN//,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,bad syntax in expected sender name: missing '=', -section,, -recipient,_CA_DN, -expect_sender,/C=DE/CN=ECC Issuing CA v10/OU=For test purpose only/OCMPforOpenSSL,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,expected sender empty attributes, -section,, -recipient,_CA_DN, -expect_sender,/CN=/OU=/O=/C=,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,, +0,explicit srvcert, -section,,,,BLANK,, -srvcert,_SERVER_CERT, -trusted,"""",BLANK,,,, -unprotected_errors,BLANK,,,,,,,, +1,srvcert missing arg, -section,, -recipient,"""",BLANK,, -srvcert,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,wrong srvcert, -section,, -recipient,"""",BLANK,, -srvcert,signer.crt, -trusted,"""",BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,srvcert is empty file, -section,, -recipient,"""",BLANK,, -srvcert,empty.txt, -trusted,"""",BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,srvcert random content, -section,, -recipient,"""",BLANK,, -srvcert,random.bin, -trusted,"""",BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,, +0,no -trusted but srvcert, -section,, -recipient,_CA_DN,BLANK,, -srvcert,_SERVER_CERT,BLANK,,BLANK,,, -unprotected_errors,BLANK,,,,,,,, +1,trusted missing arg, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,wrong trusted cert, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,signer.crt,BLANK,,BLANK, -unprotected_errors,BLANK, -secret,"""", -cert,signer.crt, -key,signer.p12, -keypass,pass:12345 +1,trusted empty file, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,empty.txt,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,trusted random file, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,random.bin,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,trusted file does not exist, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,idontexist,BLANK,,BLANK, -unprotected_errors,BLANK,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,, +1,untrusted missing arg, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt, -untrusted,,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,untrusted empty file, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt, -untrusted,empty.txt,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,untrusted random file, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt, -untrusted,random.bin,BLANK, -unprotected_errors,BLANK,,,,,,,, +1,untrusted file does not exist, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt, -untrusted,idontexist,BLANK, -unprotected_errors,BLANK,,,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,, +0,ignore key usage, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,, -ignore_keyusage, -unprotected_errors,BLANK,,,,,,,, +1,ignorekeyusage with parameter, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,, -unprotected_errors,BLANK, -ignore_keyusage,1,,,,,, +,,,,,,,,,,,,,,,,,,,,,,,,, +0,no unprotected errors - no errors, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK,BLANK,BLANK,,,,,,,, +1,unprotected_errors with parameter, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK,BLANK,BLANK,,, -unprotected_errors,123,,,, +,,,,,,,,,,,,,,,,,,,,,,,,, +0,extracertsout, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors, -extracertsout,test.extracerts.pem,,,,,,, +1,extracertsout no parameter, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors, -extracertsout,,,,,,,, +1,extracertsout directory, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors, -extracertsout,directory/,,,,,,, +1,extracertsout multiple arguments, -section,, -recipient,_CA_DN,BLANK,,BLANK,, -trusted,trusted.crt,BLANK,,BLANK, -unprotected_errors, -extracertsout,abc,def,,,,,, diff --git a/test/recipes/90-test_sslprovider.t b/test/recipes/90-test_sslprovider.t deleted file mode 100644 index 1a2a2855..00000000 --- a/test/recipes/90-test_sslprovider.t +++ /dev/null @@ -1,50 +0,0 @@ -#! /usr/bin/env perl -# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. -# -# Licensed under the Apache License 2.0 (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html - - -use OpenSSL::Test::Utils; -use OpenSSL::Test qw/:DEFAULT srctop_file srctop_dir bldtop_file bldtop_dir/; - -BEGIN { -setup("test_sslprovider"); -} - -use lib srctop_dir('Configurations'); -use lib bldtop_dir('.'); -use platform; - -plan skip_all => "No TLS/SSL protocols are supported by this OpenSSL build" - if alldisabled(grep { $_ ne "ssl3" } available_protocols("tls")); - -plan tests => 3; - -SKIP: { - skip "Skipping FIPS installation", 1 - if disabled("fips"); - - ok(run(app(['openssl', 'fipsinstall', - '-out', bldtop_file('providers', 'fipsmodule.cnf'), - '-module', bldtop_file('providers', platform->dso('fips')), - '-provider_name', 'fips', '-mac_name', 'HMAC', - '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00', - '-section_name', 'fips_sect'])), - "fipsinstall"); -} - -ok(run(test(["sslprovidertest", srctop_dir("test", "certs"), "default", - srctop_file("test", "default.cnf")])), - "running sslprovidertest"); - -SKIP: { - skip "Skipping FIPS provider test", 1 - if disabled("fips"); - - ok(run(test(["sslprovidertest", srctop_dir("test", "certs"), "fips", - srctop_file("test", "fips.cnf")])), - "running sslprovidertest"); -} diff --git a/test/recipes/90-test_store.t b/test/recipes/90-test_store.t index 3e2e69f4..9f4eaa29 100644 --- a/test/recipes/90-test_store.t +++ b/test/recipes/90-test_store.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -17,6 +17,11 @@ setup($test_name); my $mingw = config('target') =~ m|^mingw|; +my $use_md5 = !disabled("md5"); +my $use_des = !disabled("des"); # also affects 3des and pkcs12 app +my $use_dsa = !disabled("dsa"); +my $use_ecc = !disabled("ec"); + my @noexist_files = ( "test/blahdiblah.pem", "test/blahdibleh.der" ); @@ -40,25 +45,35 @@ my @generated_files = "rsa-key-pkcs1.pem", "rsa-key-pkcs1.der", "rsa-key-pkcs1-aes128.pem", "rsa-key-pkcs8.pem", "rsa-key-pkcs8.der", - "rsa-key-pkcs8-pbes1-sha1-3des.pem", "rsa-key-pkcs8-pbes1-sha1-3des.der", "rsa-key-pkcs8-pbes2-sha1.pem", "rsa-key-pkcs8-pbes2-sha1.der", + "rsa-key-pkcs8-pbes2-sha256.pem", "rsa-key-pkcs8-pbes2-sha256.der", + ); +push(@generated_files, ( + "rsa-key-pkcs8-pbes1-sha1-3des.pem", "rsa-key-pkcs8-pbes1-sha1-3des.der", + )) if $use_des; +push(@generated_files, ( "rsa-key-sha1-3des-sha1.p12", "rsa-key-sha1-3des-sha256.p12", "rsa-key-aes256-cbc-sha256.p12", "rsa-key-md5-des-sha1.p12", - "rsa-key-aes256-cbc-md5-des-sha256.p12", - "rsa-key-pkcs8-pbes2-sha256.pem", "rsa-key-pkcs8-pbes2-sha256.der", - "rsa-key-pkcs8-pbes1-md5-des.pem", "rsa-key-pkcs8-pbes1-md5-des.der", + "rsa-key-aes256-cbc-md5-des-sha256.p12" + )) if $use_des; +push(@generated_files, ( + "rsa-key-pkcs8-pbes1-md5-des.pem", "rsa-key-pkcs8-pbes1-md5-des.der" + )) if $use_md5 && $use_des; +push(@generated_files, ( "dsa-key-pkcs1.pem", "dsa-key-pkcs1.der", "dsa-key-pkcs1-aes128.pem", "dsa-key-pkcs8.pem", "dsa-key-pkcs8.der", "dsa-key-pkcs8-pbes2-sha1.pem", "dsa-key-pkcs8-pbes2-sha1.der", - "dsa-key-aes256-cbc-sha256.p12", + )) if $use_dsa; +push(@generated_files, "dsa-key-aes256-cbc-sha256.p12") if $use_dsa && $use_des; +push(@generated_files, ( "ec-key-pkcs1.pem", "ec-key-pkcs1.der", "ec-key-pkcs1-aes128.pem", "ec-key-pkcs8.pem", "ec-key-pkcs8.der", "ec-key-pkcs8-pbes2-sha1.pem", "ec-key-pkcs8-pbes2-sha1.der", - "ec-key-aes256-cbc-sha256.p12", - ); + )) if $use_ecc; +push(@generated_files, "ec-key-aes256-cbc-sha256.p12") if $use_ecc && $use_des; my %generated_file_files = $^O eq 'linux' ? ( "test/testx509.pem" => "file:testx509.pem", @@ -84,7 +99,7 @@ plan tests => $n; indir "store_$$" => sub { SKIP: { - skip "failed initialisation", $n unless init(); + init() or die "init failed"; my $rehash = init_rehash(); @@ -219,28 +234,35 @@ indir "store_$$" => sub { }, create => 1, cleanup => 1; sub init { + my $cnf = srctop_file('test', 'ca-and-certs.cnf'); + my $cakey = srctop_file('test', 'certs', 'ca-key.pem'); return ( # rsa-key-pkcs1.pem - run(app(["openssl", "genrsa", - "-out", "rsa-key-pkcs1.pem", "2432"])) - # dsa-key-pkcs1.pem - && run(app(["openssl", "dsaparam", "-genkey", - "-out", "dsa-key-pkcs1.pem", "1024"])) - # ec-key-pkcs1.pem (one might think that 'genec' would be practical) - && run(app(["openssl", "ecparam", "-genkey", "-name", "prime256v1", - "-out", "ec-key-pkcs1.pem"])) + run(app(["openssl", "pkey", + "-in", data_file("rsa-key-2432.pem"), + "-out", "rsa-key-pkcs1.pem"])) # rsa-key-pkcs1-aes128.pem && run(app(["openssl", "rsa", "-passout", "pass:password", "-aes128", "-in", "rsa-key-pkcs1.pem", "-out", "rsa-key-pkcs1-aes128.pem"])) + # dsa-key-pkcs1.pem + && (!$use_dsa || run(app(["openssl", "gendsa", + "-out", "dsa-key-pkcs1.pem", + data_file("dsaparam.pem")]))) # dsa-key-pkcs1-aes128.pem - && run(app(["openssl", "dsa", "-passout", "pass:password", "-aes128", - "-in", "dsa-key-pkcs1.pem", - "-out", "dsa-key-pkcs1-aes128.pem"])) + && (!$use_dsa || run(app(["openssl", "dsa", + "-passout", "pass:password", "-aes128", + "-in", "dsa-key-pkcs1.pem", + "-out", "dsa-key-pkcs1-aes128.pem"]))) + # ec-key-pkcs1.pem (one might think that 'genec' would be practical) + && (!$use_ecc || run(app(["openssl", "ecparam", "-genkey", + "-name", "prime256v1", + "-out", "ec-key-pkcs1.pem"]))) # ec-key-pkcs1-aes128.pem - && run(app(["openssl", "ec", "-passout", "pass:password", "-aes128", - "-in", "ec-key-pkcs1.pem", - "-out", "ec-key-pkcs1-aes128.pem"])) + && (!$use_ecc || run(app(["openssl", "ec", + "-passout", "pass:password", "-aes128", + "-in", "ec-key-pkcs1.pem", + "-out", "ec-key-pkcs1-aes128.pem"]))) # *-key-pkcs8.pem && runall(sub { my $dstfile = shift; @@ -295,20 +317,20 @@ sub init { }, grep(/-key-pkcs8-pbes2-sha256\.pem$/, @generated_files)) # *-cert.pem (intermediary for the .p12 inits) && run(app(["openssl", "req", "-x509", - "-config", data_file("ca.cnf"), "-nodes", - "-out", "cacert.pem", "-keyout", "cakey.pem"])) + "-config", $cnf, "-nodes", + "-key", $cakey, "-out", "cacert.pem"])) && runall(sub { my $srckey = shift; (my $dstfile = $srckey) =~ s|-key-pkcs8\.|-cert.|; (my $csr = $dstfile) =~ s|\.pem|.csr|; (run(app(["openssl", "req", "-new", - "-config", data_file("user.cnf"), + "-config", $cnf, "-section", "userreq", "-key", $srckey, "-out", $csr])) && run(app(["openssl", "x509", "-days", "3650", "-CA", "cacert.pem", - "-CAkey", "cakey.pem", + "-CAkey", $cakey, "-set_serial", time(), "-req", "-in", $csr, "-out", $dstfile]))); }, grep(/-key-pkcs8\.pem$/, @generated_files)) @@ -349,17 +371,21 @@ sub init { my $macalg = $macalgs{$macalg_index}; if (!defined($certpbe) || !defined($keypbe) || !defined($macalg)) { - print STDERR "Cert PBE for $pbe_index not defined\n" + print STDERR "Cert PBE for $certpbe_index not defined\n" unless defined $certpbe; - print STDERR "Key PBE for $pbe_index not defined\n" + print STDERR "Key PBE for $keypbe_index not defined\n" unless defined $keypbe; print STDERR "MACALG for $macalg_index not defined\n" unless defined $macalg; print STDERR "(destination file was $dstfile)\n"; return 0; } - run(app(["openssl", "pkcs12", "-inkey", $srckey, + run(app(["openssl", "pkcs12", + "-provider", "default", + "-provider", "legacy", + "-inkey", $srckey, "-in", $srccert, "-passout", "pass:password", + "-chain", "-CAfile", "cacert.pem", "-export", "-macalg", $macalg, "-certpbe", $certpbe, "-keypbe", $keypbe, "-out", $dstfile])); diff --git a/test/recipes/90-test_store_data/ca.cnf b/test/recipes/90-test_store_data/ca.cnf deleted file mode 100644 index bda6eec4..00000000 --- a/test/recipes/90-test_store_data/ca.cnf +++ /dev/null @@ -1,56 +0,0 @@ -#################################################################### -[ req ] -default_bits = 2432 -default_keyfile = cakey.pem -default_md = sha256 -distinguished_name = req_DN -string_mask = utf8only -x509_extensions = v3_selfsign - -[ req_DN ] -commonName = "Common Name" -commonName_value = "CA" - -[ v3_selfsign ] -basicConstraints = critical,CA:true -keyUsage = keyCertSign -subjectKeyIdentifier=hash - -#################################################################### -[ ca ] -default_ca = CA_default # The default ca section - -#################################################################### -[ CA_default ] - -dir = ./demoCA -certificate = ./demoCA/cacert.pem -serial = ./demoCA/serial -private_key = ./demoCA/private/cakey.pem -new_certs_dir = ./demoCA/newcerts - -certificate = cacert.pem -private_key = cakey.pem - -x509_extensions = v3_user - -name_opt = ca_default # Subject Name options -cert_opt = ca_default # Certificate field options - -policy = policy_anything - -[ policy_anything ] -countryName = optional -stateOrProvinceName = optional -localityName = optional -organizationName = optional -organizationalUnitName = optional -commonName = supplied -emailAddress = optional - -[ v3_user ] -basicConstraints=critical,CA:FALSE -subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer -issuerAltName=issuer:copy - diff --git a/test/recipes/90-test_store_data/dsaparam.pem b/test/recipes/90-test_store_data/dsaparam.pem new file mode 100644 index 00000000..60563cbb --- /dev/null +++ b/test/recipes/90-test_store_data/dsaparam.pem @@ -0,0 +1,14 @@ +-----BEGIN DSA PARAMETERS----- +MIICLAKCAQEArjV9Th2W4p8AlmBabk0HjaV8vPmt15/V6e6mM1Hee3LSdapxd/Fj ++7bsWroNcqIaHGS45YkJbclvC3/Szp/vh1q2Zy/v7utZ9V7/qCiEnls3CRGAfAhc +1eFIS9Jo+z+fK2tsDUgbGoDC6xEbN3nWjItyPmelBQ5Bip41ULTSQCdr/eBka1s4 +QpS1Sdrvbng3zTCJw0VQe5yM5xyYcHFdeV/v6JSFUz7voyzOGqt91l4UzVFUiZ13 +5Pgi8DUQdQVxUU+MTFwNLCy+bDTuEoKHAxkGEqiq9A08ScxwWtgy7jJQhXDoGP10 +gFMyV+5Qya7rrrYiMhZrjFna7h0z30yiPQIhAK0tbhew8+vHuO6VePIX9TMBZ7ze +k//uQOh/8ZNtS4cTAoIBAGZv2mOljtJM1UUtdl1fzUq0GkI1hjpvqfonq94DITYK +BynJL21JqPfG9JLXc8HYdg5hpwtulrjIyzg1EiB5pQgoNVy8UhavUroPw7FjEicL +dKRHQ9YwuJwuQBTNmX/ojjewqT9U6WYiYUz4SQNXFDIdNz3ikviOoGpmY/Cwbgcr +Pb/QhGqqHzB3ZeX89exVznPbvqeNOp967U+vooBMMJ4oSWVA8ANFVpmikxucRt69 +qKtfkD+3P9RvjVow4dRjOmp8jyT82RQoCeSEThdDVrjUS6IpRdMT8MJ2mwGggG6T +Y16HJCAq/7ufqJlsp5oAuX3aZsnAcnIiDxrMI9m3Xxs= +-----END DSA PARAMETERS----- diff --git a/test/recipes/90-test_store_data/rsa-key-2432.pem b/test/recipes/90-test_store_data/rsa-key-2432.pem new file mode 100644 index 00000000..b5e37f4b --- /dev/null +++ b/test/recipes/90-test_store_data/rsa-key-2432.pem @@ -0,0 +1,32 @@ +-----BEGIN PRIVATE KEY----- +MIIFlQIBADANBgkqhkiG9w0BAQEFAASCBX8wggV7AgEAAoIBMQCrCYwxGQmujZVF +lnZeobOyrk+JiHh4/6IjpepHlb1hRMZbDS2V2kZAupNr3oV14Dx4bDwbxAMOvGQr +sVDiM+LAAZtxXXq6sQNOrq3yTPuCdW6IbsHaB5ZuPwz4cNWOOHs19Jx9UufxoFZ+ +1Cj3WG0joTCTbPNe08llJ67YKCj4b3l19AJKauPFWyLl8sQE5f29rBGGnnJYzrf3 +ZRrrZApbXy2PxDVKfkjLf89la6Hcr/RihgPiZHLoN7TyAPOL4OPY+Jv6fVG9PTrf +3hwoTRD9Wp0ZdmOSCiU93vvoTFovnBMpfh7Qb6k+ufqZV0cvdDWYV7UQO1MBx24R +mqcVGwHzPCMET71GoRNKvtMI3zrN/ZN8lyyqKU3pEPcLvykZ8Pi2lZB31uLA0x6Z +zUe+rEavAgMBAAECggEwM8aFIMvCiYukl1cv5/+tRTbNLwYX6hEAhSgRnq/uj0Zh +gWig1w8nWyrfu7S10/QYeh/RploUzt4quKtJn+AzEQqrgorYvzEcnjH0yDeTn29r +EXPtzNGlMSR3CbImg5IHglLVGH8DZbqy1FvnNtEW4MVHzikaFyenfK6hmB+4H1Sn +gRRnqR1oa/LlwpRV0GHLCSLQf17xoH4chaLLZXi3kdIOIcg9bzDef7APQmKHdu01 +hlAhFZ3rPib63anYtg9jG4hLrZCUHwEwHsOaDEh9QVNSxqZJS2KTtMbYIclK3hDG +wZFmlv9bemE+KiR3EAJt9/xMROjLTNDgTOZZujR/O4IObszQ6obExiL0Z37K0AAz +f0hhMbweg0W1hC3j/pseOZpEvfoK5QZYY0nbdNqVkQKBmQDczLiFYgDEcCbc2ak4 +VGDA/N+R1lUFvfBoBKLlWaOFSnfYC9XrGa1lVe5nMZN4OAgkR4Ogvo1uh5BzXptP +s+fYfh40JS6RFXeO8/K8meFOUnjKiMZroBuFcJHSCDDJZFyfEM1vVqnsaLsqQHAd +casa3PewKvUbUDMWQFNImW6dMuDL3GpKpGc4/eU3208JnpoApcnp2qLPlwKBmQDG +TexoAiQLKRlSHrZcZJTemrTZQFoCPEoXZjbzXHERYoSOcriINWWVuhvAtA64WY/+ +lOYXb3H1kD+CccR1NLUu9lrrFbizeHl9ovrvhLCR8smgVhwP4QjW1fjNYEOfIXXX +BPLCizKSdqDLID/Jph+ym29vOedbjHZmr6Pto3fVBKQPpkLkQmyj061pmknE8DES +k6GFHAAkqQKBmQDTVtxzRwfm/lYkY+417YWikyhHRfihg1k9ptpoXnFG3q1xTHrY +Cf7PFP4ZJfm6Qx9/4jeaP2nOVtGrq+1Kz69lp+mvDbvRwNNsMBGx9jQSrJvTeDE7 +yMcu5T2d5JsV2QtScVnBbRk+IEytt3nYpPkawFAP/j4Xg58yeCV/QuT+cDl8x5+x +jEUE5vhki3TOh1Fut0FZphzaRwKBmHPpKkzlK3JGlKFWiFtbA1VWcm0mWzZBTUF+ +IpJ/LyvtPPQShGBBbd5lyUELPittVmiFWjTKlH7n0OeLXjzwEROhNiWBLdPhkInq +UOjd02OL2WTZ0E9LxyHkMijBouUJ5tpG7yrduDK6GmSAtihE7PQ2PJ1z6BKv+Kku +8w+9ZBbkPo1TLnhDh0L/QLagU4xEpTpphpjKdB75AoGYcaonPrYPhvM+EAe4DDTf +qpxI6wX6P+ws9Fx8VuD/UN3DB8AhE+tlFYQYJQkgqpAvNiOg9ix0mwNDe6oB4xwB +iQKxoBtCKYhwwP7AvXrzyqe73aWtvW9VFYUbdiVQQVqR/+Gd1wL572qFTcnw56je +wxTi4bfTajt7O/nY7jYs3WWstBh0wyl5XNZ14Acic6ZsSp+PLCEfpLo= +-----END PRIVATE KEY----- diff --git a/test/recipes/90-test_store_data/user.cnf b/test/recipes/90-test_store_data/user.cnf deleted file mode 100644 index 91f79694..00000000 --- a/test/recipes/90-test_store_data/user.cnf +++ /dev/null @@ -1,19 +0,0 @@ -#################################################################### -[ req ] -default_bits = 2432 -default_md = sha256 -distinguished_name = req_DN -string_mask = utf8only - -req_extensions = v3_req # The extensions to add to a certificate request - -[ req_DN ] -commonName = "Common Name" -commonName_value = "A user" -userId = "User ID" -userId_value = "test" - -[ v3_req ] -extendedKeyUsage = clientAuth -subjectKeyIdentifier = hash -basicConstraints = CA:false diff --git a/test/recipes/95-test_external_gost_engine.t b/test/recipes/95-test_external_gost_engine.t new file mode 100644 index 00000000..204f78a9 --- /dev/null +++ b/test/recipes/95-test_external_gost_engine.t @@ -0,0 +1,26 @@ +#! /usr/bin/env perl +# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +use OpenSSL::Test; +use OpenSSL::Test::Utils; +use OpenSSL::Test qw/:DEFAULT bldtop_file data_file srctop_file cmdstr/; + +setup("test_external"); + +plan skip_all => "No external tests in this configuration" + if disabled("external-tests"); +plan skip_all => "GOST engine tests not available on Windows or VMS" + if $^O =~ /^(VMS|MSWin32)$/; +plan skip_all => "GOST engine tests only available in a shared build" + if disabled("shared"); + +plan tests => 1; + +ok(run(cmd(["sh", data_file("gost_engine.sh")])), + "running GOST engine tests"); diff --git a/test/recipes/95-test_external_gost_engine_data/gost_engine.sh b/test/recipes/95-test_external_gost_engine_data/gost_engine.sh new file mode 100755 index 00000000..498825ba --- /dev/null +++ b/test/recipes/95-test_external_gost_engine_data/gost_engine.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# +# Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# +# OpenSSL external testing using the GOST engine +# +set -e + +O_EXE=`pwd`/$BLDTOP/apps +O_BINC=`pwd`/$BLDTOP/include +O_SINC=`pwd`/$SRCTOP/include +O_LIB=`pwd`/$BLDTOP + +export PATH=$O_EXE:$PATH +export LD_LIBRARY_PATH=$O_LIB:$LD_LIBRARY_PATH +export OPENSSL_ROOT_DIR=$O_LIB + +# Check/Set openssl version +OPENSSL_VERSION=`openssl version | cut -f 2 -d ' '` + +echo "------------------------------------------------------------------" +echo "Testing OpenSSL using GOST engine:" +echo " CWD: $PWD" +echo " SRCTOP: $SRCTOP" +echo " BLDTOP: $BLDTOP" +echo " OPENSSL_ROOT_DIR: $OPENSSL_ROOT_DIR" +echo " OpenSSL version: $OPENSSL_VERSION" +echo "------------------------------------------------------------------" + +cd $SRCTOP/gost-engine +rm -rf build +mkdir -p build +cd build +cmake .. +make +CTEST_OUTPUT_ON_FAILURE=1 HARNESS_OSSL_PREFIX='' OPENSSL_ENGINES=$OPENSSL_ROOT_DIR/gost-engine/build/bin make test + +exit 0 + diff --git a/test/run_tests.pl b/test/run_tests.pl index b75f7639..bd83a6b9 100644 --- a/test/run_tests.pl +++ b/test/run_tests.pl @@ -14,6 +14,10 @@ use warnings; BEGIN { $ENV{HARNESS_VERBOSE} = "yes" if $ENV{VERBOSE} || $ENV{V}; $ENV{HARNESS_VERBOSE_FAILURE} = "yes" if $ENV{VERBOSE_FAILURE} || $ENV{VF}; + $ENV{HARNESS_VERBOSE_FAILURES_ONLY} = "yes" + if $ENV{VERBOSE_FAILURES_ONLY} || $ENV{VFO}; + $ENV{HARNESS_VERBOSE_FAILURES_PROGRESS} = "yes" + if $ENV{VERBOSE_FAILURES_PROGRESS} || $ENV{VFP}; } use File::Spec::Functions qw/catdir catfile curdir abs2rel rel2abs/; @@ -45,8 +49,10 @@ my %tapargs = # TAP::Parser::OpenSSL implementation further down my %openssl_args = (); -$openssl_args{'failure_verbosity'} = - $ENV{HARNESS_VERBOSE_FAILURE} && $tapargs{verbosity} < 1 ? 1 : 0; +$openssl_args{'failure_verbosity'} = $ENV{HARNESS_VERBOSE} ? 0 : + $ENV{HARNESS_VERBOSE_FAILURE} ? 3 : + $ENV{HARNESS_VERBOSE_FAILURES_PROGRESS} ? 2 : + $ENV{HARNESS_VERBOSE_FAILURES_ONLY} ? 1 : 0; my $outfilename = $ENV{HARNESS_TAP_COPY}; open $openssl_args{'tap_copy'}, ">$outfilename" @@ -110,7 +116,7 @@ sub find_matching_tests { # The following is quite a bit of hackery to adapt to both TAP::Harness # and Test::Harness, depending on what's available. -# The TAP::Harness hack allows support for HARNESS_VERBOSE_FAILURE and +# The TAP::Harness hack allows support for HARNESS_VERBOSE_FAILURE* and # HARNESS_TAP_COPY, while the Test::Harness hack can't, because the pre # TAP::Harness Test::Harness simply doesn't have support for this sort of # thing. @@ -127,26 +133,55 @@ $eres = eval { sub new { my $class = shift; my %opts = %{ shift() }; + my $failure_verbosity = $openssl_args{failure_verbosity}; + print "\n" if $failure_verbosity == 1 || $failure_verbosity == 2; + my @plans = (); # initial level, no plan yet + my $output_buffer = ""; # We rely heavily on perl closures to make failure verbosity work # We need to do so, because there's no way to safely pass extra # objects down all the way to the TAP::Parser::Result object my @failure_output = (); my %callbacks = (); - if ($openssl_args{failure_verbosity} - || defined $openssl_args{tap_copy}) { - $callbacks{ALL} = sub { + if ($failure_verbosity > 0 || defined $openssl_args{tap_copy}) { + $callbacks{ALL} = sub { # on each line of test output my $self = shift; my $fh = $openssl_args{tap_copy}; - print $fh $self->as_string, "\n" if defined $fh; - push @failure_output, $self->as_string - if $openssl_args{failure_verbosity} > 0; - }; + + my $failure_verbosity = $openssl_args{failure_verbosity}; + if ($failure_verbosity == 3) { + push @failure_output, $self->as_string; + } elsif ($failure_verbosity > 0) { + my $is_plan = $self->is_plan; + my $tests_planned = $is_plan && $self->tests_planned; + my $is_test = $self->is_test; + my $is_ok = $is_test && $self->is_ok; + # workaround in case parser not coping with indentation: + if ($self->is_unknown) { + ($is_plan, $tests_planned) = (1, $1) + if ($self->as_string =~ m/^\s+1\.\.(\d+)/); + ($is_test, $is_ok) = (1, !$1) + if ($self->as_string =~ m/^\s+(not )?ok /); + } + if ($is_plan) { + push @plans, $tests_planned; + $output_buffer = ""; # ignore comments etc. until plan + } elsif ($is_test) { # result of a test + pop @plans if @plans && --($plans[-1]) <= 0; + print $output_buffer if !$is_ok; + print $self->as_string."\n" + if !$is_ok || $failure_verbosity == 2; + $output_buffer = ""; + } else { # typically comment or unknown + $output_buffer .= $self->as_string."\n"; + } + } + } } - if ($openssl_args{failure_verbosity} > 0) { + if ($failure_verbosity > 0) { $callbacks{EOF} = sub { my $self = shift; @@ -157,6 +192,8 @@ $eres = eval { # line. print $_, "\n" foreach (("", @failure_output)); } + # Echo any trailing comments etc. + print "$output_buffer" if $failure_verbosity != 3; }; } diff --git a/test/ssl-tests/17-renegotiate.cnf b/test/ssl-tests/17-renegotiate.cnf index 12cf7913..ac826af1 100644 --- a/test/ssl-tests/17-renegotiate.cnf +++ b/test/ssl-tests/17-renegotiate.cnf @@ -1,6 +1,6 @@ # Generated with generate_ssl_tests.pl -num_tests = 14 +num_tests = 15 test-0 = 0-renegotiate-client-no-resume test-1 = 1-renegotiate-client-resume @@ -16,6 +16,7 @@ test-10 = 10-no-renegotiation-server-by-client test-11 = 11-no-renegotiation-server-by-server test-12 = 12-no-renegotiation-client-by-server test-13 = 13-no-renegotiation-client-by-client +test-14 = 14-no-extms-on-renegotiation # =========================================================== [0-renegotiate-client-no-resume] @@ -430,3 +431,35 @@ Method = TLS ResumptionExpected = No +# =========================================================== + +[14-no-extms-on-renegotiation] +ssl_conf = 14-no-extms-on-renegotiation-ssl + +[14-no-extms-on-renegotiation-ssl] +server = 14-no-extms-on-renegotiation-server +client = 14-no-extms-on-renegotiation-client + +[14-no-extms-on-renegotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[14-no-extms-on-renegotiation-client] +CipherString = DEFAULT +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-14] +ExpectedResult = ServerFail +HandshakeMode = RenegotiateClient +Method = TLS +ResumptionExpected = No +client = 14-no-extms-on-renegotiation-client-extra + +[14-no-extms-on-renegotiation-client-extra] +RenegotiateNoExtms = Yes + + diff --git a/test/ssl-tests/17-renegotiate.cnf.in b/test/ssl-tests/17-renegotiate.cnf.in index 2cc21815..ff3f7490 100644 --- a/test/ssl-tests/17-renegotiate.cnf.in +++ b/test/ssl-tests/17-renegotiate.cnf.in @@ -243,6 +243,24 @@ our @tests_tls1_2 = ( "ResumptionExpected" => "No", "ExpectedResult" => "ClientFail" } + }, + { + name => "no-extms-on-renegotiation", + server => { + "MaxProtocol" => "TLSv1.2" + }, + client => { + "MaxProtocol" => "TLSv1.2", + extra => { + "RenegotiateNoExtms" => "Yes" + } + }, + test => { + "Method" => "TLS", + "HandshakeMode" => "RenegotiateClient", + "ResumptionExpected" => "No", + "ExpectedResult" => "ServerFail" + } } ); diff --git a/test/ssl_test_ctx.c b/test/ssl_test_ctx.c index aee9773b..31da26b0 100644 --- a/test/ssl_test_ctx.c +++ b/test/ssl_test_ctx.c @@ -638,6 +638,7 @@ IMPLEMENT_SSL_TEST_STRING_OPTION(SSL_TEST_CTX, test, expected_cipher) IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CLIENT_CONF, client, enable_pha) IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_SERVER_CONF, server, force_pha) +IMPLEMENT_SSL_TEST_BOOL_OPTION(SSL_TEST_CLIENT_CONF, client, no_extms_on_reneg) /* Known test options and their corresponding parse methods. */ @@ -697,6 +698,7 @@ static const ssl_test_client_option ssl_test_client_options[] = { { "SRPPassword", &parse_client_srp_password }, { "MaxFragmentLenExt", &parse_max_fragment_len_mode }, { "EnablePHA", &parse_client_enable_pha }, + { "RenegotiateNoExtms", &parse_client_no_extms_on_reneg }, }; /* Nested server options. */ diff --git a/test/ssl_test_ctx.h b/test/ssl_test_ctx.h index 29a989ab..d08c415f 100644 --- a/test/ssl_test_ctx.h +++ b/test/ssl_test_ctx.h @@ -110,6 +110,8 @@ typedef struct { char *srp_password; /* PHA enabled */ int enable_pha; + /* Do not send extms on renegotiation */ + int no_extms_on_reneg; } SSL_TEST_CLIENT_CONF; typedef struct { diff --git a/test/sslapitest.c b/test/sslapitest.c index c1c288e5..46655690 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "ssltestlib.h" @@ -37,6 +38,10 @@ #include "internal/ktls.h" #include "../ssl/ssl_local.h" +/* Defined in filterprov.c */ +OSSL_provider_init_fn filter_provider_init; +int filter_provider_set_filter(int operation, const char *name); + DEFINE_STACK_OF(OCSP_RESPID) DEFINE_STACK_OF(X509) DEFINE_STACK_OF(X509_NAME) @@ -65,6 +70,8 @@ static SSL_SESSION *create_a_psk(SSL *ssl); static char *certsdir = NULL; static char *cert = NULL; static char *privkey = NULL; +static char *cert2 = NULL; +static char *privkey2 = NULL; static char *srpvfile = NULL; static char *tmpfilename = NULL; @@ -849,9 +856,9 @@ static int execute_test_large_message(const SSL_METHOD *smeth, return testresult; } -#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_KTLS) \ - && !defined(OPENSSL_NO_SOCK) - +#if !defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_KTLS) && \ + !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_TLS1_2)) +#define TLS_CIPHER_MAX_REC_SEQ_SIZE 8 /* sock must be connected */ static int ktls_chk_platform(int sock) { @@ -860,30 +867,26 @@ static int ktls_chk_platform(int sock) return 1; } -static int ping_pong_query(SSL *clientssl, SSL *serverssl, int cfd, int sfd) +static int ping_pong_query(SSL *clientssl, SSL *serverssl, int cfd, int sfd, int rec_seq_size) { static char count = 1; unsigned char cbuf[16000] = {0}; unsigned char sbuf[16000]; size_t err = 0; - char crec_wseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char crec_wseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char crec_rseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char crec_rseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char srec_wseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char srec_wseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char srec_rseq_before[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; - char srec_rseq_after[TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE]; + char crec_wseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char crec_wseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char crec_rseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char crec_rseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char srec_wseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char srec_wseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char srec_rseq_before[TLS_CIPHER_MAX_REC_SEQ_SIZE]; + char srec_rseq_after[TLS_CIPHER_MAX_REC_SEQ_SIZE]; cbuf[0] = count++; - memcpy(crec_wseq_before, &clientssl->rlayer.write_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - memcpy(crec_rseq_before, &clientssl->rlayer.read_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - memcpy(srec_wseq_before, &serverssl->rlayer.write_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - memcpy(srec_rseq_before, &serverssl->rlayer.read_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + memcpy(crec_wseq_before, &clientssl->rlayer.write_sequence, rec_seq_size); + memcpy(crec_rseq_before, &clientssl->rlayer.read_sequence, rec_seq_size); + memcpy(srec_wseq_before, &serverssl->rlayer.write_sequence, rec_seq_size); + memcpy(srec_rseq_before, &serverssl->rlayer.read_sequence, rec_seq_size); if (!TEST_true(SSL_write(clientssl, cbuf, sizeof(cbuf)) == sizeof(cbuf))) goto end; @@ -903,14 +906,10 @@ static int ping_pong_query(SSL *clientssl, SSL *serverssl, int cfd, int sfd) } } - memcpy(crec_wseq_after, &clientssl->rlayer.write_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - memcpy(crec_rseq_after, &clientssl->rlayer.read_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - memcpy(srec_wseq_after, &serverssl->rlayer.write_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); - memcpy(srec_rseq_after, &serverssl->rlayer.read_sequence, - TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + memcpy(crec_wseq_after, &clientssl->rlayer.write_sequence, rec_seq_size); + memcpy(crec_rseq_after, &clientssl->rlayer.read_sequence, rec_seq_size); + memcpy(srec_wseq_after, &serverssl->rlayer.write_sequence, rec_seq_size); + memcpy(srec_rseq_after, &serverssl->rlayer.read_sequence, rec_seq_size); /* verify the payload */ if (!TEST_mem_eq(cbuf, sizeof(cbuf), sbuf, sizeof(sbuf))) @@ -918,42 +917,42 @@ static int ping_pong_query(SSL *clientssl, SSL *serverssl, int cfd, int sfd) /* ktls is used then kernel sequences are used instead of OpenSSL sequences */ if (clientssl->mode & SSL_MODE_NO_KTLS_TX) { - if (!TEST_mem_ne(crec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - crec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_ne(crec_wseq_before, rec_seq_size, + crec_wseq_after, rec_seq_size)) goto end; } else { - if (!TEST_mem_eq(crec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - crec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_eq(crec_wseq_before, rec_seq_size, + crec_wseq_after, rec_seq_size)) goto end; } if (serverssl->mode & SSL_MODE_NO_KTLS_TX) { - if (!TEST_mem_ne(srec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - srec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_ne(srec_wseq_before, rec_seq_size, + srec_wseq_after, rec_seq_size)) goto end; } else { - if (!TEST_mem_eq(srec_wseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - srec_wseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_eq(srec_wseq_before, rec_seq_size, + srec_wseq_after, rec_seq_size)) goto end; } if (clientssl->mode & SSL_MODE_NO_KTLS_RX) { - if (!TEST_mem_ne(crec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - crec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_ne(crec_rseq_before, rec_seq_size, + crec_rseq_after, rec_seq_size)) goto end; } else { - if (!TEST_mem_eq(crec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - crec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_eq(crec_rseq_before, rec_seq_size, + crec_rseq_after, rec_seq_size)) goto end; } if (serverssl->mode & SSL_MODE_NO_KTLS_RX) { - if (!TEST_mem_ne(srec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - srec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_ne(srec_rseq_before, rec_seq_size, + srec_rseq_after, rec_seq_size)) goto end; } else { - if (!TEST_mem_eq(srec_rseq_before, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE, - srec_rseq_after, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE)) + if (!TEST_mem_eq(srec_rseq_before, rec_seq_size, + srec_rseq_after, rec_seq_size)) goto end; } @@ -963,7 +962,9 @@ end: } static int execute_test_ktls(int cis_ktls_tx, int cis_ktls_rx, - int sis_ktls_tx, int sis_ktls_rx) + int sis_ktls_tx, int sis_ktls_rx, + int tls_version, const char *cipher, + int rec_seq_size) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; @@ -980,10 +981,9 @@ static int execute_test_ktls(int cis_ktls_tx, int cis_ktls_rx, /* Create a session based on SHA-256 */ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), - TLS1_2_VERSION, TLS1_2_VERSION, + tls_version, tls_version, &sctx, &cctx, cert, privkey)) - || !TEST_true(SSL_CTX_set_cipher_list(cctx, - "AES128-GCM-SHA256")) + || !TEST_true(SSL_CTX_set_cipher_list(cctx, cipher)) || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl, &clientssl, sfd, cfd))) goto end; @@ -1044,7 +1044,8 @@ static int execute_test_ktls(int cis_ktls_tx, int cis_ktls_rx, goto end; } - if (!TEST_true(ping_pong_query(clientssl, serverssl, cfd, sfd))) + if (!TEST_true(ping_pong_query(clientssl, serverssl, cfd, sfd, + rec_seq_size))) goto end; testresult = 1; @@ -1067,7 +1068,7 @@ end: #define SENDFILE_CHUNK (4 * 4096) #define min(a,b) ((a) > (b) ? (b) : (a)) -static int test_ktls_sendfile(void) +static int test_ktls_sendfile(int tls_version, const char *cipher) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; @@ -1094,10 +1095,9 @@ static int test_ktls_sendfile(void) /* Create a session based on SHA-256 */ if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), - TLS1_2_VERSION, TLS1_2_VERSION, + tls_version, tls_version, &sctx, &cctx, cert, privkey)) - || !TEST_true(SSL_CTX_set_cipher_list(cctx, - "AES128-GCM-SHA256")) + || !TEST_true(SSL_CTX_set_cipher_list(cctx, cipher)) || !TEST_true(create_ssl_objects2(sctx, cctx, &serverssl, &clientssl, sfd, cfd))) goto end; @@ -1168,85 +1168,401 @@ end: return testresult; } -static int test_ktls_no_txrx_client_no_txrx_server(void) +static int test_ktls_no_txrx_client_no_txrx_server(int tlsver) { - return execute_test_ktls(0, 0, 0, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 0, 0, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 0, 0, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 0, 0, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_rx_client_no_txrx_server(void) +static int test_ktls_no_rx_client_no_txrx_server(int tlsver) { - return execute_test_ktls(1, 0, 0, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 0, 0, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 0, 0, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 0, 0, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_tx_client_no_txrx_server(void) +static int test_ktls_no_tx_client_no_txrx_server(int tlsver) { - return execute_test_ktls(0, 1, 0, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 1, 0, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 1, 0, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 1, 0, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_client_no_txrx_server(void) +static int test_ktls_client_no_txrx_server(int tlsver) { - return execute_test_ktls(1, 1, 0, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 1, 0, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 1, 0, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 1, 0, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_txrx_client_no_rx_server(void) +static int test_ktls_no_txrx_client_no_rx_server(int tlsver) { - return execute_test_ktls(0, 0, 1, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 0, 1, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 0, 1, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 0, 1, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_rx_client_no_rx_server(void) +static int test_ktls_no_rx_client_no_rx_server(int tlsver) { - return execute_test_ktls(1, 0, 1, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 0, 1, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 0, 1, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 0, 1, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_tx_client_no_rx_server(void) +static int test_ktls_no_tx_client_no_rx_server(int tlsver) { - return execute_test_ktls(0, 1, 1, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 1, 1, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 1, 1, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 1, 1, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_client_no_rx_server(void) +static int test_ktls_client_no_rx_server(int tlsver) { - return execute_test_ktls(1, 1, 1, 0); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 1, 1, 0, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 1, 1, 0, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 1, 1, 0, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_txrx_client_no_tx_server(void) +static int test_ktls_no_txrx_client_no_tx_server(int tlsver) { - return execute_test_ktls(0, 0, 0, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 0, 0, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 0, 0, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 0, 0, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_rx_client_no_tx_server(void) +static int test_ktls_no_rx_client_no_tx_server(int tlsver) { - return execute_test_ktls(1, 0, 0, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 0, 0, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 0, 0, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 0, 0, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_tx_client_no_tx_server(void) +static int test_ktls_no_tx_client_no_tx_server(int tlsver) { - return execute_test_ktls(0, 1, 0, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 1, 0, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 1, 0, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 1, 0, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_client_no_tx_server(void) +static int test_ktls_client_no_tx_server(int tlsver) { - return execute_test_ktls(1, 1, 0, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 1, 0, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 1, 0, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 1, 0, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_txrx_client_server(void) +static int test_ktls_no_txrx_client_server(int tlsver) { - return execute_test_ktls(0, 0, 1, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 0, 1, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 0, 1, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 0, 1, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_rx_client_server(void) +static int test_ktls_no_rx_client_server(int tlsver) { - return execute_test_ktls(1, 0, 1, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 0, 1, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 0, 1, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 0, 1, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_no_tx_client_server(void) +static int test_ktls_no_tx_client_server(int tlsver) { - return execute_test_ktls(0, 1, 1, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(0, 1, 1, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(0, 1, 1, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(0, 1, 1, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } -static int test_ktls_client_server(void) +static int test_ktls_client_server(int tlsver) { - return execute_test_ktls(1, 1, 1, 1); + int testresult = 1; + +#ifdef OPENSSL_KTLS_AES_GCM_128 + testresult &= execute_test_ktls(1, 1, 1, 1, tlsver, + "AES128-GCM-SHA256", TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_CCM_128 + testresult &= execute_test_ktls(1, 1, 1, 1, tlsver, + "AES128-CCM-SHA256", TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE); +#endif +#ifdef OPENSSL_KTLS_AES_GCM_256 + testresult &= execute_test_ktls(1, 1, 1, 1, tlsver, + "AES256-GCM-SHA384", TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE); +#endif + return testresult; } + +#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3) +static int test_ktls(int test) +{ + int tlsver; + + if (test > 15) { +#if defined(OPENSSL_NO_TLS1_3) + return 1; +#else + test -= 16; + tlsver = TLS1_3_VERSION; +#endif + } else { +#if defined(OPENSSL_NO_TLS1_2) + return 1; +#else + tlsver = TLS1_2_VERSION; +#endif + } + + switch(test) { + case 0: + return test_ktls_no_txrx_client_no_txrx_server(tlsver); + case 1: + return test_ktls_no_rx_client_no_txrx_server(tlsver); + case 2: + return test_ktls_no_tx_client_no_txrx_server(tlsver); + case 3: + return test_ktls_client_no_txrx_server(tlsver); + case 4: + return test_ktls_no_txrx_client_no_rx_server(tlsver); + case 5: + return test_ktls_no_rx_client_no_rx_server(tlsver); + case 6: + return test_ktls_no_tx_client_no_rx_server(tlsver); + case 7: + return test_ktls_client_no_rx_server(tlsver); + case 8: + return test_ktls_no_txrx_client_no_tx_server(tlsver); + case 9: + return test_ktls_no_rx_client_no_tx_server(tlsver); + case 10: + return test_ktls_no_tx_client_no_tx_server(tlsver); + case 11: + return test_ktls_client_no_tx_server(tlsver); + case 12: + return test_ktls_no_txrx_client_server(tlsver); + case 13: + return test_ktls_no_rx_client_server(tlsver); + case 14: + return test_ktls_no_tx_client_server(tlsver); + case 15: + return test_ktls_client_server(tlsver); + default: + return 0; + } +} + +static int test_ktls_sendfile_anytls(int tst) +{ + char *cipher[] = {"AES128-GCM-SHA256","AES128-CCM-SHA256","AES256-GCM-SHA384"}; + int tlsver; + + if (tst > 2) { +#if defined(OPENSSL_NO_TLS1_3) + return 1; +#else + tst -= 3; + tlsver = TLS1_3_VERSION; +#endif + } else { +#if defined(OPENSSL_NO_TLS1_2) + return 1; +#else + tlsver = TLS1_2_VERSION; +#endif + } + +#ifndef OPENSSL_KTLS_AES_GCM_128 + if(tst == 0) return 1; +#endif +#ifndef OPENSSL_KTLS_AES_CCM_128 + if(tst == 1) return 1; +#endif +#ifndef OPENSSL_KTLS_AES_GCM_256 + if(tst == 2) return 1; +#endif + return test_ktls_sendfile(tlsver, cipher[tst]); +} + +#endif #endif static int test_large_message_tls(void) @@ -6606,7 +6922,7 @@ static int tick_key_evp_cb(SSL *s, unsigned char key_name[16], params[2] = OSSL_PARAM_construct_end(); if (aes128cbc == NULL || !EVP_CipherInit_ex(ctx, aes128cbc, NULL, tick_aes_key, iv, enc) - || !EVP_MAC_CTX_set_params(hctx, params) + || !EVP_MAC_set_ctx_params(hctx, params) || !EVP_MAC_init(hctx)) ret = -1; else @@ -6782,6 +7098,61 @@ static int test_ticket_callbacks(int tst) return testresult; } +/* + * Test incorrect shutdown. + * Test 0: client does not shutdown properly, + * server does not set SSL_OP_IGNORE_UNEXPECTED_EOF, + * server should get SSL_ERROR_SSL + * Test 1: client does not shutdown properly, + * server sets SSL_OP_IGNORE_UNEXPECTED_EOF, + * server should get SSL_ERROR_ZERO_RETURN + */ +static int test_incorrect_shutdown(int tst) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + char buf[80]; + BIO *c2s; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (tst == 1) + SSL_CTX_set_options(sctx, SSL_OP_IGNORE_UNEXPECTED_EOF); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + c2s = SSL_get_rbio(serverssl); + BIO_set_mem_eof_return(c2s, 0); + + if (!TEST_false(SSL_read(serverssl, buf, sizeof(buf)))) + goto end; + + if (tst == 0 && !TEST_int_eq(SSL_get_error(serverssl, 0), SSL_ERROR_SSL) ) + goto end; + if (tst == 1 && !TEST_int_eq(SSL_get_error(serverssl, 0), SSL_ERROR_ZERO_RETURN) ) + goto end; + + testresult = 1; + + end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + /* * Test bi-directional shutdown. * Test 0: TLSv1.2 @@ -7609,6 +7980,131 @@ static int test_servername(int tst) return testresult; } +#ifndef OPENSSL_NO_EC +/* + * Test that if signature algorithms are not available, then we do not offer or + * accept them. + * Test 0: Two RSA sig algs available: both RSA sig algs shared + * Test 1: The client only has SHA2-256: only SHA2-256 algorithms shared + * Test 2: The server only has SHA2-256: only SHA2-256 algorithms shared + * Test 3: An RSA and an ECDSA sig alg available: both sig algs shared + * Test 4: The client only has an ECDSA sig alg: only ECDSA algorithms shared + * Test 5: The server only has an ECDSA sig alg: only ECDSA algorithms shared + */ +static int test_sigalgs_available(int idx) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + OPENSSL_CTX *tmpctx = OPENSSL_CTX_new(); + OPENSSL_CTX *clientctx = libctx, *serverctx = libctx; + OSSL_PROVIDER *filterprov = NULL; + int sig, hash; + + if (!TEST_ptr(tmpctx)) + goto end; + + if (idx != 0 && idx != 3) { + if (!TEST_true(OSSL_PROVIDER_add_builtin(tmpctx, "filter", + filter_provider_init))) + goto end; + + filterprov = OSSL_PROVIDER_load(tmpctx, "filter"); + if (!TEST_ptr(filterprov)) + goto end; + + if (idx < 3) { + /* + * Only enable SHA2-256 so rsa_pss_rsae_sha384 should not be offered + * or accepted for the peer that uses this libctx. Note that libssl + * *requires* SHA2-256 to be available so we cannot disable that. We + * also need SHA1 for our certificate. + */ + if (!TEST_true(filter_provider_set_filter(OSSL_OP_DIGEST, + "SHA2-256:SHA1"))) + goto end; + } else { + if (!TEST_true(filter_provider_set_filter(OSSL_OP_SIGNATURE, + "ECDSA")) + || !TEST_true(filter_provider_set_filter(OSSL_OP_KEYMGMT, + "EC:X25519:X448"))) + goto end; + } + + if (idx == 1 || idx == 4) + clientctx = tmpctx; + else + serverctx = tmpctx; + } + + cctx = SSL_CTX_new_with_libctx(clientctx, NULL, TLS_client_method()); + sctx = SSL_CTX_new_with_libctx(serverctx, NULL, TLS_server_method()); + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), + TLS1_VERSION, + 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (idx < 3) { + if (!SSL_CTX_set1_sigalgs_list(cctx, + "rsa_pss_rsae_sha384" + ":rsa_pss_rsae_sha256") + || !SSL_CTX_set1_sigalgs_list(sctx, + "rsa_pss_rsae_sha384" + ":rsa_pss_rsae_sha256")) + goto end; + } else { + if (!SSL_CTX_set1_sigalgs_list(cctx, "rsa_pss_rsae_sha256:ECDSA+SHA256") + || !SSL_CTX_set1_sigalgs_list(sctx, + "rsa_pss_rsae_sha256:ECDSA+SHA256")) + goto end; + } + + if (!TEST_int_eq(SSL_CTX_use_certificate_file(sctx, cert2, + SSL_FILETYPE_PEM), 1) + || !TEST_int_eq(SSL_CTX_use_PrivateKey_file(sctx, + privkey2, + SSL_FILETYPE_PEM), 1) + || !TEST_int_eq(SSL_CTX_check_private_key(sctx), 1)) + goto end; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* For tests 0 and 3 we expect 2 shared sigalgs, otherwise exactly 1 */ + if (!TEST_int_eq(SSL_get_shared_sigalgs(serverssl, 0, &sig, &hash, NULL, + NULL, NULL), + (idx == 0 || idx == 3) ? 2 : 1)) + goto end; + + if (!TEST_int_eq(hash, idx == 0 ? NID_sha384 : NID_sha256)) + goto end; + + if (!TEST_int_eq(sig, (idx == 4 || idx == 5) ? EVP_PKEY_EC + : NID_rsassaPss)) + goto end; + + testresult = 1; + + end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + OSSL_PROVIDER_unload(filterprov); + OPENSSL_CTX_free(tmpctx); + + return testresult; +} +#endif /* OPENSSL_NO_EC */ + + OPT_TEST_DECLARE_USAGE("certfile privkeyfile srpvfile tmpfile provider config\n") int setup_tests(void) @@ -7675,33 +8171,25 @@ int setup_tests(void) cert = test_mk_file_path(certsdir, "servercert.pem"); if (cert == NULL) - return 0; + goto err; privkey = test_mk_file_path(certsdir, "serverkey.pem"); - if (privkey == NULL) { - OPENSSL_free(cert); - return 0; - } + if (privkey == NULL) + goto err; -#if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_KTLS) \ - && !defined(OPENSSL_NO_SOCK) - ADD_TEST(test_ktls_no_txrx_client_no_txrx_server); - ADD_TEST(test_ktls_no_rx_client_no_txrx_server); - ADD_TEST(test_ktls_no_tx_client_no_txrx_server); - ADD_TEST(test_ktls_client_no_txrx_server); - ADD_TEST(test_ktls_no_txrx_client_no_rx_server); - ADD_TEST(test_ktls_no_rx_client_no_rx_server); - ADD_TEST(test_ktls_no_tx_client_no_rx_server); - ADD_TEST(test_ktls_client_no_rx_server); - ADD_TEST(test_ktls_no_txrx_client_no_tx_server); - ADD_TEST(test_ktls_no_rx_client_no_tx_server); - ADD_TEST(test_ktls_no_tx_client_no_tx_server); - ADD_TEST(test_ktls_client_no_tx_server); - ADD_TEST(test_ktls_no_txrx_client_server); - ADD_TEST(test_ktls_no_rx_client_server); - ADD_TEST(test_ktls_no_tx_client_server); - ADD_TEST(test_ktls_client_server); - ADD_TEST(test_ktls_sendfile); + cert2 = test_mk_file_path(certsdir, "server-ecdsa-cert.pem"); + if (cert2 == NULL) + goto err; + + privkey2 = test_mk_file_path(certsdir, "server-ecdsa-key.pem"); + if (privkey2 == NULL) + goto err; + +#if !defined(OPENSSL_NO_KTLS) && !defined(OPENSSL_NO_SOCK) +#if !defined(OPENSSL_NO_TLS1_2) || !defined(OPENSSL_NO_TLS1_3) + ADD_ALL_TESTS(test_ktls, 32); + ADD_ALL_TESTS(test_ktls_sendfile_anytls, 6); +#endif #endif ADD_TEST(test_large_message_tls); ADD_TEST(test_large_message_tls_read_ahead); @@ -7796,6 +8284,7 @@ int setup_tests(void) ADD_ALL_TESTS(test_ssl_get_shared_ciphers, OSSL_NELEM(shared_ciphers_data)); ADD_ALL_TESTS(test_ticket_callbacks, 16); ADD_ALL_TESTS(test_shutdown, 7); + ADD_ALL_TESTS(test_incorrect_shutdown, 2); ADD_ALL_TESTS(test_cert_cb, 6); ADD_ALL_TESTS(test_client_cert_cb, 2); ADD_ALL_TESTS(test_ca_names, 3); @@ -7803,13 +8292,25 @@ int setup_tests(void) ADD_ALL_TESTS(test_multiblock_write, OSSL_NELEM(multiblock_cipherlist_data)); #endif ADD_ALL_TESTS(test_servername, 10); +#ifndef OPENSSL_NO_EC + ADD_ALL_TESTS(test_sigalgs_available, 6); +#endif return 1; + + err: + OPENSSL_free(cert); + OPENSSL_free(privkey); + OPENSSL_free(cert2); + OPENSSL_free(privkey2); + return 0; } void cleanup_tests(void) { OPENSSL_free(cert); OPENSSL_free(privkey); + OPENSSL_free(cert2); + OPENSSL_free(privkey2); bio_s_mempacket_test_free(); bio_s_always_retry_free(); OSSL_PROVIDER_unload(defctxnull); diff --git a/test/sslprovidertest.c b/test/sslprovidertest.c deleted file mode 100644 index 8bcfd5f9..00000000 --- a/test/sslprovidertest.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include - -#include "ssltestlib.h" -#include "testutil.h" - -static char *cert = NULL; -static char *privkey = NULL; -static char *modulename = NULL; -static char *configfile = NULL; - -static OSSL_PROVIDER *defctxlegacy = NULL; - -static int test_different_libctx(void) -{ - SSL_CTX *cctx = NULL, *sctx = NULL; - SSL *clientssl = NULL, *serverssl = NULL; - int testresult = 0; - OPENSSL_CTX *libctx = OPENSSL_CTX_new(); - OSSL_PROVIDER *prov = NULL; - - /* - * Verify that the default and fips providers in the default libctx are not - * available - */ - if (!TEST_false(OSSL_PROVIDER_available(NULL, "default")) - || !TEST_false(OSSL_PROVIDER_available(NULL, "fips"))) - goto end; - - if (!TEST_true(OPENSSL_CTX_load_config(libctx, configfile))) - goto end; - - prov = OSSL_PROVIDER_load(libctx, modulename); - if (!TEST_ptr(prov) - /* Check we have the provider available */ - || !TEST_true(OSSL_PROVIDER_available(libctx, modulename))) - goto end; - /* Check the default provider is not available */ - if (strcmp(modulename, "default") != 0 - && !TEST_false(OSSL_PROVIDER_available(libctx, "default"))) - goto end; - TEST_note("%s provider loaded", modulename); - - /* - * TODO(3.0): Make this work in TLSv1.3. Currently we can only do RSA key - * exchange, because we don't have key gen/param gen for EC yet - which - * implies TLSv1.2 only - */ - if (!TEST_true(create_ssl_ctx_pair(libctx, - TLS_server_method(), - TLS_client_method(), - TLS1_VERSION, - TLS1_2_VERSION, - &sctx, &cctx, cert, privkey))) - goto end; - - /* Ensure we use a FIPS compatible ciphersuite and sigalg */ - if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "AES128-SHA256")) - || !TEST_true(SSL_CTX_set1_sigalgs_list(cctx, "RSA+SHA256"))) - goto end; - - if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, - NULL, NULL))) - goto end; - - /* This time we expect success */ - if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) - goto end; - - /* - * Verify that the default and fips providers in the default libctx are - * still not available - */ - if (!TEST_false(OSSL_PROVIDER_available(NULL, "default")) - || !TEST_false(OSSL_PROVIDER_available(NULL, "fips"))) - goto end; - - testresult = 1; - - end: - SSL_free(serverssl); - SSL_free(clientssl); - SSL_CTX_free(sctx); - SSL_CTX_free(cctx); - - OSSL_PROVIDER_unload(prov); - OPENSSL_CTX_free(libctx); - - return testresult; -} - -int setup_tests(void) -{ - char *certsdir = NULL; - - if (!test_skip_common_options()) { - TEST_error("Error parsing test options\n"); - return 0; - } - - if (!TEST_ptr(certsdir = test_get_argument(0)) - || !TEST_ptr(modulename = test_get_argument(1)) - || !TEST_ptr(configfile = test_get_argument(2))) - return 0; - - cert = test_mk_file_path(certsdir, "servercert.pem"); - if (cert == NULL) - return 0; - - privkey = test_mk_file_path(certsdir, "serverkey.pem"); - if (privkey == NULL) { - OPENSSL_free(cert); - return 0; - } - - /* - * For tests in this file we want to ensure the default ctx does not have - * the default provider loaded into the default ctx. So we load "legacy" to - * prevent default from being auto-loaded. This tests that there is no - * "leakage", i.e. when using SSL_CTX_new_with_libctx() we expect only the - * specific libctx to be used - nothing should fall back to the default - * libctx - */ - defctxlegacy = OSSL_PROVIDER_load(NULL, "legacy"); - - ADD_TEST(test_different_libctx); - - return 1; -} - -void cleanup_tests(void) -{ - OSSL_PROVIDER_unload(defctxlegacy); -} diff --git a/test/ssltestlib.c b/test/ssltestlib.c index ce0e7761..2447af14 100644 --- a/test/ssltestlib.c +++ b/test/ssltestlib.c @@ -10,21 +10,53 @@ #include #include "internal/nelem.h" -#include "internal/cryptlib.h" /* for ossl_sleep() */ #include "ssltestlib.h" #include "testutil.h" #include "e_os.h" #ifdef OPENSSL_SYS_UNIX # include -# ifndef OPENSSL_NO_KTLS -# include -# include -# include -# include -# include -# include +#ifndef OPENSSL_NO_KTLS +# include +# include +# include +# include +# include +# include +#endif + +static ossl_inline void ossl_sleep(unsigned int millis) +{ +# ifdef OPENSSL_SYS_VXWORKS + struct timespec ts; + ts.tv_sec = (long int) (millis / 1000); + ts.tv_nsec = (long int) (millis % 1000) * 1000000ul; + nanosleep(&ts, NULL); +# else + usleep(millis * 1000); # endif +} +#elif defined(_WIN32) +# include + +static ossl_inline void ossl_sleep(unsigned int millis) +{ + Sleep(millis); +} +#else +/* Fallback to a busy wait */ +static ossl_inline void ossl_sleep(unsigned int millis) +{ + struct timeval start, now; + unsigned int elapsedms; + + gettimeofday(&start, NULL); + do { + gettimeofday(&now, NULL); + elapsedms = (((now.tv_sec - start.tv_sec) * 1000000) + + now.tv_usec - start.tv_usec) / 1000; + } while (elapsedms < millis); +} #endif static int tls_dump_new(BIO *bi); @@ -741,8 +773,10 @@ const SSL_METHOD *cm, return 1; err: - SSL_CTX_free(serverctx); - SSL_CTX_free(clientctx); + if (*sctx == NULL) + SSL_CTX_free(serverctx); + if (cctx != NULL && *cctx == NULL) + SSL_CTX_free(clientctx); return 0; } @@ -1017,6 +1051,11 @@ int create_ssl_connection(SSL *serverssl, SSL *clientssl, int want) if (!create_bare_ssl_connection(serverssl, clientssl, want, 1)) return 0; +#ifndef OPENSSL_NO_QUIC + /* QUIC does not support SSL_read_ex */ + if (SSL_is_quic(clientssl)) + return 1; +#endif /* * We attempt to read some data on the client side which we expect to fail. * This will ensure we have received the NewSessionTicket in TLSv1.3 where diff --git a/test/testutil/basic_output.c b/test/testutil/basic_output.c index 93afcd0f..bbed57c5 100644 --- a/test/testutil/basic_output.c +++ b/test/testutil/basic_output.c @@ -14,27 +14,51 @@ #include #include +/* These are available for any test program */ BIO *bio_out = NULL; BIO *bio_err = NULL; +/* These are available for TAP output only (internally) */ +static BIO *tap_out = NULL; +static BIO *tap_err = NULL; + void test_open_streams(void) { - bio_out = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); - bio_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); + tap_out = BIO_new_fp(stdout, BIO_NOCLOSE | BIO_FP_TEXT); + tap_err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT); #ifdef __VMS - bio_out = BIO_push(BIO_new(BIO_f_linebuffer()), bio_out); - bio_err = BIO_push(BIO_new(BIO_f_linebuffer()), bio_err); + tap_out = BIO_push(BIO_new(BIO_f_linebuffer()), tap_out); + tap_err = BIO_push(BIO_new(BIO_f_linebuffer()), tap_err); #endif - bio_err = BIO_push(BIO_new(BIO_f_tap()), bio_err); + tap_out = BIO_push(BIO_new(BIO_f_prefix()), tap_out); + tap_err = BIO_push(BIO_new(BIO_f_prefix()), tap_err); + + bio_out = BIO_push(BIO_new(BIO_f_prefix()), tap_out); + bio_err = BIO_push(BIO_new(BIO_f_prefix()), tap_err); + BIO_set_prefix(bio_out, "# "); + BIO_set_prefix(bio_err, "# "); OPENSSL_assert(bio_out != NULL); OPENSSL_assert(bio_err != NULL); } +void test_adjust_streams_tap_level(int level) +{ + BIO_set_indent(tap_out, level); + BIO_set_indent(tap_err, level); +} + void test_close_streams(void) { - BIO_free_all(bio_out); - BIO_free_all(bio_err); + /* + * The rest of the chain is freed by the BIO_free_all() calls below, so + * we only need to free the last one in the bio_out and bio_err chains. + */ + BIO_free(bio_out); + BIO_free(bio_err); + + BIO_free_all(tap_out); + BIO_free_all(tap_err); } int test_vprintf_stdout(const char *fmt, va_list ap) @@ -56,3 +80,23 @@ int test_flush_stderr(void) { return BIO_flush(bio_err); } + +int test_vprintf_tapout(const char *fmt, va_list ap) +{ + return BIO_vprintf(tap_out, fmt, ap); +} + +int test_vprintf_taperr(const char *fmt, va_list ap) +{ + return BIO_vprintf(tap_err, fmt, ap); +} + +int test_flush_tapout(void) +{ + return BIO_flush(tap_out); +} + +int test_flush_taperr(void) +{ + return BIO_flush(tap_err); +} diff --git a/test/testutil/driver.c b/test/testutil/driver.c index 030fb154..775e3daf 100644 --- a/test/testutil/driver.c +++ b/test/testutil/driver.c @@ -76,11 +76,6 @@ void add_all_tests(const char *test_case_name, int(*test_fn)(int idx), num_test_cases += num; } -int subtest_level(void) -{ - return level; -} - static int gcd(int a, int b) { while (b != 0) { @@ -96,7 +91,7 @@ static void set_seed(int s) seed = s; if (seed <= 0) seed = (int)time(NULL); - test_printf_stdout("%*s# RAND SEED %d\n", subtest_level(), "", seed); + test_printf_stdout("RAND SEED %d\n", seed); test_flush_stdout(); test_random_seed(seed); } @@ -109,6 +104,7 @@ int setup_test_framework(int argc, char *argv[]) if (TAP_levels != NULL) level = 4 * atoi(TAP_levels); + test_adjust_streams_tap_level(level); if (test_seed != NULL) set_seed(atoi(test_seed)); @@ -214,6 +210,7 @@ static int process_shared_options(void) if (!opt_int(opt_arg(), &value)) goto end; level = 4 * value; + test_adjust_streams_tap_level(level); break; case OPT_TEST_SEED: if (!opt_int(opt_arg(), &value)) @@ -260,13 +257,13 @@ PRINTF_FORMAT(2, 3) static void test_verdict(int verdict, test_flush_stdout(); test_flush_stderr(); - test_printf_stdout("%*s%s ", level, "", verdict != 0 ? "ok" : "not ok"); + test_printf_tapout("%s ", verdict != 0 ? "ok" : "not ok"); va_start(ap, description); - test_vprintf_stdout(description, ap); + test_vprintf_tapout(description, ap); va_end(ap); if (verdict == TEST_SKIP_CODE) - test_printf_stdout(" # skipped"); - test_printf_stdout("\n"); + test_printf_tapout(" # skipped"); + test_printf_tapout("\n"); test_flush_stdout(); } @@ -284,12 +281,11 @@ int run_tests(const char *test_prog_name) return EXIT_FAILURE; if (num_tests < 1) { - test_printf_stdout("%*s1..0 # Skipped: %s\n", level, "", - test_prog_name); + test_printf_tapout("1..0 # Skipped: %s\n", test_prog_name); } else if (show_list == 0 && single_test == -1) { if (level > 0) - test_printf_stdout("%*s# Subtest: %s\n", level, "", test_prog_name); - test_printf_stdout("%*s1..%d\n", level, "", num_tests); + test_printf_stdout("Subtest: %s\n", test_prog_name); + test_printf_tapout("1..%d\n", num_tests); } test_flush_stdout(); @@ -312,11 +308,11 @@ int run_tests(const char *test_prog_name) } else if (show_list) { if (all_tests[i].num != -1) { - test_printf_stdout("%d - %s (%d..%d)\n", ii + 1, + test_printf_tapout("%d - %s (%d..%d)\n", ii + 1, all_tests[i].test_case_name, 1, all_tests[i].num); } else { - test_printf_stdout("%d - %s\n", ii + 1, + test_printf_tapout("%d - %s\n", ii + 1, all_tests[i].test_case_name); } test_flush_stdout(); @@ -332,11 +328,11 @@ int run_tests(const char *test_prog_name) verdict = TEST_SKIP_CODE; level += 4; + test_adjust_streams_tap_level(level); if (all_tests[i].subtest && single_iter == -1) { - test_printf_stdout("%*s# Subtest: %s\n", level, "", + test_printf_stdout("Subtest: %s\n", all_tests[i].test_case_name); - test_printf_stdout("%*s%d..%d\n", level, "", 1, - all_tests[i].num); + test_printf_tapout("%d..%d\n", 1, all_tests[i].num); test_flush_stdout(); } @@ -375,6 +371,7 @@ int run_tests(const char *test_prog_name) } level -= 4; + test_adjust_streams_tap_level(level); if (verdict == 0) ++num_failed; test_verdict(verdict, "%d - %s", ii + 1, diff --git a/test/testutil/format_output.c b/test/testutil/format_output.c index 7f514751..a2f8a9e0 100644 --- a/test/testutil/format_output.c +++ b/test/testutil/format_output.c @@ -42,7 +42,8 @@ static void test_fail_string_common(const char *prefix, const char *file, const char *op, const char *m1, size_t l1, const char *m2, size_t l2) { - const size_t width = (MAX_STRING_WIDTH - subtest_level() - 12) / 16 * 16; + const size_t width = + (MAX_STRING_WIDTH - BIO_get_indent(bio_err) - 12) / 16 * 16; char b1[MAX_STRING_WIDTH + 1], b2[MAX_STRING_WIDTH + 1]; char bdiff[MAX_STRING_WIDTH + 1]; size_t n1, n2, i; diff --git a/test/testutil/output.h b/test/testutil/output.h index def76af1..8da73e2a 100644 --- a/test/testutil/output.h +++ b/test/testutil/output.h @@ -35,20 +35,31 @@ */ void test_open_streams(void); void test_close_streams(void); +void test_adjust_streams_tap_level(int level); /* The following ALL return the number of characters written */ int test_vprintf_stdout(const char *fmt, va_list ap) ossl_test__attr__((__format__(ossl_test__printf__, 1, 0))); +int test_vprintf_tapout(const char *fmt, va_list ap) + ossl_test__attr__((__format__(ossl_test__printf__, 1, 0))); int test_vprintf_stderr(const char *fmt, va_list ap) ossl_test__attr__((__format__(ossl_test__printf__, 1, 0))); +int test_vprintf_taperr(const char *fmt, va_list ap) + ossl_test__attr__((__format__(ossl_test__printf__, 1, 0))); /* These return failure or success */ int test_flush_stdout(void); +int test_flush_tapout(void); int test_flush_stderr(void); +int test_flush_taperr(void); /* Commodity functions. There's no need to override these */ int test_printf_stdout(const char *fmt, ...) ossl_test__attr__((__format__(ossl_test__printf__, 1, 2))); +int test_printf_tapout(const char *fmt, ...) + ossl_test__attr__((__format__(ossl_test__printf__, 1, 2))); int test_printf_stderr(const char *fmt, ...) ossl_test__attr__((__format__(ossl_test__printf__, 1, 2))); +int test_printf_taperr(const char *fmt, ...) + ossl_test__attr__((__format__(ossl_test__printf__, 1, 2))); # undef ossl_test__printf__ # undef ossl_test__attr__ diff --git a/test/testutil/output_helpers.c b/test/testutil/output_helpers.c index eb614f12..64e99dac 100644 --- a/test/testutil/output_helpers.c +++ b/test/testutil/output_helpers.c @@ -32,3 +32,27 @@ int test_printf_stderr(const char *fmt, ...) return ret; } + +int test_printf_tapout(const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = test_vprintf_tapout(fmt, ap); + va_end(ap); + + return ret; +} + +int test_printf_taperr(const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = test_vprintf_taperr(fmt, ap); + va_end(ap); + + return ret; +} diff --git a/test/testutil/tap_bio.c b/test/testutil/tap_bio.c deleted file mode 100644 index f3ee2787..00000000 --- a/test/testutil/tap_bio.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "tu_local.h" - -static int tap_write_ex(BIO *b, const char *buf, size_t size, size_t *in_size); -static int tap_read_ex(BIO *b, char *buf, size_t size, size_t *out_size); -static int tap_puts(BIO *b, const char *str); -static int tap_gets(BIO *b, char *str, int size); -static long tap_ctrl(BIO *b, int cmd, long arg1, void *arg2); -static int tap_new(BIO *b); -static int tap_free(BIO *b); -static long tap_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); - -const BIO_METHOD *BIO_f_tap(void) -{ - static BIO_METHOD *tap = NULL; - - if (tap == NULL) { - tap = BIO_meth_new(BIO_TYPE_START | BIO_TYPE_FILTER, "tap"); - if (tap != NULL) { - BIO_meth_set_write_ex(tap, tap_write_ex); - BIO_meth_set_read_ex(tap, tap_read_ex); - BIO_meth_set_puts(tap, tap_puts); - BIO_meth_set_gets(tap, tap_gets); - BIO_meth_set_ctrl(tap, tap_ctrl); - BIO_meth_set_create(tap, tap_new); - BIO_meth_set_destroy(tap, tap_free); - BIO_meth_set_callback_ctrl(tap, tap_callback_ctrl); - } - } - return tap; -} - -static int tap_new(BIO *b) -{ - BIO_set_data(b, NULL); - BIO_set_init(b, 1); - return 1; -} - -static int tap_free(BIO *b) -{ - if (b == NULL) - return 0; - BIO_set_data(b, NULL); - BIO_set_init(b, 0); - return 1; -} - -static int tap_read_ex(BIO *b, char *buf, size_t size, size_t *out_size) -{ - BIO *next = BIO_next(b); - int ret = 0; - - ret = BIO_read_ex(next, buf, size, out_size); - BIO_clear_retry_flags(b); - BIO_copy_next_retry(b); - return ret; -} - -/* - * Output a string to the specified bio and return 1 if successful. - */ -static int write_string(BIO *b, const char *buf, size_t n) -{ - size_t m; - - return BIO_write_ex(b, buf, n, &m) != 0 && m == n; -} - -/* - * Write some data. - * - * This function implements a simple state machine that detects new lines. - * It indents the output and prefixes it with a '#' character. - * - * It returns the number of input characters that were output in in_size. - * More characters than this will likely have been output however any calling - * code will be unable to correctly assess the actual number of characters - * emitted and would be prone to failure if the actual number were returned. - * - * The BIO_data field is used as our state. If it is NULL, we've just - * seen a new line. If it is not NULL, we're processing characters in a line. - */ -static int tap_write_ex(BIO *b, const char *buf, size_t size, size_t *in_size) -{ - static char empty[] = ""; - BIO *next = BIO_next(b); - size_t i; - int j; - - for (i = 0; i < size; i++) { - if (BIO_get_data(b) == NULL) { - BIO_set_data(b, empty); - for (j = 0; j < subtest_level(); j++) - if (!write_string(next, " ", 1)) - goto err; - if (!write_string(next, "# ", 2)) - goto err; - } - if (!write_string(next, buf + i, 1)) - goto err; - if (buf[i] == '\n') - BIO_set_data(b, NULL); - } - *in_size = i; - return 1; - -err: - *in_size = i; - return 0; -} - -static long tap_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - BIO *next = BIO_next(b); - - switch (cmd) { - case BIO_CTRL_RESET: - BIO_set_data(b, NULL); - break; - - default: - break; - } - return BIO_ctrl(next, cmd, num, ptr); -} - -static long tap_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) -{ - return BIO_callback_ctrl(BIO_next(b), cmd, fp); -} - -static int tap_gets(BIO *b, char *buf, int size) -{ - return BIO_gets(BIO_next(b), buf, size); -} - -static int tap_puts(BIO *b, const char *str) -{ - size_t m; - - if (!tap_write_ex(b, str, strlen(str), &m)) - return 0; - return m; -} diff --git a/test/tls13encryptiontest.c b/test/tls13encryptiontest.c index 84a8557e..e8614cfe 100644 --- a/test/tls13encryptiontest.c +++ b/test/tls13encryptiontest.c @@ -277,7 +277,7 @@ static int test_record(SSL3_RECORD *rec, RECORD_DATA *recd, int enc) { int ret = 0; unsigned char *refd; - size_t refdatalen; + size_t refdatalen = 0; if (enc) refd = multihexstr2buf(recd->ciphertext, &refdatalen); diff --git a/test/tls13secretstest.c b/test/tls13secretstest.c index a83fa817..1fa478e0 100644 --- a/test/tls13secretstest.c +++ b/test/tls13secretstest.c @@ -206,6 +206,13 @@ int ossl_statem_export_early_allowed(SSL *s) return 1; } +#ifndef OPENSSL_NO_QUIC +int quic_set_encryption_secrets(SSL *ssl, OSSL_ENCRYPTION_LEVEL level) +{ + return 1; +} +#endif + /* End of mocked out code */ static int test_secret(SSL *s, unsigned char *prk, diff --git a/util/err-to-raise b/util/err-to-raise index 649ca6bf..6085c32d 100755 --- a/util/err-to-raise +++ b/util/err-to-raise @@ -42,7 +42,6 @@ s/ENGINEerr\(\w+, *(\w+)\)/ERR_raise(ERR_LIB_ENGINE, $1)/; s/ESSerr\(\w+, *(\w+)\)/ERR_raise(ERR_LIB_ESS, $1)/; s/EVPerr\(\w+, *(\w+)\)/ERR_raise(ERR_LIB_EVP, $1)/; s/FIPSerr\(\w+, *(\w+)\)/ERR_raise(ERR_LIB_FIPS, $1)/; -s/HTTPerr\(\w+, *(\w+)\)/ERR_raise(ERR_LIB_HTTP, $1)/; s/KDFerr\(\w+, *(\w+)\)/ERR_raise(ERR_LIB_KDF, $1)/; s/OBJerr\(\w+, *(\w+)\)/ERR_raise(ERR_LIB_OBJ, $1)/; s/OCSPerr\(\w+, *(\w+)\)/ERR_raise(ERR_LIB_OCSP, $1)/; diff --git a/util/libcrypto.num b/util/libcrypto.num index 00e8cbbd..a94b1fa2 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -40,7 +40,7 @@ X509_NAME_delete_entry 40 3_0_0 EXIST::FUNCTION: EVP_PKEY_meth_set_verify_recover 41 3_0_0 EXIST::FUNCTION: UI_set_method 42 3_0_0 EXIST::FUNCTION: PKCS7_ISSUER_AND_SERIAL_it 43 3_0_0 EXIST::FUNCTION: -EC_GROUP_method_of 44 3_0_0 EXIST::FUNCTION:EC +EC_GROUP_method_of 44 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC RSA_blinding_on 45 3_0_0 EXIST::FUNCTION:RSA X509_get0_signature 47 3_0_0 EXIST::FUNCTION: X509_REVOKED_get0_extensions 48 3_0_0 EXIST::FUNCTION: @@ -133,7 +133,7 @@ d2i_OCSP_BASICRESP 134 3_0_0 EXIST::FUNCTION:OCSP X509v3_add_ext 135 3_0_0 EXIST::FUNCTION: X509v3_addr_subset 136 3_0_0 EXIST::FUNCTION:RFC3779 CRYPTO_strndup 137 3_0_0 EXIST::FUNCTION: -OCSP_REQ_CTX_free 138 3_0_0 EXIST::FUNCTION: +OCSP_REQ_CTX_free 138 3_0_0 EXIST::FUNCTION:OCSP X509_STORE_new 140 3_0_0 EXIST::FUNCTION: ASN1_TYPE_free 141 3_0_0 EXIST::FUNCTION: PKCS12_BAGS_new 142 3_0_0 EXIST::FUNCTION: @@ -190,7 +190,7 @@ EVP_DigestInit 193 3_0_0 EXIST::FUNCTION: EVP_PKEY_meth_find 194 3_0_0 EXIST::FUNCTION: X509_VERIFY_PARAM_get_count 195 3_0_0 EXIST::FUNCTION: ASN1_BIT_STRING_get_bit 196 3_0_0 EXIST::FUNCTION: -EVP_PKEY_cmp 197 3_0_0 EXIST::FUNCTION: +EVP_PKEY_cmp 197 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0 d2i_X509_ALGORS 198 3_0_0 EXIST::FUNCTION: EVP_PKEY2PKCS8 199 3_0_0 EXIST::FUNCTION: BN_nist_mod_256 200 3_0_0 EXIST::FUNCTION: @@ -245,7 +245,7 @@ RSA_get_ex_data 249 3_0_0 EXIST::FUNCTION:RSA EVP_PKEY_meth_get_decrypt 250 3_0_0 EXIST::FUNCTION: DES_cfb_encrypt 251 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DES CMS_SignerInfo_set1_signer_cert 252 3_0_0 EXIST::FUNCTION:CMS -X509_CRL_load_http 253 3_0_0 EXIST::FUNCTION:SOCK +X509_CRL_http_nbio 253 3_0_0 EXIST::FUNCTION:OCSP ENGINE_register_all_ciphers 254 3_0_0 EXIST::FUNCTION:ENGINE SXNET_new 255 3_0_0 EXIST::FUNCTION: EVP_camellia_256_ctr 256 3_0_0 EXIST::FUNCTION:CAMELLIA @@ -266,7 +266,7 @@ WHIRLPOOL_Init 271 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3 EVP_OpenInit 272 3_0_0 EXIST::FUNCTION:RSA OCSP_response_get1_basic 273 3_0_0 EXIST::FUNCTION:OCSP CRYPTO_gcm128_tag 274 3_0_0 EXIST::FUNCTION: -OSSL_HTTP_parse_url 275 3_0_0 EXIST::FUNCTION: +OCSP_parse_url 275 3_0_0 EXIST::FUNCTION:OCSP UI_get0_test_string 276 3_0_0 EXIST::FUNCTION: CRYPTO_secure_free 277 3_0_0 EXIST::FUNCTION: DSA_print_fp 278 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DSA,STDIO @@ -615,7 +615,7 @@ UI_get0_result_string 629 3_0_0 EXIST::FUNCTION: TS_RESP_CTX_add_policy 630 3_0_0 EXIST::FUNCTION:TS X509_REQ_dup 631 3_0_0 EXIST::FUNCTION: d2i_DSA_PUBKEY_fp 633 3_0_0 EXIST::FUNCTION:DSA,STDIO -OCSP_REQ_CTX_nbio_d2i 634 3_0_0 EXIST::FUNCTION: +OCSP_REQ_CTX_nbio_d2i 634 3_0_0 EXIST::FUNCTION:OCSP d2i_X509_REQ_fp 635 3_0_0 EXIST::FUNCTION:STDIO DH_OpenSSL 636 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,DH BN_get_rfc3526_prime_8192 637 3_0_0 EXIST::FUNCTION:DH @@ -837,7 +837,7 @@ EVP_PKEY_CTX_get_cb 857 3_0_0 EXIST::FUNCTION: X509_STORE_free 858 3_0_0 EXIST::FUNCTION: ECDSA_sign_ex 859 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC TXT_DB_insert 860 3_0_0 EXIST::FUNCTION: -EC_POINTs_make_affine 861 3_0_0 EXIST::FUNCTION:EC +EC_POINTs_make_affine 861 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC RSA_padding_add_PKCS1_PSS 862 3_0_0 EXIST::FUNCTION:RSA BF_options 863 3_0_0 EXIST::FUNCTION:BF,DEPRECATEDIN_3_0 OCSP_BASICRESP_it 864 3_0_0 EXIST::FUNCTION:OCSP @@ -1106,7 +1106,7 @@ EXTENDED_KEY_USAGE_it 1132 3_0_0 EXIST::FUNCTION: EVP_CipherInit 1133 3_0_0 EXIST::FUNCTION: PKCS12_add_safe 1134 3_0_0 EXIST::FUNCTION: ENGINE_get_digest 1135 3_0_0 EXIST::FUNCTION:ENGINE -EC_GROUP_have_precompute_mult 1136 3_0_0 EXIST::FUNCTION:EC +EC_GROUP_have_precompute_mult 1136 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC OPENSSL_gmtime 1137 3_0_0 EXIST::FUNCTION: X509_set_issuer_name 1138 3_0_0 EXIST::FUNCTION: RSA_new 1139 3_0_0 EXIST::FUNCTION:RSA @@ -1115,7 +1115,7 @@ PEM_write_bio_PKCS7 1141 3_0_0 EXIST::FUNCTION: MDC2_Final 1142 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,MDC2 SMIME_crlf_copy 1143 3_0_0 EXIST::FUNCTION: OCSP_REQUEST_get_ext_count 1144 3_0_0 EXIST::FUNCTION:OCSP -OCSP_REQ_CTX_new 1145 3_0_0 EXIST::FUNCTION: +OCSP_REQ_CTX_new 1145 3_0_0 EXIST::FUNCTION:OCSP X509_load_cert_crl_file 1146 3_0_0 EXIST::FUNCTION: EVP_PKEY_new_mac_key 1147 3_0_0 EXIST::FUNCTION: DIST_POINT_new 1148 3_0_0 EXIST::FUNCTION: @@ -1181,7 +1181,7 @@ PKCS7_add_attribute 1207 3_0_0 EXIST::FUNCTION: ENGINE_register_DSA 1208 3_0_0 EXIST::FUNCTION:ENGINE OPENSSL_LH_node_stats 1209 3_0_0 EXIST::FUNCTION:STDIO X509_policy_tree_free 1210 3_0_0 EXIST::FUNCTION: -EC_GFp_simple_method 1211 3_0_0 EXIST::FUNCTION:EC +EC_GFp_simple_method 1211 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC X509_it 1212 3_0_0 EXIST::FUNCTION: d2i_PROXY_POLICY 1213 3_0_0 EXIST::FUNCTION: MDC2_Update 1214 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,MDC2 @@ -1197,7 +1197,7 @@ X509_time_adj 1223 3_0_0 EXIST::FUNCTION: EVP_PKEY_asn1_find_str 1224 3_0_0 EXIST::FUNCTION: X509_VERIFY_PARAM_get_flags 1225 3_0_0 EXIST::FUNCTION: OPENSSL_DIR_end 1226 3_0_0 EXIST::FUNCTION: -EC_GROUP_new 1227 3_0_0 EXIST::FUNCTION:EC +EC_GROUP_new 1227 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC CMS_SignerInfo_get0_pkey_ctx 1228 3_0_0 EXIST::FUNCTION:CMS d2i_ASN1_PRINTABLESTRING 1229 3_0_0 EXIST::FUNCTION: CMS_RecipientInfo_ktri_cert_cmp 1230 3_0_0 EXIST::FUNCTION:CMS @@ -1232,7 +1232,7 @@ OPENSSL_sk_shift 1259 3_0_0 EXIST::FUNCTION: i2d_X509_REVOKED 1260 3_0_0 EXIST::FUNCTION: CMS_sign 1261 3_0_0 EXIST::FUNCTION:CMS X509_STORE_add_cert 1262 3_0_0 EXIST::FUNCTION: -EC_GROUP_precompute_mult 1263 3_0_0 EXIST::FUNCTION:EC +EC_GROUP_precompute_mult 1263 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC d2i_DISPLAYTEXT 1265 3_0_0 EXIST::FUNCTION: HMAC_CTX_copy 1266 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0 CRYPTO_gcm128_init 1267 3_0_0 EXIST::FUNCTION: @@ -1243,7 +1243,7 @@ TS_REQ_set_cert_req 1271 3_0_0 EXIST::FUNCTION:TS TXT_DB_get_by_index 1272 3_0_0 EXIST::FUNCTION: X509_check_ca 1273 3_0_0 EXIST::FUNCTION: DH_get_2048_224 1274 3_0_0 EXIST::FUNCTION:DH -X509_load_http 1275 3_0_0 EXIST::FUNCTION:SOCK +X509_http_nbio 1275 3_0_0 EXIST::FUNCTION:OCSP i2d_AUTHORITY_INFO_ACCESS 1276 3_0_0 EXIST::FUNCTION: EVP_get_cipherbyname 1277 3_0_0 EXIST::FUNCTION: CONF_dump_fp 1278 3_0_0 EXIST::FUNCTION:STDIO @@ -1379,7 +1379,7 @@ BIO_set_ex_data 1411 3_0_0 EXIST::FUNCTION: SHA512 1412 3_0_0 EXIST::FUNCTION: X509_STORE_CTX_get_explicit_policy 1413 3_0_0 EXIST::FUNCTION: EVP_DecodeBlock 1414 3_0_0 EXIST::FUNCTION: -OCSP_REQ_CTX_http 1415 3_0_0 EXIST::FUNCTION: +OCSP_REQ_CTX_http 1415 3_0_0 EXIST::FUNCTION:OCSP EVP_MD_CTX_reset 1416 3_0_0 EXIST::FUNCTION: X509_NAME_new 1417 3_0_0 EXIST::FUNCTION: ASN1_item_pack 1418 3_0_0 EXIST::FUNCTION: @@ -1577,7 +1577,7 @@ BIO_ADDRINFO_address 1613 3_0_0 EXIST::FUNCTION:SOCK ASN1_STRING_print_ex 1614 3_0_0 EXIST::FUNCTION: i2d_CMS_ReceiptRequest 1615 3_0_0 EXIST::FUNCTION:CMS d2i_TS_REQ_fp 1616 3_0_0 EXIST::FUNCTION:STDIO,TS -OCSP_REQ_CTX_i2d 1617 3_0_0 EXIST::FUNCTION: +OCSP_REQ_CTX_i2d 1617 3_0_0 EXIST::FUNCTION:OCSP EVP_PKEY_get_default_digest_nid 1618 3_0_0 EXIST::FUNCTION: ASIdOrRange_new 1619 3_0_0 EXIST::FUNCTION:RFC3779 ASN1_SCTX_new 1620 3_0_0 EXIST::FUNCTION: @@ -1593,7 +1593,7 @@ CRYPTO_ocb128_cleanup 1629 3_0_0 EXIST::FUNCTION:OCB EVP_des_ede_cbc 1630 3_0_0 EXIST::FUNCTION:DES i2d_ASN1_TIME 1631 3_0_0 EXIST::FUNCTION: ENGINE_register_all_pkey_asn1_meths 1632 3_0_0 EXIST::FUNCTION:ENGINE -OCSP_set_max_response_length 1633 3_0_0 EXIST::FUNCTION: +OCSP_set_max_response_length 1633 3_0_0 EXIST::FUNCTION:OCSP d2i_ISSUING_DIST_POINT 1634 3_0_0 EXIST::FUNCTION: CMS_RecipientInfo_set0_key 1635 3_0_0 EXIST::FUNCTION:CMS NCONF_new 1636 3_0_0 EXIST::FUNCTION: @@ -1850,7 +1850,7 @@ OCSP_ONEREQ_add_ext 1892 3_0_0 EXIST::FUNCTION:OCSP CMS_uncompress 1893 3_0_0 EXIST::FUNCTION:CMS CRYPTO_mem_debug_pop 1895 3_0_0 EXIST::FUNCTION:CRYPTO_MDEBUG,DEPRECATEDIN_3_0 EVP_aes_192_cfb128 1896 3_0_0 EXIST::FUNCTION: -OCSP_REQ_CTX_nbio 1897 3_0_0 EXIST::FUNCTION: +OCSP_REQ_CTX_nbio 1897 3_0_0 EXIST::FUNCTION:OCSP EVP_CIPHER_CTX_copy 1898 3_0_0 EXIST::FUNCTION: CRYPTO_secure_allocated 1899 3_0_0 EXIST::FUNCTION: UI_UTIL_read_pw_string 1900 3_0_0 EXIST::FUNCTION: @@ -2116,14 +2116,14 @@ EVP_MD_flags 2161 3_0_0 EXIST::FUNCTION: OPENSSL_sk_set 2162 3_0_0 EXIST::FUNCTION: OCSP_request_sign 2163 3_0_0 EXIST::FUNCTION:OCSP BN_GF2m_mod_solve_quad 2164 3_0_0 EXIST::FUNCTION:EC2M -EC_POINT_method_of 2165 3_0_0 EXIST::FUNCTION:EC +EC_POINT_method_of 2165 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC PKCS7_ENCRYPT_it 2166 3_0_0 EXIST::FUNCTION: AUTHORITY_INFO_ACCESS_it 2167 3_0_0 EXIST::FUNCTION: X509_EXTENSION_create_by_NID 2168 3_0_0 EXIST::FUNCTION: i2d_RSAPrivateKey 2169 3_0_0 EXIST::FUNCTION:RSA d2i_CERTIFICATEPOLICIES 2170 3_0_0 EXIST::FUNCTION: CMAC_CTX_get0_cipher_ctx 2171 3_0_0 EXIST::FUNCTION:CMAC,DEPRECATEDIN_3_0 -X509_STORE_load_locations 2172 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0 +X509_STORE_load_locations 2172 3_0_0 EXIST::FUNCTION: OBJ_find_sigid_algs 2173 3_0_0 EXIST::FUNCTION: TS_RESP_CTX_set_accuracy 2174 3_0_0 EXIST::FUNCTION:TS NETSCAPE_SPKI_get_pubkey 2175 3_0_0 EXIST::FUNCTION: @@ -2183,7 +2183,7 @@ POLICY_CONSTRAINTS_new 2230 3_0_0 EXIST::FUNCTION: OTHERNAME_new 2231 3_0_0 EXIST::FUNCTION: BN_rshift 2232 3_0_0 EXIST::FUNCTION: i2d_GENERAL_NAMES 2233 3_0_0 EXIST::FUNCTION: -EC_METHOD_get_field_type 2234 3_0_0 EXIST::FUNCTION:EC +EC_METHOD_get_field_type 2234 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC ENGINE_set_name 2235 3_0_0 EXIST::FUNCTION:ENGINE TS_TST_INFO_get_policy_id 2236 3_0_0 EXIST::FUNCTION:TS PKCS7_SIGNER_INFO_set 2237 3_0_0 EXIST::FUNCTION: @@ -2416,7 +2416,7 @@ Camellia_decrypt 2466 3_0_0 EXIST::FUNCTION:CAMELLIA,DEPR X509_signature_print 2467 3_0_0 EXIST::FUNCTION: EVP_camellia_128_ecb 2468 3_0_0 EXIST::FUNCTION:CAMELLIA MD2_Final 2469 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,MD2 -OCSP_REQ_CTX_add1_header 2470 3_0_0 EXIST::FUNCTION: +OCSP_REQ_CTX_add1_header 2470 3_0_0 EXIST::FUNCTION:OCSP NETSCAPE_SPKAC_it 2471 3_0_0 EXIST::FUNCTION: ASIdOrRange_free 2472 3_0_0 EXIST::FUNCTION:RFC3779 EC_POINT_get_Jprojective_coordinates_GFp 2473 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC @@ -2607,7 +2607,7 @@ EVP_PKEY_assign 2662 3_0_0 EXIST::FUNCTION: EVP_aes_128_ofb 2663 3_0_0 EXIST::FUNCTION: CMS_data 2664 3_0_0 EXIST::FUNCTION:CMS X509_load_cert_file 2665 3_0_0 EXIST::FUNCTION: -EC_GFp_nistp521_method 2667 3_0_0 EXIST::FUNCTION:EC,EC_NISTP_64_GCC_128 +EC_GFp_nistp521_method 2667 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC,EC_NISTP_64_GCC_128 ECDSA_SIG_free 2668 3_0_0 EXIST::FUNCTION:EC d2i_PKCS12_BAGS 2669 3_0_0 EXIST::FUNCTION: RSA_public_encrypt 2670 3_0_0 EXIST::FUNCTION:RSA @@ -2743,7 +2743,7 @@ CMS_dataFinal 2802 3_0_0 EXIST::FUNCTION:CMS ASN1_TIME_it 2803 3_0_0 EXIST::FUNCTION: ENGINE_get_static_state 2804 3_0_0 EXIST::FUNCTION:ENGINE EC_KEY_set_asn1_flag 2805 3_0_0 EXIST::FUNCTION:EC -EC_GFp_mont_method 2806 3_0_0 EXIST::FUNCTION:EC +EC_GFp_mont_method 2806 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC OPENSSL_asc2uni 2807 3_0_0 EXIST::FUNCTION: TS_REQ_new 2808 3_0_0 EXIST::FUNCTION:TS ENGINE_register_all_DH 2809 3_0_0 EXIST::FUNCTION:ENGINE @@ -2760,7 +2760,7 @@ CRYPTO_secure_used 2819 3_0_0 EXIST::FUNCTION: d2i_X509_CRL_INFO 2820 3_0_0 EXIST::FUNCTION: X509_CRL_get_issuer 2821 3_0_0 EXIST::FUNCTION: d2i_SCT_LIST 2822 3_0_0 EXIST::FUNCTION:CT -EC_GFp_nist_method 2823 3_0_0 EXIST::FUNCTION:EC +EC_GFp_nist_method 2823 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC SCT_free 2824 3_0_0 EXIST::FUNCTION:CT TS_TST_INFO_get_msg_imprint 2825 3_0_0 EXIST::FUNCTION:TS X509v3_addr_add_range 2826 3_0_0 EXIST::FUNCTION:RFC3779 @@ -2786,7 +2786,7 @@ ASN1_TYPE_set1 2846 3_0_0 EXIST::FUNCTION: d2i_X509_CRL_bio 2847 3_0_0 EXIST::FUNCTION: PKCS12_SAFEBAG_get1_cert 2848 3_0_0 EXIST::FUNCTION: ASN1_UNIVERSALSTRING_free 2849 3_0_0 EXIST::FUNCTION: -EC_KEY_precompute_mult 2850 3_0_0 EXIST::FUNCTION:EC +EC_KEY_precompute_mult 2850 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC CRYPTO_mem_debug_realloc 2851 3_0_0 EXIST::FUNCTION:CRYPTO_MDEBUG,DEPRECATEDIN_3_0 PKCS7_new 2852 3_0_0 EXIST::FUNCTION: BASIC_CONSTRAINTS_it 2853 3_0_0 EXIST::FUNCTION: @@ -2800,7 +2800,7 @@ X509_EXTENSION_dup 2861 3_0_0 EXIST::FUNCTION: EVP_PKEY_asn1_new 2862 3_0_0 EXIST::FUNCTION: BIO_socket_nbio 2863 3_0_0 EXIST::FUNCTION:SOCK EVP_CIPHER_set_asn1_iv 2864 3_0_0 EXIST::FUNCTION: -EC_GFp_nistp224_method 2865 3_0_0 EXIST::FUNCTION:EC,EC_NISTP_64_GCC_128 +EC_GFp_nistp224_method 2865 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC,EC_NISTP_64_GCC_128 BN_swap 2866 3_0_0 EXIST::FUNCTION: d2i_ECParameters 2867 3_0_0 EXIST::FUNCTION:EC X509_NAME_add_entry_by_OBJ 2868 3_0_0 EXIST::FUNCTION: @@ -3013,7 +3013,7 @@ X509_REQ_get_X509_PUBKEY 3077 3_0_0 EXIST::FUNCTION: ENGINE_load_private_key 3078 3_0_0 EXIST::FUNCTION:ENGINE GENERAL_NAMES_new 3079 3_0_0 EXIST::FUNCTION: i2d_POLICYQUALINFO 3080 3_0_0 EXIST::FUNCTION: -EC_GF2m_simple_method 3081 3_0_0 EXIST::FUNCTION:EC,EC2M +EC_GF2m_simple_method 3081 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC,EC2M RSA_get_method 3082 3_0_0 EXIST::FUNCTION:RSA d2i_ASRange 3083 3_0_0 EXIST::FUNCTION:RFC3779 CMS_ContentInfo_new 3084 3_0_0 EXIST::FUNCTION:CMS @@ -3318,7 +3318,7 @@ EVP_camellia_256_cfb1 3385 3_0_0 EXIST::FUNCTION:CAMELLIA CRYPTO_secure_actual_size 3387 3_0_0 EXIST::FUNCTION: COMP_CTX_free 3388 3_0_0 EXIST::FUNCTION:COMP i2d_PBE2PARAM 3389 3_0_0 EXIST::FUNCTION: -EC_POINT_make_affine 3390 3_0_0 EXIST::FUNCTION:EC +EC_POINT_make_affine 3390 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC DSA_generate_parameters 3391 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_0_9_8,DSA ASN1_BIT_STRING_num_asc 3392 3_0_0 EXIST::FUNCTION: X509_INFO_free 3394 3_0_0 EXIST::FUNCTION: @@ -3376,7 +3376,7 @@ ERR_get_next_error_library 3446 3_0_0 EXIST::FUNCTION: OCSP_RESPONSE_print 3447 3_0_0 EXIST::FUNCTION:OCSP BN_get_rfc3526_prime_2048 3448 3_0_0 EXIST::FUNCTION:DH BIO_new_bio_pair 3449 3_0_0 EXIST::FUNCTION: -EC_GFp_nistp256_method 3450 3_0_0 EXIST::FUNCTION:EC,EC_NISTP_64_GCC_128 +EC_GFp_nistp256_method 3450 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0,EC,EC_NISTP_64_GCC_128 BIO_method_type 3451 3_0_0 EXIST::FUNCTION: ECPKParameters_print 3452 3_0_0 EXIST::FUNCTION:EC EVP_rc4 3453 3_0_0 EXIST::FUNCTION:RC4 @@ -3461,7 +3461,7 @@ ERR_print_errors_cb 3531 3_0_0 EXIST::FUNCTION: ENGINE_set_default_string 3532 3_0_0 EXIST::FUNCTION:ENGINE BIO_number_read 3533 3_0_0 EXIST::FUNCTION: CRYPTO_zalloc 3534 3_0_0 EXIST::FUNCTION: -EVP_PKEY_cmp_parameters 3535 3_0_0 EXIST::FUNCTION: +EVP_PKEY_cmp_parameters 3535 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0 EVP_PKEY_CTX_new_id 3537 3_0_0 EXIST::FUNCTION: TLS_FEATURE_free 3538 3_0_0 EXIST::FUNCTION: d2i_BASIC_CONSTRAINTS 3539 3_0_0 EXIST::FUNCTION: @@ -3762,7 +3762,7 @@ i2d_PrivateKey_bio 3843 3_0_0 EXIST::FUNCTION: RSA_padding_add_PKCS1_type_1 3844 3_0_0 EXIST::FUNCTION:RSA i2d_re_X509_tbs 3845 3_0_0 EXIST::FUNCTION: EVP_CIPHER_iv_length 3846 3_0_0 EXIST::FUNCTION: -OCSP_REQ_CTX_get0_mem_bio 3847 3_0_0 EXIST::FUNCTION: +OCSP_REQ_CTX_get0_mem_bio 3847 3_0_0 EXIST::FUNCTION:OCSP i2d_PKCS8PrivateKeyInfo_bio 3848 3_0_0 EXIST::FUNCTION: d2i_OCSP_CERTID 3849 3_0_0 EXIST::FUNCTION:OCSP EVP_CIPHER_meth_set_init 3850 3_0_0 EXIST::FUNCTION: @@ -4425,10 +4425,10 @@ OCSP_resp_get0_respdata 4530 3_0_0 EXIST::FUNCTION:OCSP EVP_MD_CTX_set_pkey_ctx 4531 3_0_0 EXIST::FUNCTION: EVP_PKEY_meth_set_digest_custom 4532 3_0_0 EXIST::FUNCTION: EVP_PKEY_meth_get_digest_custom 4533 3_0_0 EXIST::FUNCTION: -EVP_MAC_CTX_new ? 3_0_0 EXIST::FUNCTION: -EVP_MAC_CTX_free ? 3_0_0 EXIST::FUNCTION: -EVP_MAC_CTX_dup ? 3_0_0 EXIST::FUNCTION: -EVP_MAC_CTX_mac ? 3_0_0 EXIST::FUNCTION: +EVP_MAC_new_ctx ? 3_0_0 EXIST::FUNCTION: +EVP_MAC_free_ctx ? 3_0_0 EXIST::FUNCTION: +EVP_MAC_dup_ctx ? 3_0_0 EXIST::FUNCTION: +EVP_MAC_get_ctx_mac ? 3_0_0 EXIST::FUNCTION: EVP_MAC_size ? 3_0_0 EXIST::FUNCTION: EVP_MAC_init ? 3_0_0 EXIST::FUNCTION: EVP_MAC_update ? 3_0_0 EXIST::FUNCTION: @@ -4467,7 +4467,7 @@ ASYNC_WAIT_CTX_set_callback ? 3_0_0 EXIST::FUNCTION: ASYNC_WAIT_CTX_set_status ? 3_0_0 EXIST::FUNCTION: ASYNC_WAIT_CTX_get_status ? 3_0_0 EXIST::FUNCTION: ERR_load_ESS_strings ? 3_0_0 EXIST::FUNCTION: -EVP_KDF_CTX_free ? 3_0_0 EXIST::FUNCTION: +EVP_KDF_free_ctx ? 3_0_0 EXIST::FUNCTION: EVP_KDF_reset ? 3_0_0 EXIST::FUNCTION: EVP_KDF_size ? 3_0_0 EXIST::FUNCTION: EVP_KDF_derive ? 3_0_0 EXIST::FUNCTION: @@ -4509,6 +4509,7 @@ OSSL_CRMF_PBMPARAMETER_new ? 3_0_0 EXIST::FUNCTION:CRMF OSSL_CRMF_PBMPARAMETER_it ? 3_0_0 EXIST::FUNCTION:CRMF d2i_OSSL_CRMF_CERTID ? 3_0_0 EXIST::FUNCTION:CRMF i2d_OSSL_CRMF_CERTID ? 3_0_0 EXIST::FUNCTION:CRMF +OSSL_CRMF_CERTID_dup ? 3_0_0 EXIST::FUNCTION:CRMF OSSL_CRMF_CERTID_free ? 3_0_0 EXIST::FUNCTION:CRMF OSSL_CRMF_CERTID_new ? 3_0_0 EXIST::FUNCTION:CRMF OSSL_CRMF_CERTID_it ? 3_0_0 EXIST::FUNCTION:CRMF @@ -4616,8 +4617,8 @@ EVP_CIPHER_up_ref ? 3_0_0 EXIST::FUNCTION: EVP_CIPHER_fetch ? 3_0_0 EXIST::FUNCTION: EVP_CIPHER_mode ? 3_0_0 EXIST::FUNCTION: OPENSSL_info ? 3_0_0 EXIST::FUNCTION: -EVP_KDF_CTX_new ? 3_0_0 EXIST::FUNCTION: -EVP_KDF_CTX_kdf ? 3_0_0 EXIST::FUNCTION: +EVP_KDF_new_ctx ? 3_0_0 EXIST::FUNCTION: +EVP_KDF_get_ctx_kdf ? 3_0_0 EXIST::FUNCTION: i2d_KeyParams ? 3_0_0 EXIST::FUNCTION: d2i_KeyParams ? 3_0_0 EXIST::FUNCTION: i2d_KeyParams_bio ? 3_0_0 EXIST::FUNCTION: @@ -4682,7 +4683,6 @@ ERR_set_error ? 3_0_0 EXIST::FUNCTION: ERR_vset_error ? 3_0_0 EXIST::FUNCTION: X509_get0_authority_issuer ? 3_0_0 EXIST::FUNCTION: X509_get0_authority_serial ? 3_0_0 EXIST::FUNCTION: -EC_GROUP_new_ex ? 3_0_0 EXIST::FUNCTION:EC EC_GROUP_new_by_curve_name_ex ? 3_0_0 EXIST::FUNCTION:EC EC_KEY_new_ex ? 3_0_0 EXIST::FUNCTION:EC EC_KEY_new_by_curve_name_ex ? 3_0_0 EXIST::FUNCTION:EC @@ -4701,8 +4701,8 @@ EVP_CIPHER_gettable_ctx_params ? 3_0_0 EXIST::FUNCTION: EVP_MD_get_params ? 3_0_0 EXIST::FUNCTION: EVP_MAC_fetch ? 3_0_0 EXIST::FUNCTION: EVP_MAC_settable_ctx_params ? 3_0_0 EXIST::FUNCTION: -EVP_MAC_CTX_set_params ? 3_0_0 EXIST::FUNCTION: -EVP_MAC_CTX_get_params ? 3_0_0 EXIST::FUNCTION: +EVP_MAC_set_ctx_params ? 3_0_0 EXIST::FUNCTION: +EVP_MAC_get_ctx_params ? 3_0_0 EXIST::FUNCTION: EVP_MAC_gettable_ctx_params ? 3_0_0 EXIST::FUNCTION: EVP_MAC_free ? 3_0_0 EXIST::FUNCTION: EVP_MAC_up_ref ? 3_0_0 EXIST::FUNCTION: @@ -4715,11 +4715,11 @@ EVP_CIPHER_free ? 3_0_0 EXIST::FUNCTION: EVP_KDF_up_ref ? 3_0_0 EXIST::FUNCTION: EVP_KDF_free ? 3_0_0 EXIST::FUNCTION: EVP_KDF_fetch ? 3_0_0 EXIST::FUNCTION: -EVP_KDF_CTX_dup ? 3_0_0 EXIST::FUNCTION: +EVP_KDF_dup_ctx ? 3_0_0 EXIST::FUNCTION: EVP_KDF_provider ? 3_0_0 EXIST::FUNCTION: EVP_KDF_get_params ? 3_0_0 EXIST::FUNCTION: -EVP_KDF_CTX_get_params ? 3_0_0 EXIST::FUNCTION: -EVP_KDF_CTX_set_params ? 3_0_0 EXIST::FUNCTION: +EVP_KDF_get_ctx_params ? 3_0_0 EXIST::FUNCTION: +EVP_KDF_set_ctx_params ? 3_0_0 EXIST::FUNCTION: EVP_KDF_gettable_params ? 3_0_0 EXIST::FUNCTION: EVP_KDF_gettable_ctx_params ? 3_0_0 EXIST::FUNCTION: EVP_KDF_settable_ctx_params ? 3_0_0 EXIST::FUNCTION: @@ -4755,10 +4755,10 @@ OSSL_CMP_CTX_get_option ? 3_0_0 EXIST::FUNCTION:CMP OSSL_CMP_CTX_set_log_cb ? 3_0_0 EXIST::FUNCTION:CMP OSSL_CMP_CTX_print_errors ? 3_0_0 EXIST::FUNCTION:CMP OSSL_CMP_CTX_set1_serverPath ? 3_0_0 EXIST::FUNCTION:CMP -OSSL_CMP_CTX_set1_server ? 3_0_0 EXIST::FUNCTION:CMP +OSSL_CMP_CTX_set1_serverName ? 3_0_0 EXIST::FUNCTION:CMP OSSL_CMP_CTX_set_serverPort ? 3_0_0 EXIST::FUNCTION:CMP -OSSL_CMP_CTX_set1_proxy ? 3_0_0 EXIST::FUNCTION:CMP -OSSL_CMP_CTX_set1_no_proxy ? 3_0_0 EXIST::FUNCTION:CMP +OSSL_CMP_CTX_set1_proxyName ? 3_0_0 EXIST::FUNCTION:CMP +OSSL_CMP_CTX_set_proxyPort ? 3_0_0 EXIST::FUNCTION:CMP OSSL_CMP_CTX_set_http_cb ? 3_0_0 EXIST::FUNCTION:CMP OSSL_CMP_CTX_set_http_cb_arg ? 3_0_0 EXIST::FUNCTION:CMP OSSL_CMP_CTX_get_http_cb_arg ? 3_0_0 EXIST::FUNCTION:CMP @@ -4924,15 +4924,11 @@ EVP_PKEY_pairwise_check ? 3_0_0 EXIST::FUNCTION: ASN1_item_verify_ctx ? 3_0_0 EXIST::FUNCTION: RAND_DRBG_set_callback_data ? 3_0_0 EXIST::FUNCTION: RAND_DRBG_get_callback_data ? 3_0_0 EXIST::FUNCTION: -BIO_socket_wait ? 3_0_0 EXIST::FUNCTION:SOCK -BIO_wait ? 3_0_0 EXIST::FUNCTION: -BIO_connect_retry ? 3_0_0 EXIST::FUNCTION: -ERR_load_HTTP_strings ? 3_0_0 EXIST::FUNCTION: -OSSL_HTTP_get ? 3_0_0 EXIST::FUNCTION: -OSSL_HTTP_get_asn1 ? 3_0_0 EXIST::FUNCTION: -OSSL_HTTP_post_asn1 ? 3_0_0 EXIST::FUNCTION: -OSSL_HTTP_transfer ? 3_0_0 EXIST::FUNCTION: -OSSL_HTTP_proxy_connect ? 3_0_0 EXIST::FUNCTION: +OSSL_HTTP_get ? 3_0_0 NOEXIST::FUNCTION:SOCK +OSSL_HTTP_get_asn1 ? 3_0_0 NOEXIST::FUNCTION:SOCK +OSSL_HTTP_post_asn1 ? 3_0_0 NOEXIST::FUNCTION:SOCK +OSSL_HTTP_transfer ? 3_0_0 NOEXIST::FUNCTION:SOCK +OSSL_HTTP_proxy_connect ? 3_0_0 NOEXIST::FUNCTION:SOCK ERR_add_error_txt ? 3_0_0 EXIST::FUNCTION: ERR_add_error_mem_bio ? 3_0_0 EXIST::FUNCTION: X509_STORE_CTX_print_verify_cb ? 3_0_0 EXIST::FUNCTION: @@ -4994,7 +4990,6 @@ OSSL_CMP_try_certreq ? 3_0_0 EXIST::FUNCTION:CMP OSSL_CMP_certConf_cb ? 3_0_0 EXIST::FUNCTION:CMP OSSL_CMP_exec_RR_ses ? 3_0_0 EXIST::FUNCTION:CMP OSSL_CMP_exec_GENM_ses ? 3_0_0 EXIST::FUNCTION:CMP -OSSL_CMP_MSG_http_perform ? 3_0_0 EXIST::FUNCTION:CMP EVP_PKEY_gen ? 3_0_0 EXIST::FUNCTION: EVP_PKEY_CTX_set_rsa_keygen_bits ? 3_0_0 EXIST::FUNCTION:RSA EVP_PKEY_CTX_set_rsa_keygen_pubexp ? 3_0_0 EXIST::FUNCTION:RSA @@ -5092,4 +5087,11 @@ OSSL_STORE_LOADER_set_attach ? 3_0_0 EXIST::FUNCTION: EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen ? 3_0_0 EXIST::FUNCTION:RSA EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md ? 3_0_0 EXIST::FUNCTION:RSA EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md_name ? 3_0_0 EXIST::FUNCTION:RSA +OSSL_PROVIDER_do_all ? 3_0_0 EXIST::FUNCTION: +EC_GROUP_get_field_type ? 3_0_0 EXIST::FUNCTION:EC +X509_PUBKEY_eq ? 3_0_0 EXIST::FUNCTION: +EVP_PKEY_eq ? 3_0_0 EXIST::FUNCTION: +EVP_PKEY_parameters_eq ? 3_0_0 EXIST::FUNCTION: +OSSL_PROVIDER_query_operation ? 3_0_0 EXIST::FUNCTION: +OSSL_PROVIDER_get0_provider_ctx ? 3_0_0 EXIST::FUNCTION: EVP_chacha20_poly1305_draft ? 3_0_0 EXIST::FUNCTION:CHACHA,POLY1305 diff --git a/util/libssl.num b/util/libssl.num index fc563ef8..f63e56f4 100644 --- a/util/libssl.num +++ b/util/libssl.num @@ -354,7 +354,7 @@ SSL_set_session_id_context 354 3_0_0 EXIST::FUNCTION: SSL_new 355 3_0_0 EXIST::FUNCTION: TLSv1_1_method 356 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_1_1_0,TLS1_1_METHOD SSL_CTX_get_cert_store 357 3_0_0 EXIST::FUNCTION: -SSL_CTX_load_verify_locations 358 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0 +SSL_CTX_load_verify_locations 358 3_0_0 EXIST::FUNCTION: SSL_SESSION_print_fp 359 3_0_0 EXIST::FUNCTION:STDIO SSL_get0_dane_tlsa 360 3_0_0 EXIST::FUNCTION: SSL_CTX_set_generate_session_id 361 3_0_0 EXIST::FUNCTION: @@ -515,3 +515,14 @@ SSL_CTX_set_tlsext_ticket_key_evp_cb ? 3_0_0 EXIST::FUNCTION: SSL_CTX_new_with_libctx ? 3_0_0 EXIST::FUNCTION: SSL_new_session_ticket ? 3_0_0 EXIST::FUNCTION: SSL_CTX_set_timeout_tls13 ? 3_0_0 EXIST::FUNCTION: +SSL_CTX_set_quic_method ? 3_0_0 EXIST::FUNCTION:QUIC +SSL_set_quic_method ? 3_0_0 EXIST::FUNCTION:QUIC +SSL_set_quic_transport_params ? 3_0_0 EXIST::FUNCTION:QUIC +SSL_get_peer_quic_transport_params ? 3_0_0 EXIST::FUNCTION:QUIC +SSL_quic_max_handshake_flight_len ? 3_0_0 EXIST::FUNCTION:QUIC +SSL_quic_read_level ? 3_0_0 EXIST::FUNCTION:QUIC +SSL_quic_write_level ? 3_0_0 EXIST::FUNCTION:QUIC +SSL_provide_quic_data ? 3_0_0 EXIST::FUNCTION:QUIC +SSL_process_quic_post_handshake ? 3_0_0 EXIST::FUNCTION:QUIC +SSL_is_quic ? 3_0_0 EXIST::FUNCTION:QUIC +SSL_CIPHER_get_prf_nid ? 3_0_0 EXIST::FUNCTION: diff --git a/util/missingcrypto.txt b/util/missingcrypto.txt index 3473a869..fe5deafa 100644 --- a/util/missingcrypto.txt +++ b/util/missingcrypto.txt @@ -629,7 +629,6 @@ ERR_load_ENGINE_strings(3) ERR_load_ERR_strings(3) ERR_load_ESS_strings(3) ERR_load_EVP_strings(3) -ERR_load_HTTP_strings(3) ERR_load_KDF_strings(3) ERR_load_OBJ_strings(3) ERR_load_OCSP_strings(3) @@ -738,7 +737,6 @@ IPAddressChoice_it(3) IPAddressFamily_it(3) IPAddressOrRange_it(3) IPAddressRange_it(3) -ISSUING_DIST_POINT_it(3) LONG_it(3) MD2_options(3) MD4_Transform(3) @@ -910,6 +908,7 @@ OPENSSL_strnlen(3) OPENSSL_uni2asc(3) OPENSSL_uni2utf8(3) OPENSSL_utf82uni(3) +OSSL_CMP_MSG_http_perform(3) OSSL_SERIALIZER-DH(7) OSSL_SERIALIZER-DSA(7) OSSL_SERIALIZER-EC(7) @@ -1315,7 +1314,6 @@ X509V3_set_ctx(3) X509V3_set_nconf(3) X509V3_string_free(3) X509_ALGORS_it(3) -X509_ALGOR_it(3) X509_ATTRIBUTE_count(3) X509_ATTRIBUTE_create(3) X509_ATTRIBUTE_create_by_NID(3) @@ -1337,6 +1335,7 @@ X509_CRL_diff(3) X509_CRL_get_lastUpdate(3) X509_CRL_get_meth_data(3) X509_CRL_get_nextUpdate(3) +X509_CRL_http_nbio(3) X509_CRL_it(3) X509_CRL_print(3) X509_CRL_print_ex(3) @@ -1471,6 +1470,7 @@ X509_get_default_private_dir(3) X509_get_pubkey_parameters(3) X509_get_signature_type(3) X509_gmtime_adj(3) +X509_http_nbio(3) X509_issuer_and_serial_hash(3) X509_issuer_name_hash(3) X509_issuer_name_hash_old(3) @@ -1572,7 +1572,6 @@ i2v_ASN1_BIT_STRING(3) i2v_GENERAL_NAME(3) i2v_GENERAL_NAMES(3) o2i_ECPublicKey(3) -openssl-core_numbers.h(7) provider-kdf(7) v2i_ASN1_BIT_STRING(3) v2i_GENERAL_NAME(3) diff --git a/util/mkpod2html.pl b/util/mkpod2html.pl index 9e81d366..2df4b22b 100755 --- a/util/mkpod2html.pl +++ b/util/mkpod2html.pl @@ -45,7 +45,7 @@ close F; unlink $opt_o; $contents =~ - s|href="http://man\.he\.net/(man\d/[^"]+)(?:\.html)?"|href="../$1.html|g; + s|href="http://man\.he\.net/(man\d/[^"]+)(?:\.html)?"|href="../$1.html"|g; open F, ">$opt_o" or die "Can't write $opt_o, $!"; print F $contents; diff --git a/util/other.syms b/util/other.syms index d9934859..be725fd0 100644 --- a/util/other.syms +++ b/util/other.syms @@ -39,7 +39,6 @@ GEN_SESSION_CB datatype OPENSSL_Applink external OPENSSL_CTX datatype NAMING_AUTHORITY datatype -OSSL_HTTP_bio_cb_t datatype OSSL_PARAM datatype OSSL_PROVIDER datatype OSSL_SERIALIZER datatype @@ -320,7 +319,6 @@ EVP_rc5_32_12_16_cfb define EVP_seed_cfb define EVP_sm4_cfb define OBJ_cleanup define deprecated 1.1.0 -OCSP_parse_url define OPENSSL_FILE define OPENSSL_FUNC define OPENSSL_LINE define @@ -359,6 +357,7 @@ OpenSSL_add_all_digests define deprecated 1.1.0 OpenSSL_add_ssl_algorithms define OSSL_CMP_CTX_set_log_verbosity define OSSL_CMP_CR define +OSSL_CMP_DEFAULT_PORT define OSSL_CMP_IR define OSSL_CMP_KUR define OSSL_CMP_LOG_ALERT define @@ -375,6 +374,7 @@ OSSL_CMP_P10CR define OSSL_CMP_certConf_cb_t datatype OSSL_CMP_log_cb_t datatype OSSL_CMP_severity datatype +OSSL_CMP_http_cb_t datatype OSSL_CMP_transfer_cb_t datatype OSSL_CMP_SRV_cert_request_cb_t datatype OSSL_CMP_SRV_rr_cb_t datatype @@ -561,8 +561,6 @@ SSLv23_client_method define SSLv23_method define SSLv23_server_method define TLS_DEFAULT_CIPHERSUITES define deprecated 3.0.0 -X509_CRL_http_nbio define -X509_http_nbio define X509_LOOKUP_add_dir define X509_LOOKUP_add_store define X509_LOOKUP_load_file define diff --git a/util/perl/OpenSSL/Test.pm b/util/perl/OpenSSL/Test.pm index 8d2894e7..b40283fe 100644 --- a/util/perl/OpenSSL/Test.pm +++ b/util/perl/OpenSSL/Test.pm @@ -35,6 +35,8 @@ OpenSSL::Test - a private extension of Test::More setup("my_test_name"); + plan tests => 2; + ok(run(app(["openssl", "version"])), "check for openssl presence"); indir "subdir" => sub {