1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-23 08:38:49 -05:00

schannel: add support for CURLOPT_CAINFO

- Move verify_certificate functionality in schannel.c into a new
  file called schannel_verify.c. Additionally, some structure defintions
  from schannel.c have been moved to schannel.h to allow them to be
  used in schannel_verify.c.

- Make verify_certificate functionality for Schannel available on
  all versions of Windows instead of just Windows CE. verify_certificate
  will be invoked on Windows CE or when the user specifies
  CURLOPT_CAINFO and CURLOPT_SSL_VERIFYPEER.

- In verify_certificate, create a custom certificate chain engine that
  exclusively trusts the certificate store backed by the CURLOPT_CAINFO
  file.

- doc updates of --cacert/CAINFO support for schannel

- Use CERT_NAME_SEARCH_ALL_NAMES_FLAG when invoking CertGetNameString
  when available. This implements a TODO in schannel.c to improve
  handling of multiple SANs in a certificate. In particular, all SANs
  will now be searched instead of just the first name.

- Update tool_operate.c to not search for the curl-ca-bundle.crt file
  when using Schannel to maintain backward compatibility. Previously,
  any curl-ca-bundle.crt file found in that search would have been
  ignored by Schannel. But, with CAINFO support, the file found by
  that search would have been used as the certificate store and
  could cause issues for any users that have curl-ca-bundle.crt in
  the search path.

- Update url.c to not set the build time CURL_CA_BUNDLE if the selected
  SSL backend is Schannel. We allow setting CA location for schannel
  only when explicitly specified by the user via CURLOPT_CAINFO /
  --cacert.

- Add new test cases 3000 and 3001. These test cases check that the first
  and last SAN, respectively, matches the connection hostname. New test
  certificates have been added for these cases. For 3000, the certificate
  prefix is Server-localhost-firstSAN and for 3001, the certificate
  prefix is Server-localhost-secondSAN.

- Remove TODO 15.2 (Add support for custom server certificate
  validation), this commit addresses it.

Closes https://github.com/curl/curl/pull/1325
This commit is contained in:
Dan McNulty 2017-03-10 14:27:30 -06:00 committed by Jay Satiro
parent 4d660fdcb0
commit 8996300211
37 changed files with 1406 additions and 258 deletions

View File

@ -121,7 +121,6 @@
15. WinSSL/SChannel 15. WinSSL/SChannel
15.1 Add support for client certificate authentication 15.1 Add support for client certificate authentication
15.2 Add support for custom server certificate validation
15.3 Add support for the --ciphers option 15.3 Add support for the --ciphers option
16. SASL 16. SASL
@ -823,17 +822,6 @@ that doesn't exist on the server, just like --ftp-create-dirs.
- Getting a Certificate for Schannel - Getting a Certificate for Schannel
https://msdn.microsoft.com/en-us/library/windows/desktop/aa375447.aspx https://msdn.microsoft.com/en-us/library/windows/desktop/aa375447.aspx
15.2 Add support for custom server certificate validation
WinSSL/SChannel currently makes use of the OS-level system and user
certificate trust store. This does not allow the application or user to
customize the server certificate validation process using curl or libcurl.
Therefore support for the existing --cacert or --capath options should be
implemented by supplying a custom certificate to the SChannel APIs, see:
- Getting a Certificate for Schannel
https://msdn.microsoft.com/en-us/library/windows/desktop/aa375447.aspx
15.3 Add support for the --ciphers option 15.3 Add support for the --ciphers option
The cipher suites used by WinSSL/SChannel are configured on an OS-level The cipher suites used by WinSSL/SChannel are configured on an OS-level

View File

@ -25,4 +25,9 @@ should not be set. If the option is not set, then curl will use the
certificates in the system and user Keychain to verify the peer, which is the certificates in the system and user Keychain to verify the peer, which is the
preferred method of verifying the peer's certificate chain. preferred method of verifying the peer's certificate chain.
(Schannel/WinSSL only) This option is supported for WinSSL in Windows 7 or
later with libcurl 7.60 or later. This option is supported for backward
compatibility with other SSL engines; instead it is recommended to use Windows'
store of root certificates (the default for WinSSL).
If this option is used several times, the last one will be used. If this option is used several times, the last one will be used.

View File

@ -52,6 +52,11 @@ should not be set. If the option is not set, then curl will use the
certificates in the system and user Keychain to verify the peer, which is the certificates in the system and user Keychain to verify the peer, which is the
preferred method of verifying the peer's certificate chain. preferred method of verifying the peer's certificate chain.
(Schannel/WinSSL only) This option is supported for WinSSL in Windows 7 or
later with libcurl 7.60 or later. This option is supported for backward
compatibility with other SSL engines; instead it is recommended to use Windows'
store of root certificates (the default for WinSSL).
The application does not have to keep the string around after setting this The application does not have to keep the string around after setting this
option. option.
.SH DEFAULT .SH DEFAULT

View File

@ -29,8 +29,8 @@ LIB_VAUTH_HFILES = vauth/vauth.h vauth/digest.h vauth/ntlm.h
LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \ LIB_VTLS_CFILES = vtls/openssl.c vtls/gtls.c vtls/vtls.c vtls/nss.c \
vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c \ vtls/polarssl.c vtls/polarssl_threadlock.c vtls/axtls.c \
vtls/cyassl.c vtls/schannel.c vtls/darwinssl.c vtls/gskit.c \ vtls/cyassl.c vtls/schannel.c vtls/schannel_verify.c \
vtls/mbedtls.c vtls/darwinssl.c vtls/gskit.c vtls/mbedtls.c
LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \ LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h \ vtls/nssg.h vtls/polarssl.h vtls/polarssl_threadlock.h vtls/axtls.h \

View File

@ -25,7 +25,7 @@
#if defined(USE_OPENSSL) \ #if defined(USE_OPENSSL) \
|| defined(USE_AXTLS) \ || defined(USE_AXTLS) \
|| defined(USE_GSKIT) \ || defined(USE_GSKIT) \
|| (defined(USE_SCHANNEL) && defined(_WIN32_WCE)) || defined(USE_SCHANNEL)
/* these backends use functions from this file */ /* these backends use functions from this file */
#ifdef HAVE_NETINET_IN_H #ifdef HAVE_NETINET_IN_H

View File

@ -488,13 +488,20 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
set->socks5_gssapi_nec = FALSE; set->socks5_gssapi_nec = FALSE;
#endif #endif
/* This is our preferred CA cert bundle/path since install time */ /* Set the default CA cert bundle/path detected/specified at build time.
*
* If Schannel (WinSSL) is the selected SSL backend then these locations
* are ignored. We allow setting CA location for schannel only when
* explicitly specified by the user via CURLOPT_CAINFO / --cacert.
*/
if(Curl_ssl_backend() != CURLSSLBACKEND_SCHANNEL) {
#if defined(CURL_CA_BUNDLE) #if defined(CURL_CA_BUNDLE)
result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE); result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_ORIG], CURL_CA_BUNDLE);
if(result) if(result)
return result; return result;
result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_PROXY], CURL_CA_BUNDLE); result = Curl_setstropt(&set->str[STRING_SSL_CAFILE_PROXY],
CURL_CA_BUNDLE);
if(result) if(result)
return result; return result;
#endif #endif
@ -507,6 +514,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
if(result) if(result)
return result; return result;
#endif #endif
}
set->wildcard_enabled = FALSE; set->wildcard_enabled = FALSE;
set->chunk_bgn = ZERO_NULL; set->chunk_bgn = ZERO_NULL;

View File

@ -42,13 +42,12 @@
#ifdef USE_SCHANNEL #ifdef USE_SCHANNEL
#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS
#ifndef USE_WINDOWS_SSPI #ifndef USE_WINDOWS_SSPI
# error "Can't compile SCHANNEL support without SSPI." # error "Can't compile SCHANNEL support without SSPI."
#endif #endif
#include <schnlsp.h>
#include <schannel.h>
#include "curl_sspi.h"
#include "schannel.h" #include "schannel.h"
#include "vtls.h" #include "vtls.h"
#include "sendf.h" #include "sendf.h"
@ -61,7 +60,6 @@
#include "x509asn1.h" #include "x509asn1.h"
#include "curl_printf.h" #include "curl_printf.h"
#include "system_win32.h" #include "system_win32.h"
#include "hostcheck.h"
/* The last #include file should be: */ /* The last #include file should be: */
#include "curl_memory.h" #include "curl_memory.h"
@ -142,37 +140,6 @@
# define CALG_SHA_256 0x0000800c # define CALG_SHA_256 0x0000800c
#endif #endif
/* Structs to store Schannel handles */
struct curl_schannel_cred {
CredHandle cred_handle;
TimeStamp time_stamp;
int refcount;
};
struct curl_schannel_ctxt {
CtxtHandle ctxt_handle;
TimeStamp time_stamp;
};
struct ssl_backend_data {
struct curl_schannel_cred *cred;
struct curl_schannel_ctxt *ctxt;
SecPkgContext_StreamSizes stream_sizes;
size_t encdata_length, decdata_length;
size_t encdata_offset, decdata_offset;
unsigned char *encdata_buffer, *decdata_buffer;
/* encdata_is_incomplete: if encdata contains only a partial record that
can't be decrypted without another Curl_read_plain (that is, status is
SEC_E_INCOMPLETE_MESSAGE) then set this true. after Curl_read_plain writes
more bytes into encdata then set this back to false. */
bool encdata_is_incomplete;
unsigned long req_flags, ret_flags;
CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
bool recv_sspi_close_notify; /* true if connection closed by close_notify */
bool recv_connection_closed; /* true if connection closed, regardless how */
bool use_alpn; /* true if ALPN is used for this connection */
};
#define BACKEND connssl->backend #define BACKEND connssl->backend
static Curl_recv schannel_recv; static Curl_recv schannel_recv;
@ -181,10 +148,6 @@ static Curl_send schannel_send;
static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex, static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex,
const char *pinnedpubkey); const char *pinnedpubkey);
#ifdef _WIN32_WCE
static CURLcode verify_certificate(struct connectdata *conn, int sockindex);
#endif
static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType, static void InitSecBuffer(SecBuffer *buffer, unsigned long BufType,
void *BufDataPtr, unsigned long BufByteSize) void *BufDataPtr, unsigned long BufByteSize)
{ {
@ -335,6 +298,26 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
BACKEND->use_alpn = false; BACKEND->use_alpn = false;
#endif #endif
#ifdef _WIN32_WCE
/* certificate validation on CE doesn't seem to work right; we'll
* do it following a more manual process. */
BACKEND->use_manual_cred_validation = true;
#else
if(SSL_CONN_CONFIG(CAfile)) {
if(Curl_verify_windows_version(6, 1, PLATFORM_WINNT,
VERSION_GREATER_THAN_EQUAL)) {
BACKEND->use_manual_cred_validation = true;
}
else {
failf(data, "schannel: this version of Windows is too old to support "
"certificate verification via CA bundle file.");
return CURLE_SSL_CACERT_BADFILE;
}
}
else
BACKEND->use_manual_cred_validation = false;
#endif
BACKEND->cred = NULL; BACKEND->cred = NULL;
/* check for an existing re-usable credential handle */ /* check for an existing re-usable credential handle */
@ -358,27 +341,24 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
if(conn->ssl_config.verifypeer) { if(conn->ssl_config.verifypeer) {
#ifdef _WIN32_WCE if(BACKEND->use_manual_cred_validation)
/* certificate validation on CE doesn't seem to work right; we'll schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION;
do it following a more manual process. */ else
schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
SCH_CRED_IGNORE_REVOCATION_OFFLINE;
#else
schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION; schannel_cred.dwFlags = SCH_CRED_AUTO_CRED_VALIDATION;
/* TODO s/data->set.ssl.no_revoke/SSL_SET_OPTION(no_revoke)/g */ /* TODO s/data->set.ssl.no_revoke/SSL_SET_OPTION(no_revoke)/g */
if(data->set.ssl.no_revoke) if(data->set.ssl.no_revoke) {
schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK | schannel_cred.dwFlags |= SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
SCH_CRED_IGNORE_REVOCATION_OFFLINE; SCH_CRED_IGNORE_REVOCATION_OFFLINE;
else
schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
#endif
if(data->set.ssl.no_revoke)
infof(data, "schannel: disabled server certificate revocation " infof(data, "schannel: disabled server certificate revocation "
"checks\n"); "checks\n");
else }
else {
schannel_cred.dwFlags |= SCH_CRED_REVOCATION_CHECK_CHAIN;
infof(data, "schannel: checking server certificate revocation\n"); infof(data, "schannel: checking server certificate revocation\n");
} }
}
else { else {
schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | schannel_cred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION |
SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_NO_REVOCATION_CHECK |
@ -898,12 +878,9 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)
} }
} }
#ifdef _WIN32_WCE if(conn->ssl_config.verifypeer && BACKEND->use_manual_cred_validation) {
/* Windows CE doesn't do any server certificate validation.
We have to do it manually. */
if(conn->ssl_config.verifypeer)
return verify_certificate(conn, sockindex); return verify_certificate(conn, sockindex);
#endif }
return CURLE_OK; return CURLE_OK;
} }
@ -1868,146 +1845,6 @@ static CURLcode pkp_pin_peer_pubkey(struct connectdata *conn, int sockindex,
return result; return result;
} }
#ifdef _WIN32_WCE
static CURLcode verify_certificate(struct connectdata *conn, int sockindex)
{
SECURITY_STATUS status;
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CURLcode result = CURLE_OK;
CERT_CONTEXT *pCertContextServer = NULL;
const CERT_CHAIN_CONTEXT *pChainContext = NULL;
const char * const conn_hostname = SSL_IS_PROXY() ?
conn->http_proxy.host.name :
conn->host.name;
status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
&pCertContextServer);
if((status != SEC_E_OK) || (pCertContextServer == NULL)) {
failf(data, "schannel: Failed to read remote certificate context: %s",
Curl_sspi_strerror(conn, status));
result = CURLE_PEER_FAILED_VERIFICATION;
}
if(result == CURLE_OK) {
CERT_CHAIN_PARA ChainPara;
memset(&ChainPara, 0, sizeof(ChainPara));
ChainPara.cbSize = sizeof(ChainPara);
if(!CertGetCertificateChain(NULL,
pCertContextServer,
NULL,
pCertContextServer->hCertStore,
&ChainPara,
(data->set.ssl.no_revoke ? 0 :
CERT_CHAIN_REVOCATION_CHECK_CHAIN),
NULL,
&pChainContext)) {
failf(data, "schannel: CertGetCertificateChain failed: %s",
Curl_sspi_strerror(conn, GetLastError()));
pChainContext = NULL;
result = CURLE_PEER_FAILED_VERIFICATION;
}
if(result == CURLE_OK) {
CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0];
DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED);
dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus;
if(dwTrustErrorMask) {
if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_IS_REVOKED");
else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_IS_PARTIAL_CHAIN");
else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_IS_UNTRUSTED_ROOT");
else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_IS_NOT_TIME_VALID");
else
failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x",
dwTrustErrorMask);
result = CURLE_PEER_FAILED_VERIFICATION;
}
}
}
if(result == CURLE_OK) {
if(conn->ssl_config.verifyhost) {
TCHAR cert_hostname_buff[256];
DWORD len;
/* TODO: Fix this for certificates with multiple alternative names.
Right now we're only asking for the first preferred alternative name.
Instead we'd need to do all via CERT_NAME_SEARCH_ALL_NAMES_FLAG
(if WinCE supports that?) and run this section in a loop for each.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa376086.aspx
curl: (51) schannel: CertGetNameString() certificate hostname
(.google.com) did not match connection (google.com)
*/
len = CertGetNameString(pCertContextServer,
CERT_NAME_DNS_TYPE,
CERT_NAME_DISABLE_IE4_UTF8_FLAG,
NULL,
cert_hostname_buff,
256);
if(len > 0) {
const char *cert_hostname;
/* Comparing the cert name and the connection hostname encoded as UTF-8
* is acceptable since both values are assumed to use ASCII
* (or some equivalent) encoding
*/
cert_hostname = Curl_convert_tchar_to_UTF8(cert_hostname_buff);
if(!cert_hostname) {
result = CURLE_OUT_OF_MEMORY;
}
else{
int match_result;
match_result = Curl_cert_hostcheck(cert_hostname, conn->host.name);
if(match_result == CURL_HOST_MATCH) {
infof(data,
"schannel: connection hostname (%s) validated "
"against certificate name (%s)\n",
conn->host.name,
cert_hostname);
result = CURLE_OK;
}
else{
failf(data,
"schannel: connection hostname (%s) "
"does not match certificate name (%s)",
conn->host.name,
cert_hostname);
result = CURLE_PEER_FAILED_VERIFICATION;
}
Curl_unicodefree(cert_hostname);
}
}
else {
failf(data,
"schannel: CertGetNameString did not provide any "
"certificate name information");
result = CURLE_PEER_FAILED_VERIFICATION;
}
}
}
if(pChainContext)
CertFreeCertificateChain(pChainContext);
if(pCertContextServer)
CertFreeCertificateContext(pCertContextServer);
return result;
}
#endif /* _WIN32_WCE */
static void Curl_schannel_checksum(const unsigned char *input, static void Curl_schannel_checksum(const unsigned char *input,
size_t inputlen, size_t inputlen,
unsigned char *checksum, unsigned char *checksum,

View File

@ -26,9 +26,49 @@
#ifdef USE_SCHANNEL #ifdef USE_SCHANNEL
#include <schnlsp.h>
#include <schannel.h>
#include "curl_sspi.h"
#include "urldata.h" #include "urldata.h"
extern const struct Curl_ssl Curl_ssl_schannel; extern const struct Curl_ssl Curl_ssl_schannel;
CURLcode verify_certificate(struct connectdata *conn, int sockindex);
/* structs to expose only in schannel.c and schannel_verify.c */
#ifdef EXPOSE_SCHANNEL_INTERNAL_STRUCTS
struct curl_schannel_cred {
CredHandle cred_handle;
TimeStamp time_stamp;
int refcount;
};
struct curl_schannel_ctxt {
CtxtHandle ctxt_handle;
TimeStamp time_stamp;
};
struct ssl_backend_data {
struct curl_schannel_cred *cred;
struct curl_schannel_ctxt *ctxt;
SecPkgContext_StreamSizes stream_sizes;
size_t encdata_length, decdata_length;
size_t encdata_offset, decdata_offset;
unsigned char *encdata_buffer, *decdata_buffer;
/* encdata_is_incomplete: if encdata contains only a partial record that
can't be decrypted without another Curl_read_plain (that is, status is
SEC_E_INCOMPLETE_MESSAGE) then set this true. after Curl_read_plain writes
more bytes into encdata then set this back to false. */
bool encdata_is_incomplete;
unsigned long req_flags, ret_flags;
CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
bool recv_sspi_close_notify; /* true if connection closed by close_notify */
bool recv_connection_closed; /* true if connection closed, regardless how */
bool use_alpn; /* true if ALPN is used for this connection */
bool use_manual_cred_validation; /* true if manual cred validation is used */
};
#endif /* EXPOSE_SCHANNEL_INTERNAL_STRUCTS */
#endif /* USE_SCHANNEL */ #endif /* USE_SCHANNEL */
#endif /* HEADER_CURL_SCHANNEL_H */ #endif /* HEADER_CURL_SCHANNEL_H */

551
lib/vtls/schannel_verify.c Normal file
View File

@ -0,0 +1,551 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 2012 - 2016, Marc Hoersken, <info@marc-hoersken.de>
* Copyright (C) 2012, Mark Salisbury, <mark.salisbury@hp.com>
* Copyright (C) 2012 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.haxx.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
***************************************************************************/
/*
* Source file for SChannel-specific certificate verification. This code should
* only be invoked by code in schannel.c.
*/
#include "curl_setup.h"
#ifdef USE_SCHANNEL
#define EXPOSE_SCHANNEL_INTERNAL_STRUCTS
#ifndef USE_WINDOWS_SSPI
# error "Can't compile SCHANNEL support without SSPI."
#endif
#include "schannel.h"
#include "vtls.h"
#include "sendf.h"
#include "strerror.h"
#include "curl_multibyte.h"
#include "curl_printf.h"
#include "hostcheck.h"
#include "system_win32.h"
/* The last #include file should be: */
#include "curl_memory.h"
#include "memdebug.h"
#define BACKEND connssl->backend
#define MAX_CAFILE_SIZE 1048576 /* 1 MiB */
#define BEGIN_CERT "-----BEGIN CERTIFICATE-----\n"
#define END_CERT "\n-----END CERTIFICATE-----"
typedef struct {
DWORD cbSize;
HCERTSTORE hRestrictedRoot;
HCERTSTORE hRestrictedTrust;
HCERTSTORE hRestrictedOther;
DWORD cAdditionalStore;
HCERTSTORE *rghAdditionalStore;
DWORD dwFlags;
DWORD dwUrlRetrievalTimeout;
DWORD MaximumCachedCertificates;
DWORD CycleDetectionModulus;
HCERTSTORE hExclusiveRoot;
HCERTSTORE hExclusiveTrustedPeople;
} CERT_CHAIN_ENGINE_CONFIG_WIN7, *PCERT_CHAIN_ENGINE_CONFIG_WIN7;
static CURLcode add_certs_to_store(HCERTSTORE trust_store,
const char *ca_file,
struct connectdata *conn)
{
CURLcode result;
struct Curl_easy *data = conn->data;
HANDLE ca_file_handle = INVALID_HANDLE_VALUE;
LARGE_INTEGER file_size;
char *ca_file_buffer = NULL;
char *current_ca_file_ptr = NULL;
const TCHAR *ca_file_tstr = NULL;
size_t ca_file_bufsize = 0;
DWORD total_bytes_read = 0;
bool more_certs = 0;
int num_certs = 0;
size_t END_CERT_LEN;
ca_file_tstr = Curl_convert_UTF8_to_tchar(ca_file);
if(!ca_file_tstr) {
failf(data,
"schannel: invalid path name for CA file '%s': %s",
ca_file, Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
/*
* Read the CA file completely into memory before parsing it. This
* optimizes for the common case where the CA file will be relatively
* small ( < 1 MiB ).
*/
ca_file_handle = CreateFile(ca_file_tstr,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(ca_file_handle == INVALID_HANDLE_VALUE) {
failf(data,
"schannel: failed to open CA file '%s': %s",
ca_file, Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
if(!GetFileSizeEx(ca_file_handle, &file_size)) {
failf(data,
"schannel: failed to determine size of CA file '%s': %s",
ca_file, Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
if(file_size.QuadPart > MAX_CAFILE_SIZE) {
failf(data,
"schannel: CA file exceeds max size of %u bytes",
MAX_CAFILE_SIZE);
result = CURLE_OUT_OF_MEMORY;
goto cleanup;
}
ca_file_bufsize = (size_t)file_size.QuadPart;
ca_file_buffer = (char *)malloc(ca_file_bufsize + 1);
if(!ca_file_buffer) {
result = CURLE_OUT_OF_MEMORY;
goto cleanup;
}
result = CURLE_OK;
while(total_bytes_read < ca_file_bufsize) {
DWORD bytes_to_read = (DWORD)(ca_file_bufsize - total_bytes_read);
DWORD bytes_read = 0;
if(!ReadFile(ca_file_handle, ca_file_buffer + total_bytes_read,
bytes_to_read, &bytes_read, NULL)) {
failf(data,
"schannel: failed to read from CA file '%s': %s",
ca_file, Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
goto cleanup;
}
if(bytes_read == 0) {
/* Premature EOF -- adjust the bufsize to the new value */
ca_file_bufsize = total_bytes_read;
}
else {
total_bytes_read += bytes_read;
}
}
/* Null terminate the buffer */
ca_file_buffer[ca_file_bufsize] = '\0';
if(result != CURLE_OK) {
goto cleanup;
}
END_CERT_LEN = strlen(END_CERT);
more_certs = 1;
current_ca_file_ptr = ca_file_buffer;
while(more_certs && *current_ca_file_ptr != '\0') {
char *begin_cert_ptr = strstr(current_ca_file_ptr, BEGIN_CERT);
if(!begin_cert_ptr) {
more_certs = 0;
}
else {
char *end_cert_ptr = strstr(begin_cert_ptr, END_CERT);
if(!end_cert_ptr) {
failf(data,
"schannel: CA file '%s' is not correctly formatted",
ca_file);
result = CURLE_SSL_CACERT_BADFILE;
more_certs = 0;
}
else {
CERT_BLOB cert_blob;
CERT_CONTEXT *cert_context = NULL;
BOOL add_cert_result = FALSE;
DWORD actual_content_type = 0;
DWORD cert_size = (DWORD)
((end_cert_ptr + END_CERT_LEN) - begin_cert_ptr);
cert_blob.pbData = (BYTE *)begin_cert_ptr;
cert_blob.cbData = cert_size;
if(!CryptQueryObject(CERT_QUERY_OBJECT_BLOB,
&cert_blob,
CERT_QUERY_CONTENT_FLAG_CERT,
CERT_QUERY_FORMAT_FLAG_ALL,
0,
NULL,
&actual_content_type,
NULL,
NULL,
NULL,
&cert_context)) {
failf(data,
"schannel: failed to extract certificate from CA file "
"'%s': %s",
ca_file, Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
more_certs = 0;
}
else {
current_ca_file_ptr = begin_cert_ptr + cert_size;
/* Sanity check that the cert_context object is the right type */
if(CERT_QUERY_CONTENT_CERT != actual_content_type) {
failf(data,
"schannel: unexpected content type '%d' when extracting "
"certificate from CA file '%s'",
actual_content_type, ca_file);
result = CURLE_SSL_CACERT_BADFILE;
more_certs = 0;
}
else {
add_cert_result =
CertAddCertificateContextToStore(trust_store,
cert_context,
CERT_STORE_ADD_ALWAYS,
NULL);
CertFreeCertificateContext(cert_context);
if(!add_cert_result) {
failf(data,
"schannel: failed to add certificate from CA file '%s'"
"to certificate store: %s",
ca_file, Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
more_certs = 0;
}
else {
num_certs++;
}
}
}
}
}
}
if(result == CURLE_OK) {
if(!num_certs) {
infof(data,
"schannel: did not add any certificates from CA file '%s'\n",
ca_file);
}
else {
infof(data,
"schannel: added %d certificate(s) from CA file '%s'\n",
num_certs, ca_file);
}
}
cleanup:
if(ca_file_handle != INVALID_HANDLE_VALUE) {
CloseHandle(ca_file_handle);
}
Curl_safefree(ca_file_buffer);
Curl_unicodefree(ca_file_tstr);
return result;
}
static CURLcode verify_host(struct Curl_easy *data,
CERT_CONTEXT *pCertContextServer,
const char * const conn_hostname)
{
CURLcode result = CURLE_PEER_FAILED_VERIFICATION;
TCHAR *cert_hostname_buff = NULL;
size_t cert_hostname_buff_index = 0;
DWORD len = 0;
DWORD actual_len = 0;
/* CertGetNameString will provide the 8-bit character string without
* any decoding */
DWORD name_flags = CERT_NAME_DISABLE_IE4_UTF8_FLAG;
#ifdef CERT_NAME_SEARCH_ALL_NAMES_FLAG
name_flags |= CERT_NAME_SEARCH_ALL_NAMES_FLAG;
#endif
/* Determine the size of the string needed for the cert hostname */
len = CertGetNameString(pCertContextServer,
CERT_NAME_DNS_TYPE,
name_flags,
NULL,
NULL,
0);
if(len == 0) {
failf(data,
"schannel: CertGetNameString() returned no "
"certificate name information");
result = CURLE_PEER_FAILED_VERIFICATION;
goto cleanup;
}
/* CertGetNameString guarantees that the returned name will not contain
* embedded null bytes. This appears to be undocumented behavior.
*/
cert_hostname_buff = (LPTSTR)malloc(len * sizeof(TCHAR));
actual_len = CertGetNameString(pCertContextServer,
CERT_NAME_DNS_TYPE,
name_flags,
NULL,
(LPTSTR) cert_hostname_buff,
len);
/* Sanity check */
if(actual_len != len) {
failf(data,
"schannel: CertGetNameString() returned certificate "
"name information of unexpected size");
result = CURLE_PEER_FAILED_VERIFICATION;
goto cleanup;
}
/* If HAVE_CERT_NAME_SEARCH_ALL_NAMES is available, the output
* will contain all DNS names, where each name is null-terminated
* and the last DNS name is double null-terminated. Due to this
* encoding, use the length of the buffer to iterate over all names.
*/
result = CURLE_PEER_FAILED_VERIFICATION;
while(cert_hostname_buff_index < len &&
cert_hostname_buff[cert_hostname_buff_index] != TEXT('\0') &&
result == CURLE_PEER_FAILED_VERIFICATION) {
char *cert_hostname;
/* Comparing the cert name and the connection hostname encoded as UTF-8
* is acceptable since both values are assumed to use ASCII
* (or some equivalent) encoding
*/
cert_hostname = Curl_convert_tchar_to_UTF8(
&cert_hostname_buff[cert_hostname_buff_index]);
if(!cert_hostname) {
result = CURLE_OUT_OF_MEMORY;
}
else {
int match_result;
match_result = Curl_cert_hostcheck(cert_hostname, conn_hostname);
if(match_result == CURL_HOST_MATCH) {
infof(data,
"schannel: connection hostname (%s) validated "
"against certificate name (%s)\n",
conn_hostname, cert_hostname);
result = CURLE_OK;
}
else {
size_t cert_hostname_len;
infof(data,
"schannel: connection hostname (%s) did not match "
"against certificate name (%s)\n",
conn_hostname, cert_hostname);
cert_hostname_len = _tcslen(
&cert_hostname_buff[cert_hostname_buff_index]);
/* Move on to next cert name */
cert_hostname_buff_index += cert_hostname_len + 1;
result = CURLE_PEER_FAILED_VERIFICATION;
}
Curl_unicodefree(cert_hostname);
}
}
if(result == CURLE_PEER_FAILED_VERIFICATION) {
failf(data,
"schannel: CertGetNameString() failed to match "
"connection hostname (%s) against server certificate names",
conn_hostname);
}
else if(result != CURLE_OK)
failf(data, "schannel: server certificate name verification failed");
cleanup:
Curl_unicodefree(cert_hostname_buff);
return result;
}
CURLcode verify_certificate(struct connectdata *conn, int sockindex)
{
SECURITY_STATUS status;
struct Curl_easy *data = conn->data;
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
CURLcode result = CURLE_OK;
CERT_CONTEXT *pCertContextServer = NULL;
const CERT_CHAIN_CONTEXT *pChainContext = NULL;
HCERTCHAINENGINE cert_chain_engine = NULL;
HCERTSTORE trust_store = NULL;
const char * const conn_hostname = SSL_IS_PROXY() ?
conn->http_proxy.host.name :
conn->host.name;
status = s_pSecFn->QueryContextAttributes(&BACKEND->ctxt->ctxt_handle,
SECPKG_ATTR_REMOTE_CERT_CONTEXT,
&pCertContextServer);
if((status != SEC_E_OK) || (pCertContextServer == NULL)) {
failf(data, "schannel: Failed to read remote certificate context: %s",
Curl_sspi_strerror(conn, status));
result = CURLE_PEER_FAILED_VERIFICATION;
}
if(result == CURLE_OK && SSL_CONN_CONFIG(CAfile) &&
BACKEND->use_manual_cred_validation) {
/*
* Create a chain engine that uses the certificates in the CA file as
* trusted certificates. This is only supported on Windows 7+.
*/
if(Curl_verify_windows_version(6, 1, PLATFORM_WINNT, VERSION_LESS_THAN)) {
failf(data, "schannel: this version of Windows is too old to support "
"certificate verification via CA bundle file.");
result = CURLE_SSL_CACERT_BADFILE;
}
else {
/* Open the certificate store */
trust_store = CertOpenStore(CERT_STORE_PROV_MEMORY,
0,
(HCRYPTPROV)NULL,
CERT_STORE_CREATE_NEW_FLAG,
NULL);
if(!trust_store) {
failf(data, "schannel: failed to create certificate store: %s",
Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
}
else {
result = add_certs_to_store(trust_store, SSL_CONN_CONFIG(CAfile),
conn);
}
}
if(result == CURLE_OK) {
CERT_CHAIN_ENGINE_CONFIG_WIN7 engine_config;
BOOL create_engine_result;
memset(&engine_config, 0, sizeof(engine_config));
engine_config.cbSize = sizeof(engine_config);
engine_config.hExclusiveRoot = trust_store;
/* CertCreateCertificateChainEngine will check the expected size of the
* CERT_CHAIN_ENGINE_CONFIG structure and fail if the specified size
* does not match the expected size. When this occurs, it indicates that
* CAINFO is not supported on the version of Windows in use.
*/
create_engine_result =
CertCreateCertificateChainEngine(
(CERT_CHAIN_ENGINE_CONFIG *)&engine_config, &cert_chain_engine);
if(!create_engine_result) {
failf(data,
"schannel: failed to create certificate chain engine: %s",
Curl_strerror(conn, GetLastError()));
result = CURLE_SSL_CACERT_BADFILE;
}
}
}
if(result == CURLE_OK) {
CERT_CHAIN_PARA ChainPara;
memset(&ChainPara, 0, sizeof(ChainPara));
ChainPara.cbSize = sizeof(ChainPara);
if(!CertGetCertificateChain(cert_chain_engine,
pCertContextServer,
NULL,
pCertContextServer->hCertStore,
&ChainPara,
(data->set.ssl.no_revoke ? 0 :
CERT_CHAIN_REVOCATION_CHECK_CHAIN),
NULL,
&pChainContext)) {
failf(data, "schannel: CertGetCertificateChain failed: %s",
Curl_sspi_strerror(conn, GetLastError()));
pChainContext = NULL;
result = CURLE_PEER_FAILED_VERIFICATION;
}
if(result == CURLE_OK) {
CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0];
DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED);
dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus;
if(dwTrustErrorMask) {
if(dwTrustErrorMask & CERT_TRUST_IS_REVOKED)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_IS_REVOKED");
else if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_IS_PARTIAL_CHAIN");
else if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_IS_UNTRUSTED_ROOT");
else if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_IS_NOT_TIME_VALID");
else if(dwTrustErrorMask & CERT_TRUST_REVOCATION_STATUS_UNKNOWN)
failf(data, "schannel: CertGetCertificateChain trust error"
" CERT_TRUST_REVOCATION_STATUS_UNKNOWN");
else
failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x",
dwTrustErrorMask);
result = CURLE_PEER_FAILED_VERIFICATION;
}
}
}
if(result == CURLE_OK) {
if(SSL_CONN_CONFIG(verifyhost)) {
result = verify_host(conn->data, pCertContextServer, conn_hostname);
}
}
if(cert_chain_engine) {
CertFreeCertificateChainEngine(cert_chain_engine);
}
if(trust_store) {
CertCloseStore(trust_store, 0);
}
if(pChainContext)
CertFreeCertificateChain(pChainContext);
if(pCertContextServer)
CertFreeCertificateContext(pCertContextServer);
return result;
}
#endif /* USE_SCHANNEL */

View File

@ -638,12 +638,19 @@ char **__crt0_glob_function(char *arg)
*/ */
CURLcode FindWin32CACert(struct OperationConfig *config, CURLcode FindWin32CACert(struct OperationConfig *config,
curl_sslbackend backend,
const char *bundle_file) const char *bundle_file)
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
/* search and set cert file only if libcurl supports SSL */ /* Search and set cert file only if libcurl supports SSL.
if(curlinfo->features & CURL_VERSION_SSL) { *
* If Schannel (WinSSL) is the selected SSL backend then these locations
* are ignored. We allow setting CA location for schannel only when
* explicitly specified by the user via CURLOPT_CAINFO / --cacert.
*/
if((curlinfo->features & CURL_VERSION_SSL) &&
backend != CURLSSLBACKEND_SCHANNEL) {
DWORD res_len; DWORD res_len;
char buf[PATH_MAX]; char buf[PATH_MAX];

View File

@ -58,6 +58,7 @@ char **__crt0_glob_function(char *arg);
#ifdef WIN32 #ifdef WIN32
CURLcode FindWin32CACert(struct OperationConfig *config, CURLcode FindWin32CACert(struct OperationConfig *config,
curl_sslbackend backend,
const char *bundle_file); const char *bundle_file);
#endif /* WIN32 */ #endif /* WIN32 */

View File

@ -228,6 +228,28 @@ static CURLcode operate_do(struct GlobalConfig *global,
if(!config->cacert && if(!config->cacert &&
!config->capath && !config->capath &&
!config->insecure_ok) { !config->insecure_ok) {
struct curl_tlssessioninfo *tls_backend_info = NULL;
/* With the addition of CAINFO support for Schannel, this search could find
* a certificate bundle that was previously ignored. To maintain backward
* compatibility, only perform this search if not using Schannel.
*/
result = curl_easy_getinfo(config->easy,
CURLINFO_TLS_SSL_PTR,
&tls_backend_info);
if(result) {
goto quit_curl;
}
/* Set the CA cert locations specified in the environment. For Windows if
* no environment-specified filename is found then check for CA bundle
* default filename curl-ca-bundle.crt in the user's PATH.
*
* If Schannel (WinSSL) is the selected SSL backend then these locations
* are ignored. We allow setting CA location for schannel only when
* explicitly specified by the user via CURLOPT_CAINFO / --cacert.
*/
if(tls_backend_info->backend != CURLSSLBACKEND_SCHANNEL) {
char *env; char *env;
env = curlx_getenv("CURL_CA_BUNDLE"); env = curlx_getenv("CURL_CA_BUNDLE");
if(env) { if(env) {
@ -269,12 +291,14 @@ static CURLcode operate_do(struct GlobalConfig *global,
curl_free(env); curl_free(env);
#ifdef WIN32 #ifdef WIN32
else { else {
result = FindWin32CACert(config, "curl-ca-bundle.crt"); result = FindWin32CACert(config, tls_backend_info->backend,
"curl-ca-bundle.crt");
if(result) if(result)
goto quit_curl; goto quit_curl;
} }
#endif #endif
} }
}
if(config->postfields) { if(config->postfields) {
if(config->use_httpget) { if(config->use_httpget) {

View File

@ -62,7 +62,25 @@ GENERATEDCERTS = \
Server-localhost0h-sv.key \ Server-localhost0h-sv.key \
Server-localhost0h-sv.pem \ Server-localhost0h-sv.pem \
Server-localhost0h-sv.pub.der \ Server-localhost0h-sv.pub.der \
Server-localhost0h-sv.pub.pem Server-localhost0h-sv.pub.pem \
Server-localhost-firstSAN-sv.crl \
Server-localhost-firstSAN-sv.crt \
Server-localhost-firstSAN-sv.csr \
Server-localhost-firstSAN-sv.der \
Server-localhost-firstSAN-sv.dhp \
Server-localhost-firstSAN-sv.key \
Server-localhost-firstSAN-sv.pem \
Server-localhost-firstSAN-sv.pub.der \
Server-localhost-firstSAN-sv.pub.pem \
Server-localhost-lastSAN-sv.crl \
Server-localhost-lastSAN-sv.crt \
Server-localhost-lastSAN-sv.csr \
Server-localhost-lastSAN-sv.der \
Server-localhost-lastSAN-sv.dhp \
Server-localhost-lastSAN-sv.key \
Server-localhost-lastSAN-sv.pem \
Server-localhost-lastSAN-sv.pub.der \
Server-localhost-lastSAN-sv.pub.pem
SRPFILES = \ SRPFILES = \
srp-verifier-conf \ srp-verifier-conf \
@ -76,7 +94,8 @@ clean-certs:
cd $(srcdir); rm -f $(GENERATEDCERTS) cd $(srcdir); rm -f $(GENERATEDCERTS)
build-certs: $(srcdir)/EdelCurlRoot-ca.cacert $(srcdir)/Server-localhost-sv.pem \ build-certs: $(srcdir)/EdelCurlRoot-ca.cacert $(srcdir)/Server-localhost-sv.pem \
$(srcdir)/Server-localhost.nn-sv.pem $(srcdir)/Server-localhost0h-sv.pem $(srcdir)/Server-localhost.nn-sv.pem $(srcdir)/Server-localhost0h-sv.pem \
$(srcdir)/Server-localhost-firstSAN-sv.pem $(srcdir)/Server-localhost-lastSAN-sv.pem
$(srcdir)/EdelCurlRoot-ca.cacert: $(srcdir)/EdelCurlRoot-ca.cacert:
cd $(srcdir); scripts/genroot.sh EdelCurlRoot cd $(srcdir); scripts/genroot.sh EdelCurlRoot
@ -89,3 +108,9 @@ $(srcdir)/Server-localhost.nn-sv.pem: $(srcdir)/EdelCurlRoot-ca.cacert
$(srcdir)/Server-localhost0h-sv.pem: $(srcdir)/EdelCurlRoot-ca.cacert $(srcdir)/Server-localhost0h-sv.pem: $(srcdir)/EdelCurlRoot-ca.cacert
cd $(srcdir); scripts/genserv.sh Server-localhost0h EdelCurlRoot cd $(srcdir); scripts/genserv.sh Server-localhost0h EdelCurlRoot
$(srcdir)/Server-localhost-firstSAN-sv.pem: $(srcdir)/EdelCurlRoot-ca.cacert
cd $(srcdir); scripts/genserv.sh Server-localhost-firstSAN EdelCurlRoot
$(srcdir)/Server-localhost-lastSAN-sv.pem: $(srcdir)/EdelCurlRoot-ca.cacert
cd $(srcdir); scripts/genserv.sh Server-localhost-firstSAN EdelCurlRoot

View File

@ -0,0 +1,13 @@
-----BEGIN X509 CRL-----
MIIB9TCB3gIBATANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJOTjExMC8GA1UE
CgwoRWRlbCBDdXJsIEFyY3RpYyBJbGx1ZGl1bSBSZXNlYXJjaCBDbG91ZDEmMCQG
A1UEAwwdTm9ydGhlcm4gTm93aGVyZSBUcnVzdCBBbmNob3IXDTE2MDgzMDE4MzIx
NVoXDTE2MDkyOTE4MzIxNVowMjAXAgYNZJ8o86IXDTE2MDgzMDE4MzAxNVowFwIG
DWSfO0UqFw0xNjA4MzAxODMyMTVaoA4wDDAKBgNVHRQEAwIBATANBgkqhkiG9w0B
AQUFAAOCAQEAOUlXQDrOURgODds6feyO+87oPHkgTveOiTm8CtSVHObxwkPkHTIg
pivd7iXccgEc8CstcGF9Pk5KLVJrXXxEKgGr69NZNGtHa8xXlYSIh+Vre0Pni3Px
sUAMcsnvGt+cYw/5s/2Wy9u5UVzfJwdxjkxMMp9X648AqeSop229541zGV47M4ox
h0wh2Mj/w/CFUKw0ijVgVWff5DhKXVaLPCXdh7hhgXcsYUZ4W3G/iOL/jd+Ji88o
OmZvoP+MOco6or13rz178bGB1mS626z7EU/HNgP8sn25TyQwwopr9uW6H7VvRMaI
6uwWvihKgoGCRVSVwYEfX+oOLadfJqdHdg==
-----END X509 CRL-----

View File

@ -0,0 +1,80 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 14725819352362 (0xd649f3b452a)
Signature Algorithm: sha1WithRSAEncryption
Issuer:
countryName = NN
organizationName = Edel Curl Arctic Illudium Research Cloud
commonName = Northern Nowhere Trust Anchor
Validity
Not Before: Aug 30 18:32:15 2016 GMT
Not After : Nov 16 18:32:15 2024 GMT
Subject:
countryName = NN
organizationName = Edel Curl Arctic Illudium Research Cloud
commonName = localhost.nn
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:c5:87:2e:fb:f5:88:8a:39:4c:62:88:9f:fb:4a:
02:1c:27:92:9d:0b:65:a2:70:1f:d1:b7:de:c8:1d:
87:28:4b:9c:4b:cc:f6:f6:7c:83:1f:2d:76:be:41:
29:5e:31:fa:23:0c:2d:7d:cb:38:c2:8b:54:8f:fc:
6a:50:6d:c7:d7:af:72:fb:3b:a1:a7:4d:c4:1b:d2:
0d:75:7c:92:62:97:48:c4:e8:12:c0:00:33:66:0e:
28:17:0f:5c:36:d6:50:70:ec:c8:9f:a2:ae:b9:eb:
eb:19:05:f0:53:83:42:2a:ae:40:1f:fa:fb:7a:b7:
86:4c:ab:6b:28:0b:2f:7f:81
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:localhost, DNS:localhost1, DNS:localhost2
X509v3 Key Usage:
Digital Signature, Key Encipherment, Key Agreement
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Key Identifier:
2C:4D:DD:54:88:59:3F:A4:34:9C:E3:56:FF:95:0F:E2:CE:51:20:95
X509v3 Authority Key Identifier:
keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE
X509v3 Basic Constraints:
CA:FALSE
Signature Algorithm: sha1WithRSAEncryption
77:cd:d2:17:91:a6:4b:70:de:79:6a:20:82:a3:56:a3:d0:6a:
ba:f7:7d:6f:00:69:d2:06:06:0b:da:cd:49:9d:36:fd:d0:cc:
bd:8a:dc:e1:d6:89:c9:23:02:8a:19:2d:14:ca:c6:06:87:66:
c7:f4:32:37:95:0d:f1:a7:1c:a1:fe:43:4f:3b:03:03:e2:1a:
c6:fc:91:d5:0d:a0:7e:82:60:14:31:2f:6d:b8:f4:57:98:8d:
04:74:a3:82:28:6d:1c:b4:de:1a:70:bd:fe:73:ac:b7:96:ec:
7c:9b:6d:64:c6:f8:67:39:c7:ea:f4:aa:48:26:b8:14:85:f0:
00:ab:8f:bd:1a:95:e2:a7:63:92:35:1e:37:04:c2:70:2c:1c:
56:95:b1:83:70:8c:99:88:1c:8a:6f:7a:a2:0d:84:dd:4f:0e:
3e:8b:fb:31:cf:ae:ee:b0:e4:f6:c1:8d:d1:98:a9:8d:17:1f:
5d:5a:79:e8:7c:97:ab:40:bc:aa:7e:c4:0b:19:30:ad:18:aa:
9c:9b:eb:3f:35:d3:86:9c:3a:cc:e6:9a:2c:47:d1:bb:36:6e:
f2:c5:d4:e3:0c:5b:c6:eb:30:e6:0d:3a:4b:3a:a3:6b:62:93:
8b:6a:59:1f:48:66:2e:d9:70:14:b6:aa:4f:d1:3b:38:5e:e6:
79:7f:b7:00
-----BEGIN CERTIFICATE-----
MIIDWjCCAkKgAwIBAgIGDWSfO0UqMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT
Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo
IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe
Fw0xNjA4MzAxODMyMTVaFw0yNDExMTYxODMyMTVaMFcxCzAJBgNVBAYTAk5OMTEw
LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk
MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
AoGBAMWHLvv1iIo5TGKIn/tKAhwnkp0LZaJwH9G33sgdhyhLnEvM9vZ8gx8tdr5B
KV4x+iMMLX3LOMKLVI/8alBtx9evcvs7oadNxBvSDXV8kmKXSMToEsAAM2YOKBcP
XDbWUHDsyJ+irrnr6xkF8FODQiquQB/6+3q3hkyraygLL3+BAgMBAAGjgZ4wgZsw
LAYDVR0RBCUwI4IJbG9jYWxob3N0ggpsb2NhbGhvc3Qxggpsb2NhbGhvc3QyMAsG
A1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQULE3dVIhZ
P6Q0nONW/5UP4s5RIJUwHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84w
CQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAd83SF5GmS3DeeWoggqNWo9Bq
uvd9bwBp0gYGC9rNSZ02/dDMvYrc4daJySMCihktFMrGBodmx/QyN5UN8accof5D
TzsDA+IaxvyR1Q2gfoJgFDEvbbj0V5iNBHSjgihtHLTeGnC9/nOst5bsfJttZMb4
ZznH6vSqSCa4FIXwAKuPvRqV4qdjkjUeNwTCcCwcVpWxg3CMmYgcim96og2E3U8O
Pov7Mc+u7rDk9sGN0ZipjRcfXVp56HyXq0C8qn7ECxkwrRiqnJvrPzXThpw6zOaa
LEfRuzZu8sXU4wxbxusw5g06Szqja2KTi2pZH0hmLtlwFLaqT9E7OF7meX+3AA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,11 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIBlzCCAQACAQAwVzELMAkGA1UEBhMCTk4xMTAvBgNVBAoMKEVkZWwgQ3VybCBB
cmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQxFTATBgNVBAMMDGxvY2FsaG9z
dC5ubjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxYcu+/WIijlMYoif+0oC
HCeSnQtlonAf0bfeyB2HKEucS8z29nyDHy12vkEpXjH6Iwwtfcs4wotUj/xqUG3H
169y+zuhp03EG9INdXySYpdIxOgSwAAzZg4oFw9cNtZQcOzIn6KuuevrGQXwU4NC
Kq5AH/r7ereGTKtrKAsvf4ECAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBADlhAYRy
2heMP/fGllGXW/uAEm2q6ubWhqgd3/5d+06LjTIs57qT/nwbr79e1PxholGWM+Zb
/NGKZ4geZK0mJT/gnaJCyUsrjdp2KIEw9zmBoZyypJd/5Fhe1tzX0xwG40+3np9K
orpp7wcILLeMho8+I4mNEzOJHidxy/9uia5U
-----END CERTIFICATE REQUEST-----

Binary file not shown.

View File

@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDFhy779YiKOUxiiJ/7SgIcJ5KdC2WicB/Rt97IHYcoS5xLzPb2
fIMfLXa+QSleMfojDC19yzjCi1SP/GpQbcfXr3L7O6GnTcQb0g11fJJil0jE6BLA
ADNmDigXD1w21lBw7Mifoq656+sZBfBTg0IqrkAf+vt6t4ZMq2soCy9/gQIDAQAB
AoGAUjKXErJyR1LgvoAsUt3RUvYExOVhPd963kKtqojfHZ2ZRNHeU2QtDGRW7YUg
OdqCRONkatyOmiZw4hogA6graJKiqKLvM/F4qRoLsxH9T/cSOIl9QjZVkUd1HV/Z
iJluibPTewVyfoYzkq48GN+QIi//msYKBjI5Q2Yybn4WrgECQQDk/mDp4sAvuLXL
NxaQKuDZA5TxU2u8GTItFqOoHneVFSJLE4O3kr7wh47O817mnljZfskZwVXBYx6R
VbXsy8ZJAkEA3NLRFh8cR03CN+eYPi33JrUVRSrn8eAB5MNOaOdO4mT0pTAzfVfe
g6rMDnK2n7WZzwf6YmvRVyppW2/kQjyPeQJAXoa3ILTuWoSn3owN71MT3+E/oWKr
LUlFUiFvSx3QhSTlNBKJI8UatpVumPUTbqVczeMtRkltidfNrXaxE1+GqQJAW9WU
vMVtZj3xUnyPNPS6vy85zE0ertmBEBklJ71icgaYM4aLM0pysIE8YZnVVzAX6iCg
QYQjSEPMEwnCfMVgyQJAcWnk6HPLbJmUt+ZGGAcqzfycR6jMKFnm4st2Ld6JuDT2
h2lb40Uma9gO+aXLIf+K9prCxb+7nR1M3qLwV4krkQ==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,120 @@
extensions = x509v3
[ x509v3 ]
subjectAltName = DNS:localhost,DNS:localhost1,DNS:localhost2
keyUsage = keyEncipherment,digitalSignature,keyAgreement
extendedKeyUsage = serverAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid
basicConstraints = CA:false
[ req ]
default_bits = 1024
distinguished_name = req_DN
default_md = sha256
string_mask = utf8only
[ req_DN ]
countryName = "Country Name is Northern Nowhere"
countryName_value = NN
organizationName = "Organization Name"
organizationName_value = Edel Curl Arctic Illudium Research Cloud
commonName = "Common Name"
commonName_value = localhost.nn
[something]
# The key
# the certificate
# some dhparam
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDFhy779YiKOUxiiJ/7SgIcJ5KdC2WicB/Rt97IHYcoS5xLzPb2
fIMfLXa+QSleMfojDC19yzjCi1SP/GpQbcfXr3L7O6GnTcQb0g11fJJil0jE6BLA
ADNmDigXD1w21lBw7Mifoq656+sZBfBTg0IqrkAf+vt6t4ZMq2soCy9/gQIDAQAB
AoGAUjKXErJyR1LgvoAsUt3RUvYExOVhPd963kKtqojfHZ2ZRNHeU2QtDGRW7YUg
OdqCRONkatyOmiZw4hogA6graJKiqKLvM/F4qRoLsxH9T/cSOIl9QjZVkUd1HV/Z
iJluibPTewVyfoYzkq48GN+QIi//msYKBjI5Q2Yybn4WrgECQQDk/mDp4sAvuLXL
NxaQKuDZA5TxU2u8GTItFqOoHneVFSJLE4O3kr7wh47O817mnljZfskZwVXBYx6R
VbXsy8ZJAkEA3NLRFh8cR03CN+eYPi33JrUVRSrn8eAB5MNOaOdO4mT0pTAzfVfe
g6rMDnK2n7WZzwf6YmvRVyppW2/kQjyPeQJAXoa3ILTuWoSn3owN71MT3+E/oWKr
LUlFUiFvSx3QhSTlNBKJI8UatpVumPUTbqVczeMtRkltidfNrXaxE1+GqQJAW9WU
vMVtZj3xUnyPNPS6vy85zE0ertmBEBklJ71icgaYM4aLM0pysIE8YZnVVzAX6iCg
QYQjSEPMEwnCfMVgyQJAcWnk6HPLbJmUt+ZGGAcqzfycR6jMKFnm4st2Ld6JuDT2
h2lb40Uma9gO+aXLIf+K9prCxb+7nR1M3qLwV4krkQ==
-----END RSA PRIVATE KEY-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 14725819352362 (0xd649f3b452a)
Signature Algorithm: sha1WithRSAEncryption
Issuer:
countryName = NN
organizationName = Edel Curl Arctic Illudium Research Cloud
commonName = Northern Nowhere Trust Anchor
Validity
Not Before: Aug 30 18:32:15 2016 GMT
Not After : Nov 16 18:32:15 2024 GMT
Subject:
countryName = NN
organizationName = Edel Curl Arctic Illudium Research Cloud
commonName = localhost.nn
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:c5:87:2e:fb:f5:88:8a:39:4c:62:88:9f:fb:4a:
02:1c:27:92:9d:0b:65:a2:70:1f:d1:b7:de:c8:1d:
87:28:4b:9c:4b:cc:f6:f6:7c:83:1f:2d:76:be:41:
29:5e:31:fa:23:0c:2d:7d:cb:38:c2:8b:54:8f:fc:
6a:50:6d:c7:d7:af:72:fb:3b:a1:a7:4d:c4:1b:d2:
0d:75:7c:92:62:97:48:c4:e8:12:c0:00:33:66:0e:
28:17:0f:5c:36:d6:50:70:ec:c8:9f:a2:ae:b9:eb:
eb:19:05:f0:53:83:42:2a:ae:40:1f:fa:fb:7a:b7:
86:4c:ab:6b:28:0b:2f:7f:81
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:localhost, DNS:localhost1, DNS:localhost2
X509v3 Key Usage:
Digital Signature, Key Encipherment, Key Agreement
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Key Identifier:
2C:4D:DD:54:88:59:3F:A4:34:9C:E3:56:FF:95:0F:E2:CE:51:20:95
X509v3 Authority Key Identifier:
keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE
X509v3 Basic Constraints:
CA:FALSE
Signature Algorithm: sha1WithRSAEncryption
77:cd:d2:17:91:a6:4b:70:de:79:6a:20:82:a3:56:a3:d0:6a:
ba:f7:7d:6f:00:69:d2:06:06:0b:da:cd:49:9d:36:fd:d0:cc:
bd:8a:dc:e1:d6:89:c9:23:02:8a:19:2d:14:ca:c6:06:87:66:
c7:f4:32:37:95:0d:f1:a7:1c:a1:fe:43:4f:3b:03:03:e2:1a:
c6:fc:91:d5:0d:a0:7e:82:60:14:31:2f:6d:b8:f4:57:98:8d:
04:74:a3:82:28:6d:1c:b4:de:1a:70:bd:fe:73:ac:b7:96:ec:
7c:9b:6d:64:c6:f8:67:39:c7:ea:f4:aa:48:26:b8:14:85:f0:
00:ab:8f:bd:1a:95:e2:a7:63:92:35:1e:37:04:c2:70:2c:1c:
56:95:b1:83:70:8c:99:88:1c:8a:6f:7a:a2:0d:84:dd:4f:0e:
3e:8b:fb:31:cf:ae:ee:b0:e4:f6:c1:8d:d1:98:a9:8d:17:1f:
5d:5a:79:e8:7c:97:ab:40:bc:aa:7e:c4:0b:19:30:ad:18:aa:
9c:9b:eb:3f:35:d3:86:9c:3a:cc:e6:9a:2c:47:d1:bb:36:6e:
f2:c5:d4:e3:0c:5b:c6:eb:30:e6:0d:3a:4b:3a:a3:6b:62:93:
8b:6a:59:1f:48:66:2e:d9:70:14:b6:aa:4f:d1:3b:38:5e:e6:
79:7f:b7:00
-----BEGIN CERTIFICATE-----
MIIDWjCCAkKgAwIBAgIGDWSfO0UqMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT
Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo
IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe
Fw0xNjA4MzAxODMyMTVaFw0yNDExMTYxODMyMTVaMFcxCzAJBgNVBAYTAk5OMTEw
LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk
MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
AoGBAMWHLvv1iIo5TGKIn/tKAhwnkp0LZaJwH9G33sgdhyhLnEvM9vZ8gx8tdr5B
KV4x+iMMLX3LOMKLVI/8alBtx9evcvs7oadNxBvSDXV8kmKXSMToEsAAM2YOKBcP
XDbWUHDsyJ+irrnr6xkF8FODQiquQB/6+3q3hkyraygLL3+BAgMBAAGjgZ4wgZsw
LAYDVR0RBCUwI4IJbG9jYWxob3N0ggpsb2NhbGhvc3Qxggpsb2NhbGhvc3QyMAsG
A1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQULE3dVIhZ
P6Q0nONW/5UP4s5RIJUwHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84w
CQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEAd83SF5GmS3DeeWoggqNWo9Bq
uvd9bwBp0gYGC9rNSZ02/dDMvYrc4daJySMCihktFMrGBodmx/QyN5UN8accof5D
TzsDA+IaxvyR1Q2gfoJgFDEvbbj0V5iNBHSjgihtHLTeGnC9/nOst5bsfJttZMb4
ZznH6vSqSCa4FIXwAKuPvRqV4qdjkjUeNwTCcCwcVpWxg3CMmYgcim96og2E3U8O
Pov7Mc+u7rDk9sGN0ZipjRcfXVp56HyXq0C8qn7ECxkwrRiqnJvrPzXThpw6zOaa
LEfRuzZu8sXU4wxbxusw5g06Szqja2KTi2pZH0hmLtlwFLaqT9E7OF7meX+3AA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,25 @@
extensions = x509v3
[ x509v3 ]
subjectAltName = DNS:localhost,DNS:localhost1,DNS:localhost2
keyUsage = keyEncipherment,digitalSignature,keyAgreement
extendedKeyUsage = serverAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid
basicConstraints = CA:false
[ req ]
default_bits = 1024
distinguished_name = req_DN
default_md = sha256
string_mask = utf8only
[ req_DN ]
countryName = "Country Name is Northern Nowhere"
countryName_value = NN
organizationName = "Organization Name"
organizationName_value = Edel Curl Arctic Illudium Research Cloud
commonName = "Common Name"
commonName_value = localhost.nn
[something]
# The key
# the certificate
# some dhparam

Binary file not shown.

View File

@ -0,0 +1,6 @@
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDFhy779YiKOUxiiJ/7SgIcJ5Kd
C2WicB/Rt97IHYcoS5xLzPb2fIMfLXa+QSleMfojDC19yzjCi1SP/GpQbcfXr3L7
O6GnTcQb0g11fJJil0jE6BLAADNmDigXD1w21lBw7Mifoq656+sZBfBTg0IqrkAf
+vt6t4ZMq2soCy9/gQIDAQAB
-----END PUBLIC KEY-----

View File

@ -0,0 +1,14 @@
-----BEGIN X509 CRL-----
MIICDjCB9wIBATANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJOTjExMC8GA1UE
CgwoRWRlbCBDdXJsIEFyY3RpYyBJbGx1ZGl1bSBSZXNlYXJjaCBDbG91ZDEmMCQG
A1UEAwwdTm9ydGhlcm4gTm93aGVyZSBUcnVzdCBBbmNob3IXDTE2MDgzMDE4MzI1
N1oXDTE2MDkyOTE4MzI1N1owSzAXAgYNZJ8o86IXDTE2MDgzMDE4MzAxNVowFwIG
DWSfO0UqFw0xNjA4MzAxODMyMTVaMBcCBg1kn0GuixcNMTYwODMwMTgzMjU3WqAO
MAwwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQEFBQADggEBAE0v3zGBeKKuODAUugh7
l6bJi7Cs0CDhuBJ8wCpwL5XRGwWhYChJtEXWFUKLBhMarIPYKEv3f3rd8gtFII/8
wmnxoTL6eXZNL+FpHkZJ+blsHi73G7xzpB6kdFHIxI4tixwiUCe85u6WIRWkIEBs
kyPPAgbnosF37umQfEaBrweVy+EztrYw8jgd0oDBybQp25p7Noa0N4uDoDInuOgP
A7Q1Zf0ndWjrlEQtjMAUdA6blGKlb8BjMPtX50mbXuXctLeICns8TVUSQSiKU+oR
1QTgbkl+AfdaFlfNAum4a42bCLyeBQ/O31NydZbCE8o2q9PqPepAkL9dXhMLiK/a
tjA=
-----END X509 CRL-----

View File

@ -0,0 +1,80 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 14725819772555 (0xd649f41ae8b)
Signature Algorithm: sha1WithRSAEncryption
Issuer:
countryName = NN
organizationName = Edel Curl Arctic Illudium Research Cloud
commonName = Northern Nowhere Trust Anchor
Validity
Not Before: Aug 30 18:32:57 2016 GMT
Not After : Nov 16 18:32:57 2024 GMT
Subject:
countryName = NN
organizationName = Edel Curl Arctic Illudium Research Cloud
commonName = localhost.nn
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:a3:2a:75:d7:bf:75:41:40:be:42:b8:b9:00:28:
f1:45:29:55:bc:36:ca:a6:b7:86:93:97:25:84:aa:
c9:80:ac:41:d9:28:fb:b0:68:4b:5b:ee:bd:94:83:
da:2b:f6:cc:cc:11:df:fb:48:e6:e9:d5:97:41:7f:
9a:0d:b7:87:96:12:22:41:2a:7f:95:8a:14:d6:6c:
4b:34:df:18:29:01:0d:b2:3c:4d:c8:c4:5e:87:fa:
9f:aa:ee:a4:73:e9:bb:74:57:85:24:2a:51:e4:43:
5c:4b:97:51:52:b9:82:6e:9c:ce:ae:0f:91:45:25:
f9:b4:24:66:8e:47:1f:d7:d5
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:localhost1, DNS:localhost2, DNS:localhost
X509v3 Key Usage:
Digital Signature, Key Encipherment, Key Agreement
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Key Identifier:
2C:CF:E3:6E:08:F9:CE:9B:98:3B:B3:17:7F:0C:9D:E4:5B:1B:76:8A
X509v3 Authority Key Identifier:
keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE
X509v3 Basic Constraints:
CA:FALSE
Signature Algorithm: sha1WithRSAEncryption
2e:3d:c1:a2:a7:e4:70:f8:a8:13:86:c3:af:22:1f:e9:e1:62:
f4:cf:16:66:a8:3b:70:f6:12:30:be:fe:8e:44:1b:71:b5:c1:
e0:4b:66:c4:5d:d4:d7:7d:49:43:4a:6d:22:1b:ce:3d:e3:14:
14:b3:6d:3a:93:39:0c:9b:2c:83:35:1d:7e:7c:29:29:3c:51:
6b:27:c3:5b:2d:f2:61:18:f8:c7:90:be:3b:68:3f:08:9b:ac:
68:01:d2:0c:ec:aa:5d:9e:78:b7:8b:84:04:01:b2:08:ef:df:
0c:f2:29:99:fe:61:d1:65:80:aa:ef:df:8e:28:55:a6:f9:88:
0c:01:bb:fc:1c:9e:9c:08:8d:c5:34:24:91:c1:ac:71:22:e1:
12:78:e0:45:d5:e2:39:c4:3c:16:09:80:d0:5b:bc:49:0a:4c:
a3:5b:e1:36:40:ed:26:6d:8d:a0:d3:4a:3c:86:93:2f:d4:0a:
3c:72:08:62:d7:66:d0:b3:05:c2:0f:1d:af:3c:65:67:f2:6c:
76:a5:9c:37:ac:c4:ac:96:b7:e4:c0:ef:a4:5b:28:1e:16:09:
15:f6:7b:bb:5d:a2:94:9a:df:52:7b:ae:c9:39:f4:18:9e:84:
57:6c:d3:6d:ae:35:38:8f:8f:9b:0d:df:77:69:ae:25:ec:ce:
d0:2b:bd:8d
-----BEGIN CERTIFICATE-----
MIIDWjCCAkKgAwIBAgIGDWSfQa6LMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT
Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo
IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe
Fw0xNjA4MzAxODMyNTdaFw0yNDExMTYxODMyNTdaMFcxCzAJBgNVBAYTAk5OMTEw
LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk
MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
AoGBAKMqdde/dUFAvkK4uQAo8UUpVbw2yqa3hpOXJYSqyYCsQdko+7BoS1vuvZSD
2iv2zMwR3/tI5unVl0F/mg23h5YSIkEqf5WKFNZsSzTfGCkBDbI8TcjEXof6n6ru
pHPpu3RXhSQqUeRDXEuXUVK5gm6czq4PkUUl+bQkZo5HH9fVAgMBAAGjgZ4wgZsw
LAYDVR0RBCUwI4IKbG9jYWxob3N0MYIKbG9jYWxob3N0MoIJbG9jYWxob3N0MAsG
A1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQULM/jbgj5
zpuYO7MXfwyd5FsbdoowHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84w
CQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEALj3BoqfkcPioE4bDryIf6eFi
9M8WZqg7cPYSML7+jkQbcbXB4EtmxF3U131JQ0ptIhvOPeMUFLNtOpM5DJssgzUd
fnwpKTxRayfDWy3yYRj4x5C+O2g/CJusaAHSDOyqXZ54t4uEBAGyCO/fDPIpmf5h
0WWAqu/fjihVpvmIDAG7/ByenAiNxTQkkcGscSLhEnjgRdXiOcQ8FgmA0Fu8SQpM
o1vhNkDtJm2NoNNKPIaTL9QKPHIIYtdm0LMFwg8drzxlZ/JsdqWcN6zErJa35MDv
pFsoHhYJFfZ7u12ilJrfUnuuyTn0GJ6EV2zTba41OI+Pmw3fd2muJezO0Cu9jQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,11 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIBlzCCAQACAQAwVzELMAkGA1UEBhMCTk4xMTAvBgNVBAoMKEVkZWwgQ3VybCBB
cmN0aWMgSWxsdWRpdW0gUmVzZWFyY2ggQ2xvdWQxFTATBgNVBAMMDGxvY2FsaG9z
dC5ubjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAoyp11791QUC+Qri5ACjx
RSlVvDbKpreGk5clhKrJgKxB2Sj7sGhLW+69lIPaK/bMzBHf+0jm6dWXQX+aDbeH
lhIiQSp/lYoU1mxLNN8YKQENsjxNyMReh/qfqu6kc+m7dFeFJCpR5ENcS5dRUrmC
bpzOrg+RRSX5tCRmjkcf19UCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4GBACoIAlf0
hSnZJOBBt7FS7iXlNRyKZAD881jhHFux+Gxq3gtbJsP57c+ALZ3MswjjUXW0Iq11
IZLeZQGCAHYp4/GuTHbaq0qo1LjgpTqgQfwEB3BqNGs6yJiST+3risgawFbfqEDY
LCm7rs/yyaOdMjwdwrUMciSv5KtlXZ1VThyt
-----END CERTIFICATE REQUEST-----

Binary file not shown.

View File

@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCjKnXXv3VBQL5CuLkAKPFFKVW8Nsqmt4aTlyWEqsmArEHZKPuw
aEtb7r2Ug9or9szMEd/7SObp1ZdBf5oNt4eWEiJBKn+VihTWbEs03xgpAQ2yPE3I
xF6H+p+q7qRz6bt0V4UkKlHkQ1xLl1FSuYJunM6uD5FFJfm0JGaORx/X1QIDAQAB
AoGAaC2QGDSSNRuVXxx6YnPBuJrvtsB1G4VKU6nJtq8lARb65CCassOkegow2UZm
YnOtxw4SqGqfpOVPMe66+c8Yrd+6zimC7VorxmfhNxqOO34bxzztKKk8Q7c+odl3
+c4aVnFBk2hzuOW4PuJoFfFNQZWmh/XJdKK85X+bkryS/oECQQDTdzwYyDxvrPaw
ZeR5oDleopk5W5QwmBAq4ehtie1oZfhzlNZzPOjnI9I71MRYdCwkesKHL2k6q7cT
jA4sSmx5AkEAxYc6+o8l0/HE8HzypWe/ZfozaY3ccIFzmvcwQorbCvAxDtZ1DbFy
VWLOgM/6gwDIUDF6ckaInaVmiVJl60Y3PQJAZFBOuO7cBJoHWDytuqiwLl1x1EzG
KpsoKD+MU9I3RewBhUrYxEfjsCpFA8716YQKoK9/ckOiZouoyGQLISWY+QJAG5id
AMxm+Ilafk62h61K7DBcZm7PUViEki3erC1CFPEhqXUEvXkBBDTdrNlholPFqI6B
EN4R0BR/ksfUPV598QJAF8jl/8gz8pmAWmqw8tKbWdQeDgisyTHeYlPMxq4fUbLH
mJk05csSX9CTg4eO7NRRwPxODKmPCd88sZZSOuTQmQ==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,120 @@
extensions = x509v3
[ x509v3 ]
subjectAltName = DNS:localhost1,DNS:localhost2,DNS:localhost
keyUsage = keyEncipherment,digitalSignature,keyAgreement
extendedKeyUsage = serverAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid
basicConstraints = CA:false
[ req ]
default_bits = 1024
distinguished_name = req_DN
default_md = sha256
string_mask = utf8only
[ req_DN ]
countryName = "Country Name is Northern Nowhere"
countryName_value = NN
organizationName = "Organization Name"
organizationName_value = Edel Curl Arctic Illudium Research Cloud
commonName = "Common Name"
commonName_value = localhost.nn
[something]
# The key
# the certificate
# some dhparam
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQCjKnXXv3VBQL5CuLkAKPFFKVW8Nsqmt4aTlyWEqsmArEHZKPuw
aEtb7r2Ug9or9szMEd/7SObp1ZdBf5oNt4eWEiJBKn+VihTWbEs03xgpAQ2yPE3I
xF6H+p+q7qRz6bt0V4UkKlHkQ1xLl1FSuYJunM6uD5FFJfm0JGaORx/X1QIDAQAB
AoGAaC2QGDSSNRuVXxx6YnPBuJrvtsB1G4VKU6nJtq8lARb65CCassOkegow2UZm
YnOtxw4SqGqfpOVPMe66+c8Yrd+6zimC7VorxmfhNxqOO34bxzztKKk8Q7c+odl3
+c4aVnFBk2hzuOW4PuJoFfFNQZWmh/XJdKK85X+bkryS/oECQQDTdzwYyDxvrPaw
ZeR5oDleopk5W5QwmBAq4ehtie1oZfhzlNZzPOjnI9I71MRYdCwkesKHL2k6q7cT
jA4sSmx5AkEAxYc6+o8l0/HE8HzypWe/ZfozaY3ccIFzmvcwQorbCvAxDtZ1DbFy
VWLOgM/6gwDIUDF6ckaInaVmiVJl60Y3PQJAZFBOuO7cBJoHWDytuqiwLl1x1EzG
KpsoKD+MU9I3RewBhUrYxEfjsCpFA8716YQKoK9/ckOiZouoyGQLISWY+QJAG5id
AMxm+Ilafk62h61K7DBcZm7PUViEki3erC1CFPEhqXUEvXkBBDTdrNlholPFqI6B
EN4R0BR/ksfUPV598QJAF8jl/8gz8pmAWmqw8tKbWdQeDgisyTHeYlPMxq4fUbLH
mJk05csSX9CTg4eO7NRRwPxODKmPCd88sZZSOuTQmQ==
-----END RSA PRIVATE KEY-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 14725819772555 (0xd649f41ae8b)
Signature Algorithm: sha1WithRSAEncryption
Issuer:
countryName = NN
organizationName = Edel Curl Arctic Illudium Research Cloud
commonName = Northern Nowhere Trust Anchor
Validity
Not Before: Aug 30 18:32:57 2016 GMT
Not After : Nov 16 18:32:57 2024 GMT
Subject:
countryName = NN
organizationName = Edel Curl Arctic Illudium Research Cloud
commonName = localhost.nn
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (1024 bit)
Modulus:
00:a3:2a:75:d7:bf:75:41:40:be:42:b8:b9:00:28:
f1:45:29:55:bc:36:ca:a6:b7:86:93:97:25:84:aa:
c9:80:ac:41:d9:28:fb:b0:68:4b:5b:ee:bd:94:83:
da:2b:f6:cc:cc:11:df:fb:48:e6:e9:d5:97:41:7f:
9a:0d:b7:87:96:12:22:41:2a:7f:95:8a:14:d6:6c:
4b:34:df:18:29:01:0d:b2:3c:4d:c8:c4:5e:87:fa:
9f:aa:ee:a4:73:e9:bb:74:57:85:24:2a:51:e4:43:
5c:4b:97:51:52:b9:82:6e:9c:ce:ae:0f:91:45:25:
f9:b4:24:66:8e:47:1f:d7:d5
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:localhost1, DNS:localhost2, DNS:localhost
X509v3 Key Usage:
Digital Signature, Key Encipherment, Key Agreement
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Key Identifier:
2C:CF:E3:6E:08:F9:CE:9B:98:3B:B3:17:7F:0C:9D:E4:5B:1B:76:8A
X509v3 Authority Key Identifier:
keyid:12:CA:BA:4B:46:04:A7:75:8A:2C:E8:0E:54:94:BC:12:65:A6:7B:CE
X509v3 Basic Constraints:
CA:FALSE
Signature Algorithm: sha1WithRSAEncryption
2e:3d:c1:a2:a7:e4:70:f8:a8:13:86:c3:af:22:1f:e9:e1:62:
f4:cf:16:66:a8:3b:70:f6:12:30:be:fe:8e:44:1b:71:b5:c1:
e0:4b:66:c4:5d:d4:d7:7d:49:43:4a:6d:22:1b:ce:3d:e3:14:
14:b3:6d:3a:93:39:0c:9b:2c:83:35:1d:7e:7c:29:29:3c:51:
6b:27:c3:5b:2d:f2:61:18:f8:c7:90:be:3b:68:3f:08:9b:ac:
68:01:d2:0c:ec:aa:5d:9e:78:b7:8b:84:04:01:b2:08:ef:df:
0c:f2:29:99:fe:61:d1:65:80:aa:ef:df:8e:28:55:a6:f9:88:
0c:01:bb:fc:1c:9e:9c:08:8d:c5:34:24:91:c1:ac:71:22:e1:
12:78:e0:45:d5:e2:39:c4:3c:16:09:80:d0:5b:bc:49:0a:4c:
a3:5b:e1:36:40:ed:26:6d:8d:a0:d3:4a:3c:86:93:2f:d4:0a:
3c:72:08:62:d7:66:d0:b3:05:c2:0f:1d:af:3c:65:67:f2:6c:
76:a5:9c:37:ac:c4:ac:96:b7:e4:c0:ef:a4:5b:28:1e:16:09:
15:f6:7b:bb:5d:a2:94:9a:df:52:7b:ae:c9:39:f4:18:9e:84:
57:6c:d3:6d:ae:35:38:8f:8f:9b:0d:df:77:69:ae:25:ec:ce:
d0:2b:bd:8d
-----BEGIN CERTIFICATE-----
MIIDWjCCAkKgAwIBAgIGDWSfQa6LMA0GCSqGSIb3DQEBBQUAMGgxCzAJBgNVBAYT
Ak5OMTEwLwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNo
IENsb3VkMSYwJAYDVQQDDB1Ob3J0aGVybiBOb3doZXJlIFRydXN0IEFuY2hvcjAe
Fw0xNjA4MzAxODMyNTdaFw0yNDExMTYxODMyNTdaMFcxCzAJBgNVBAYTAk5OMTEw
LwYDVQQKDChFZGVsIEN1cmwgQXJjdGljIElsbHVkaXVtIFJlc2VhcmNoIENsb3Vk
MRUwEwYDVQQDDAxsb2NhbGhvc3Qubm4wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
AoGBAKMqdde/dUFAvkK4uQAo8UUpVbw2yqa3hpOXJYSqyYCsQdko+7BoS1vuvZSD
2iv2zMwR3/tI5unVl0F/mg23h5YSIkEqf5WKFNZsSzTfGCkBDbI8TcjEXof6n6ru
pHPpu3RXhSQqUeRDXEuXUVK5gm6czq4PkUUl+bQkZo5HH9fVAgMBAAGjgZ4wgZsw
LAYDVR0RBCUwI4IKbG9jYWxob3N0MYIKbG9jYWxob3N0MoIJbG9jYWxob3N0MAsG
A1UdDwQEAwIDqDATBgNVHSUEDDAKBggrBgEFBQcDATAdBgNVHQ4EFgQULM/jbgj5
zpuYO7MXfwyd5FsbdoowHwYDVR0jBBgwFoAUEsq6S0YEp3WKLOgOVJS8EmWme84w
CQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOCAQEALj3BoqfkcPioE4bDryIf6eFi
9M8WZqg7cPYSML7+jkQbcbXB4EtmxF3U131JQ0ptIhvOPeMUFLNtOpM5DJssgzUd
fnwpKTxRayfDWy3yYRj4x5C+O2g/CJusaAHSDOyqXZ54t4uEBAGyCO/fDPIpmf5h
0WWAqu/fjihVpvmIDAG7/ByenAiNxTQkkcGscSLhEnjgRdXiOcQ8FgmA0Fu8SQpM
o1vhNkDtJm2NoNNKPIaTL9QKPHIIYtdm0LMFwg8drzxlZ/JsdqWcN6zErJa35MDv
pFsoHhYJFfZ7u12ilJrfUnuuyTn0GJ6EV2zTba41OI+Pmw3fd2muJezO0Cu9jQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,25 @@
extensions = x509v3
[ x509v3 ]
subjectAltName = DNS:localhost1,DNS:localhost2,DNS:localhost
keyUsage = keyEncipherment,digitalSignature,keyAgreement
extendedKeyUsage = serverAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid
basicConstraints = CA:false
[ req ]
default_bits = 1024
distinguished_name = req_DN
default_md = sha256
string_mask = utf8only
[ req_DN ]
countryName = "Country Name is Northern Nowhere"
countryName_value = NN
organizationName = "Organization Name"
organizationName_value = Edel Curl Arctic Illudium Research Cloud
commonName = "Common Name"
commonName_value = localhost.nn
[something]
# The key
# the certificate
# some dhparam

Binary file not shown.

View File

@ -0,0 +1,6 @@
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjKnXXv3VBQL5CuLkAKPFFKVW8
Nsqmt4aTlyWEqsmArEHZKPuwaEtb7r2Ug9or9szMEd/7SObp1ZdBf5oNt4eWEiJB
Kn+VihTWbEs03xgpAQ2yPE3IxF6H+p+q7qRz6bt0V4UkKlHkQ1xLl1FSuYJunM6u
D5FFJfm0JGaORx/X1QIDAQAB
-----END PUBLIC KEY-----

View File

@ -195,4 +195,6 @@ test2048 test2049 test2050 test2051 test2052 test2053 test2054 test2055 \
test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \ test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \
test2064 test2065 test2066 test2067 test2068 test2069 \ test2064 test2065 test2066 test2067 test2068 test2069 \
\ \
test2070 test2071 test2072 test2073 test2070 test2071 test2072 test2073 \
\
test3000 test3001

57
tests/data/test3000 Normal file
View File

@ -0,0 +1,57 @@
<testcase>
<info>
<keywords>
HTTPS
HTTP GET
PEM certificate
</keywords>
</info>
#
# Server-side
<reply>
<data>
HTTP/1.1 200 OK
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Content-Length: 7
MooMoo
</data>
</reply>
#
# Client-side
<client>
<features>
SSL
</features>
<server>
https Server-localhost-firstSAN-sv.pem
</server>
<name>
HTTPS GET to localhost, first subject alt name matches, CN does not match
</name>
<command>
--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt https://localhost:%HTTPSPORT/3000
</command>
# Ensure that we're running on localhost because we're checking the host name
<precheck>
perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0.0.1' );"
</precheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
GET /3000 HTTP/1.1
Host: localhost:%HTTPSPORT
Accept: */*
</protocol>
</verify>
</testcase>

57
tests/data/test3001 Normal file
View File

@ -0,0 +1,57 @@
<testcase>
<info>
<keywords>
HTTPS
HTTP GET
PEM certificate
</keywords>
</info>
#
# Server-side
<reply>
<data>
HTTP/1.1 200 OK
Date: Thu, 09 Nov 2010 14:49:00 GMT
Server: test-server/fake
Content-Length: 7
MooMoo
</data>
</reply>
#
# Client-side
<client>
<features>
SSL
</features>
<server>
https Server-localhost-lastSAN-sv.pem
</server>
<name>
HTTPS GET to localhost, last subject alt name matches, CN does not match
</name>
<command>
--cacert %SRCDIR/certs/EdelCurlRoot-ca.crt https://localhost:%HTTPSPORT/3001
</command>
# Ensure that we're running on localhost because we're checking the host name
<precheck>
perl -e "print 'Test requires default test server host' if ( '%HOSTIP' ne '127.0.0.1' );"
</precheck>
</client>
#
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
GET /3001 HTTP/1.1
Host: localhost:%HTTPSPORT
Accept: */*
</protocol>
</verify>
</testcase>

View File

@ -82,7 +82,7 @@ LFLAGS_PDB = /incremental:no /opt:ref,icf /DEBUG
CFLAGS_LIBCURL_STATIC = /DCURL_STATICLIB CFLAGS_LIBCURL_STATIC = /DCURL_STATICLIB
WIN_LIBS = ws2_32.lib wldap32.lib advapi32.lib WIN_LIBS = ws2_32.lib wldap32.lib advapi32.lib crypt32.lib
BASE_NAME = libcurl BASE_NAME = libcurl
BASE_NAME_DEBUG = $(BASE_NAME)_debug BASE_NAME_DEBUG = $(BASE_NAME)_debug