diff options
| author | Han Han <hhan@thousandeyes.com> | 2018-08-15 19:57:16 -0700 | 
|---|---|---|
| committer | Daniel Stenberg <daniel@haxx.se> | 2018-09-06 08:27:15 +0200 | 
| commit | 5a3efb1dba509b269953ff684f61e682fec14bf5 (patch) | |
| tree | 3ed6965b426614cb6e9898f11661d9dc295670f1 /lib | |
| parent | 84a23a0997dc3f1e062bd809fbe47e202fb0a193 (diff) | |
schannel: unified error code handling
Closes #2901
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/vtls/schannel.c | 99 | ||||
| -rw-r--r-- | lib/vtls/schannel_verify.c | 2 | 
2 files changed, 71 insertions, 30 deletions
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c index 8f6c301d1..e7d1e3dde 100644 --- a/lib/vtls/schannel.c +++ b/lib/vtls/schannel.c @@ -363,7 +363,7 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,    sep = _tcschr(path, TEXT('\\'));    if(sep == NULL) -    return CURLE_SSL_CONNECT_ERROR; +    return CURLE_SSL_CERTPROBLEM;    store_name_len = sep - path; @@ -387,19 +387,19 @@ get_cert_location(TCHAR *path, DWORD *store_name, TCHAR **store_path,                      store_name_len) == 0)      *store_name = CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE;    else -    return CURLE_SSL_CONNECT_ERROR; +    return CURLE_SSL_CERTPROBLEM;    *store_path = sep + 1;    sep = _tcschr(*store_path, TEXT('\\'));    if(sep == NULL) -    return CURLE_SSL_CONNECT_ERROR; +    return CURLE_SSL_CERTPROBLEM;    *sep = 0;    *thumbprint = sep + 1;    if(_tcslen(*thumbprint) != CERT_THUMBPRINT_STR_LEN) -    return CURLE_SSL_CONNECT_ERROR; +    return CURLE_SSL_CERTPROBLEM;    return CURLE_OK;  } @@ -612,7 +612,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)                "last error is %x",                cert_store_name, cert_store_path, GetLastError());          Curl_unicodefree(cert_path); -        return CURLE_SSL_CONNECT_ERROR; +        return CURLE_SSL_CERTPROBLEM;        }        cert_thumbprint.pbData = cert_thumbprint_data; @@ -623,7 +623,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)                                cert_thumbprint_data, &cert_thumbprint.cbData,                                NULL, NULL)) {          Curl_unicodefree(cert_path); -        return CURLE_SSL_CONNECT_ERROR; +        return CURLE_SSL_CERTPROBLEM;        }        client_certs[0] = CertFindCertificateInStore( @@ -636,6 +636,10 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)          schannel_cred.cCreds = 1;          schannel_cred.paCred = client_certs;        } +      else { +        /* CRYPT_E_NOT_FOUND / E_INVALIDARG */ +        return CURLE_SSL_CERTPROBLEM; +      }        CertCloseStore(cert_store, 0);      } @@ -672,14 +676,20 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)        CertFreeCertificateContext(client_certs[0]);      if(sspi_status != SEC_E_OK) { -      if(sspi_status == SEC_E_WRONG_PRINCIPAL) -        failf(data, "schannel: SNI or certificate check failed: %s", -              Curl_sspi_strerror(conn, sspi_status)); -      else -        failf(data, "schannel: AcquireCredentialsHandle failed: %s", -              Curl_sspi_strerror(conn, sspi_status)); +      failf(data, "schannel: AcquireCredentialsHandle failed: %s", +            Curl_sspi_strerror(conn, sspi_status));        Curl_safefree(BACKEND->cred); -      return CURLE_SSL_CONNECT_ERROR; +      switch(sspi_status) { +        case SEC_E_INSUFFICIENT_MEMORY: +          return CURLE_OUT_OF_MEMORY; +        case SEC_E_NO_CREDENTIALS: +        case SEC_E_SECPKG_NOT_FOUND: +        case SEC_E_NOT_OWNER: +        case SEC_E_UNKNOWN_CREDENTIALS: +        case SEC_E_INTERNAL_ERROR: +        default: +          return CURLE_SSL_CONNECT_ERROR; +      }      }    } @@ -782,14 +792,30 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)    Curl_unicodefree(host_name);    if(sspi_status != SEC_I_CONTINUE_NEEDED) { -    if(sspi_status == SEC_E_WRONG_PRINCIPAL) -      failf(data, "schannel: SNI or certificate check failed: %s", -            Curl_sspi_strerror(conn, sspi_status)); -    else -      failf(data, "schannel: initial InitializeSecurityContext failed: %s", -            Curl_sspi_strerror(conn, sspi_status));      Curl_safefree(BACKEND->ctxt); -    return CURLE_SSL_CONNECT_ERROR; +    switch(sspi_status) { +      case SEC_E_INSUFFICIENT_MEMORY: +        failf(data, "schannel: initial InitializeSecurityContext failed: %s", +              Curl_sspi_strerror(conn, sspi_status)); +        return CURLE_OUT_OF_MEMORY; +      case SEC_E_WRONG_PRINCIPAL: +        failf(data, "schannel: SNI or certificate check failed: %s", +              Curl_sspi_strerror(conn, sspi_status)); +        return CURLE_PEER_FAILED_VERIFICATION; +      case SEC_E_INVALID_HANDLE: +      case SEC_E_INVALID_TOKEN: +      case SEC_E_LOGON_DENIED: +      case SEC_E_TARGET_UNKNOWN: +      case SEC_E_NO_AUTHENTICATING_AUTHORITY: +      case SEC_E_INTERNAL_ERROR: +      case SEC_E_NO_CREDENTIALS: +      case SEC_E_UNSUPPORTED_FUNCTION: +      case SEC_E_APPLICATION_PROTOCOL_MISMATCH: +      default: +        failf(data, "schannel: initial InitializeSecurityContext failed: %s", +              Curl_sspi_strerror(conn, sspi_status)); +        return CURLE_SSL_CONNECT_ERROR; +    }    }    infof(data, "schannel: sending initial handshake data: " @@ -1004,14 +1030,29 @@ schannel_connect_step2(struct connectdata *conn, int sockindex)        }      }      else { -      if(sspi_status == SEC_E_WRONG_PRINCIPAL) -        failf(data, "schannel: SNI or certificate check failed: %s", -              Curl_sspi_strerror(conn, sspi_status)); -      else -        failf(data, "schannel: next InitializeSecurityContext failed: %s", -              Curl_sspi_strerror(conn, sspi_status)); -      return sspi_status == SEC_E_UNTRUSTED_ROOT ? -          CURLE_SSL_CACERT : CURLE_SSL_CONNECT_ERROR; +      switch(sspi_status) { +        case SEC_E_INSUFFICIENT_MEMORY: +          failf(data, "schannel: next InitializeSecurityContext failed: %s", +                Curl_sspi_strerror(conn, sspi_status)); +          return CURLE_OUT_OF_MEMORY; +        case SEC_E_WRONG_PRINCIPAL: +          failf(data, "schannel: SNI or certificate check failed: %s", +                Curl_sspi_strerror(conn, sspi_status)); +          return CURLE_PEER_FAILED_VERIFICATION; +        case SEC_E_INVALID_HANDLE: +        case SEC_E_INVALID_TOKEN: +        case SEC_E_LOGON_DENIED: +        case SEC_E_TARGET_UNKNOWN: +        case SEC_E_NO_AUTHENTICATING_AUTHORITY: +        case SEC_E_INTERNAL_ERROR: +        case SEC_E_NO_CREDENTIALS: +        case SEC_E_UNSUPPORTED_FUNCTION: +        case SEC_E_APPLICATION_PROTOCOL_MISMATCH: +        default: +          failf(data, "schannel: next InitializeSecurityContext failed: %s", +                Curl_sspi_strerror(conn, sspi_status)); +          return CURLE_SSL_CONNECT_ERROR; +      }      }      /* check if there was additional remaining encrypted data */ @@ -1192,7 +1233,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)      if((sspi_status != SEC_E_OK) || (ccert_context == NULL)) {        failf(data, "schannel: failed to retrieve remote cert context"); -      return CURLE_SSL_CONNECT_ERROR; +      return CURLE_PEER_FAILED_VERIFICATION;      }      result = Curl_ssl_init_certinfo(data, 1); diff --git a/lib/vtls/schannel_verify.c b/lib/vtls/schannel_verify.c index 5a7092a21..27d28e218 100644 --- a/lib/vtls/schannel_verify.c +++ b/lib/vtls/schannel_verify.c @@ -135,7 +135,7 @@ static CURLcode add_certs_to_store(HCERTSTORE trust_store,      failf(data,            "schannel: CA file exceeds max size of %u bytes",            MAX_CAFILE_SIZE); -    result = CURLE_OUT_OF_MEMORY; +    result = CURLE_SSL_CACERT_BADFILE;      goto cleanup;    }  | 
