MCPcopy Create free account
hub / github.com/apache/qpid-proton / verify_peer

Function verify_peer

c/src/ssl/schannel.cpp:2117–2351  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2115}
2116
2117static HRESULT verify_peer(pni_ssl_t *ssl, HCERTSTORE root_store, const char *server_name, bool tracing)
2118{
2119 // Free/release the following before return:
2120 PCCERT_CONTEXT peer_cc = 0;
2121 PCCERT_CONTEXT trust_anchor = 0;
2122 PCCERT_CHAIN_CONTEXT chain_context = 0;
2123 wchar_t *nameUCS2 = 0;
2124
2125 if (server_name && strlen(server_name) > 255) {
2126 ssl_log_error("invalid server name: %s", server_name);
2127 return WSAENAMETOOLONG;
2128 }
2129
2130 // Get peer's certificate.
2131 SECURITY_STATUS status;
2132 status = QueryContextAttributes(&ssl->ctxt_handle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &peer_cc);
2133 if (status != SEC_E_OK) {
2134 ssl_log_error_status(status, "can't obtain remote peer certificate information");
2135 return status;
2136 }
2137
2138 // Build the peer's certificate chain. Multiple chains may be built but we
2139 // care about rgpChain[0], which is the best. Custom root stores are not
2140 // allowed until W8/server 2012: see CERT_CHAIN_ENGINE_CONFIG. For now, we
2141 // manually override to taste.
2142
2143 // Chain verification functions give false reports for CRL if the trust anchor
2144 // is not in the official root store. We ignore CRL completely if it doesn't
2145 // apply to any untrusted certs in the chain, and defer to SChannel's veto
2146 // otherwise. To rely on CRL, the CA must be in both the official system
2147 // trusted root store and the Proton cred->trust_store. To defeat CRL, the
2148 // most distal cert with CRL must be placed in the Proton cred->trust_store.
2149 // Similarly, certificate usage checking is overly strict at times.
2150
2151 CERT_CHAIN_PARA desc;
2152 memset(&desc, 0, sizeof(desc));
2153 desc.cbSize = sizeof(desc);
2154
2155 LPSTR usages[] = { szOID_PKIX_KP_SERVER_AUTH };
2156 DWORD n_usages = sizeof(usages) / sizeof(LPSTR);
2157 desc.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR;
2158 desc.RequestedUsage.Usage.cUsageIdentifier = n_usages;
2159 desc.RequestedUsage.Usage.rgpszUsageIdentifier = usages;
2160
2161 if(!CertGetCertificateChain(0, peer_cc, 0, peer_cc->hCertStore, &desc,
2162 CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT |
2163 CERT_CHAIN_CACHE_END_CERT,
2164 0, &chain_context)){
2165 HRESULT st = GetLastError();
2166 ssl_log_error_status(st, "Basic certificate chain check failed");
2167 CertFreeCertificateContext(peer_cc);
2168 return st;
2169 }
2170 if (chain_context->cChain < 1 || chain_context->rgpChain[0]->cElement < 1) {
2171 ssl_log_error("empty chain with status %x %x", chain_context->TrustStatus.dwErrorStatus,
2172 chain_context->TrustStatus.dwInfoStatus);
2173 return SEC_E_CERT_UNKNOWN;
2174 }

Callers 2

client_handshakeFunction · 0.85
server_handshakeFunction · 0.85

Calls 4

ssl_log_error_statusFunction · 0.85
store_containsFunction · 0.85
server_name_matchesFunction · 0.85
ssl_log_errorFunction · 0.70

Tested by

no test coverage detected