diff --git a/doc/Developing.md b/doc/Developing.md index 25be453796..730d9593b8 100644 --- a/doc/Developing.md +++ b/doc/Developing.md @@ -40,6 +40,12 @@ To enable step-through debugging, right click on `AppInstallerCLIPackage` in the The best way to debug the client is to select `Do not launch, but debug my code when it starts` in the `Debug` tab and start the debugging session with F5. You can then use the `wingetdev` command in a terminal session, or any PowerShell code for COM API interaction, which will get picked up by the debugger. +## Architecture Documentation + +For information on specific aspects of the codebase architecture: + +* [Secure Connection Architecture](SecureConnectionArchitecture.md) - Documentation on HTTPS/TLS implementation for secure downloads + ## Running Unit Tests The unit tests are located inside the `AppInstallerCLITests` project. When the solution is built, all tests are compiled under `src///AppInstallerCLITests`. An executable `AppInstallerCLITests.exe` is generated in this directory to run the tests. Run `AppInstallerCLITests.exe` from the command line to execute the tests. To see all available options, run `AppInstallerCLITests.exe --help`. diff --git a/doc/SecureConnectionArchitecture.md b/doc/SecureConnectionArchitecture.md new file mode 100644 index 0000000000..ad13c73e90 --- /dev/null +++ b/doc/SecureConnectionArchitecture.md @@ -0,0 +1,212 @@ +# WinGet Secure Connection Architecture for Installer Downloads + +This document describes where and how WinGet implements secure connections (HTTPS/TLS) when downloading installers. + +## Overview + +WinGet uses a multi-layered approach to ensure secure downloads of installers: +1. **WinINet API** - Primary download method using Windows built-in networking +2. **Delivery Optimization (DO)** - Fallback/alternative download method +3. **Certificate Pinning** - Additional security layer for validating server certificates +4. **HTTP Client (WinHTTP)** - Used for REST API interactions + +## Core Download Implementation + +### Primary Download Path: WinINet + +**Location:** `src/AppInstallerCommonCore/Downloader.cpp` + +The main download functionality uses the WinINet API which provides: +- Automatic HTTPS/TLS support through Windows +- Built-in certificate validation via Windows Certificate Store +- Support for HTTP to HTTPS redirects + +**Key Functions:** +- `InternetOpen()` - Initializes WinINet session with HTTPS/TLS support (lines 146-151 for proxy, 155-160 for no proxy) +- `InternetOpenUrl()` - Opens URL connection with security flags (lines 178-184) + - Uses `INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTPS` to allow HTTP→HTTPS redirects +- `InternetReadFile()` - Reads data from secure connection (line 247) + +**Security Features:** +- Inherits Windows OS TLS/SSL configuration +- Validates server certificates against Windows Certificate Store +- Supports proxy configurations with secure connections +- Automatic handling of HTTPS protocol + +### Alternative Download: Delivery Optimization + +**Location:** `src/AppInstallerCommonCore/DODownloader.cpp` + +Provides an alternative download path using Windows Delivery Optimization service: +- Optimizes bandwidth usage +- Supports peer-to-peer delivery +- Uses HTTPS for secure connections +- Built on top of Windows DO service security features + +## Certificate Pinning System + +### Certificate Validation Framework + +**Location:** `src/AppInstallerSharedLib/Public/winget/Certificates.h` +**Implementation:** `src/AppInstallerSharedLib/Certificates.cpp` + +Provides advanced certificate validation beyond standard Windows certificate validation: + +**Key Components:** + +1. **PinningDetails** - Defines specific certificate properties to validate: + - Public key pinning (`PinningVerificationType::PublicKey`) + - Subject validation (`PinningVerificationType::Subject`) + - Issuer validation (`PinningVerificationType::Issuer`) + - Support for partial certificate chains + +2. **PinningChain** - Validates full certificate chain: + - Root certificate validation + - Intermediate certificate validation + - Leaf certificate validation + - Partial chain support for flexible validation + +3. **PinningConfiguration** - Main configuration interface: + - Manages multiple acceptable certificate chains + - Validates certificates against pinning rules + - Caches validated certificates for performance + +### Certificate Resources + +**Location:** `src/CertificateResources/` + +Contains embedded certificate files: +- `Microsoft_TLS_ECC_Root_G2.crt` - Microsoft TLS ECC Root Certificate +- `Microsoft_TLS_RSA_Root_G2.crt` - Microsoft TLS RSA Root Certificate +- Additional intermediate and root certificates + +These certificates are used for pinning validation to ensure connections are to trusted Microsoft services. + +## HTTP Client for REST APIs + +### WinHTTP-based HTTP Client + +**Location:** `src/AppInstallerCommonCore/HttpClientHelper.cpp` + +Used for REST API interactions (repository metadata, etc.): + +**Key Security Functions:** + +1. **Certificate Validation Callback** (lines 28-44): + ```cpp + void NativeHandleServerCertificateValidation( + web::http::client::native_handle handle, + const Certificates::PinningConfiguration& pinningConfiguration, + ThreadLocalStorage::ThreadGlobals* threadGlobals) + ``` + - Retrieves server certificate using `WinHttpQueryOption()` + - Validates against pinning configuration + - Throws `APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH` on failure + +2. **Setting Pinning Configuration** (lines 188-194): + ```cpp + void HttpClientHelper::SetPinningConfiguration( + const Certificates::PinningConfiguration& configuration, + std::shared_ptr threadGlobals) + ``` + - Configures custom certificate validation + - Integrates pinning configuration with HTTP client + +**Security Features:** +- Uses WinHTTP native API for HTTPS connections +- Custom certificate validation via `set_nativehandle_servercertificate_validation` +- Built-in TLS/SSL support through Windows +- Proxy support with secure connections + +### HTTP Streaming Components + +**Location:** `src/AppInstallerCommonCore/HttpStream/` + +Additional HTTP functionality for streaming downloads: +- `HttpClientWrapper.cpp/h` - Wrapper around Windows.Web.Http client +- `HttpRandomAccessStream.cpp/h` - Random access streaming for HTTP downloads +- `HttpLocalCache.cpp/h` - Local caching for HTTP content + +All components leverage Windows.Web.Http which provides: +- Automatic HTTPS/TLS handling +- Certificate validation +- Secure connection management + +## Network Configuration + +### Network Settings + +**Location:** `src/AppInstallerCommonCore/Public/winget/NetworkSettings.h` +**Implementation:** Network settings management + +Provides configuration for: +- Proxy settings (applies to secure connections) +- Network timeout configurations +- Connection retry logic + +### Authentication + +**Location:** `src/AppInstallerCommonCore/Authentication/` + +Contains authentication mechanisms that work over secure connections: +- `Authentication.cpp` - Core authentication framework +- `WebAccountManagerAuthenticator.cpp` - Web account integration +- All authentication data transmitted over HTTPS + +## Security Flow for Installer Downloads + +### Step-by-Step Process: + +1. **Connection Initialization:** + - `InternetOpen()` creates session with Windows networking + - Inherits Windows TLS/SSL configuration + - Configures proxy if specified + +2. **URL Opening:** + - `InternetOpenUrl()` opens HTTPS URL + - WinINet automatically: + - Negotiates TLS connection + - Validates server certificate against Windows Certificate Store + - Establishes encrypted connection + +3. **Certificate Validation (if configured):** + - For REST APIs: Custom certificate pinning via `HttpClientHelper` + - Validates certificate against pinning configuration + - Ensures connection is to expected server + +4. **Secure Data Transfer:** + - `InternetReadFile()` reads encrypted data + - WinINet automatically decrypts data + - Data integrity verified via TLS + +5. **Hash Verification:** + - SHA256 hash computed during download (Downloader.cpp, line 230) + - Validates installer integrity after download + - Prevents tampering even if TLS compromised + +## Summary of Secure Connection Locations + +| Component | Primary Location | Purpose | +|-----------|-----------------|---------| +| Main Download (WinINet) | `src/AppInstallerCommonCore/Downloader.cpp` | Primary installer download with HTTPS | +| DO Download | `src/AppInstallerCommonCore/DODownloader.cpp` | Alternative download with HTTPS | +| Certificate Pinning | `src/AppInstallerSharedLib/Certificates.cpp` | Advanced certificate validation | +| HTTP Client | `src/AppInstallerCommonCore/HttpClientHelper.cpp` | REST API with certificate pinning | +| Certificate Resources | `src/CertificateResources/` | Embedded trusted certificates | +| Network Settings | `src/AppInstallerCommonCore/NetworkSettings.cpp` | Network configuration | + +## Security Guarantees + +WinGet's secure connection implementation provides: + +1. **Transport Security:** All connections use HTTPS with TLS encryption +2. **Certificate Validation:** Server certificates validated against Windows Certificate Store +3. **Certificate Pinning:** Additional validation for critical connections (REST APIs) +4. **Integrity Verification:** SHA256 hashing of downloaded files +5. **Windows Integration:** Leverages OS-level security features and certificate management + +## Related Error Codes + +- `APPINSTALLER_CLI_ERROR_PINNED_CERTIFICATE_MISMATCH` - Certificate pinning validation failed +- `HTTP_STATUS_*` - Various HTTP status codes handled in Downloader.cpp +- WinINet/WinHTTP error codes - Passed through from underlying APIs diff --git a/doc/SecureConnectionQuickRef.md b/doc/SecureConnectionQuickRef.md new file mode 100644 index 0000000000..6f548957a5 --- /dev/null +++ b/doc/SecureConnectionQuickRef.md @@ -0,0 +1,52 @@ +# Quick Reference: Secure Connection Code Locations + +This document provides a quick reference to answer: "Where is the code in WinGet to enable a secure connection to download an installer?" + +## Main Installer Download (Primary) + +**File:** `src/AppInstallerCommonCore/Downloader.cpp` + +**Key Lines:** +- Lines 146-151: `InternetOpen()` - Initialize WinINet session with proxy (includes automatic HTTPS/TLS support) +- Lines 155-160: `InternetOpen()` - Initialize WinINet session without proxy (includes automatic HTTPS/TLS support) +- Lines 178-184: `InternetOpenUrl()` - Open secure HTTPS connection with security flags +- Line 247: `InternetReadFile()` - Read encrypted data over secure connection + +**How it works:** Uses Windows WinINet API which automatically: +- Negotiates TLS connection +- Validates server certificates via Windows Certificate Store +- Establishes encrypted channel + +## Certificate Pinning (Additional Security) + +**Files:** +- **Header:** `src/AppInstallerSharedLib/Public/winget/Certificates.h` +- **Implementation:** `src/AppInstallerSharedLib/Certificates.cpp` +- **Usage:** `src/AppInstallerCommonCore/HttpClientHelper.cpp` (lines 28-44: `NativeHandleServerCertificateValidation` function) + +**How it works:** +- Extracts server certificate using `WinHttpQueryOption()` +- Validates against pre-configured pinning rules +- Rejects connections if certificate doesn't match expected values + +## Certificate Resources + +**Location:** `src/CertificateResources/` + +Contains Microsoft root certificates used for pinning validation: +- `Microsoft_TLS_ECC_Root_G2.crt` +- `Microsoft_TLS_RSA_Root_G2.crt` + +## Alternative Download Method + +**File:** `src/AppInstallerCommonCore/DODownloader.cpp` + +Uses Windows Delivery Optimization service (also HTTPS-based) + +## Summary + +**Primary secure connection code:** `src/AppInstallerCommonCore/Downloader.cpp` using WinINet API + +**Enhanced security (certificate pinning):** `src/AppInstallerSharedLib/Certificates.cpp` and `src/AppInstallerCommonCore/HttpClientHelper.cpp` + +For detailed architecture information, see [SecureConnectionArchitecture.md](SecureConnectionArchitecture.md). diff --git a/src/AppInstallerCommonCore/Downloader.cpp b/src/AppInstallerCommonCore/Downloader.cpp index a073f59861..e7742a9282 100644 --- a/src/AppInstallerCommonCore/Downloader.cpp +++ b/src/AppInstallerCommonCore/Downloader.cpp @@ -172,6 +172,8 @@ namespace AppInstaller::Utility } std::wstring customHeadersWide = Utility::ConvertToUTF16(customHeaders); + // Open URL connection - WinINet automatically handles HTTPS/TLS for secure downloads + // See doc/SecureConnectionArchitecture.md for details on security implementation auto urlWide = Utility::ConvertToUTF16(url); wil::unique_hinternet urlFile(InternetOpenUrl( session.get(), diff --git a/src/AppInstallerCommonCore/HttpClientHelper.cpp b/src/AppInstallerCommonCore/HttpClientHelper.cpp index 439171ce81..47c2e179f1 100644 --- a/src/AppInstallerCommonCore/HttpClientHelper.cpp +++ b/src/AppInstallerCommonCore/HttpClientHelper.cpp @@ -22,6 +22,9 @@ namespace AppInstaller::Http } } + // Custom certificate validation for HTTPS connections using certificate pinning + // This validates server certificates against configured pinning rules for enhanced security + // See doc/SecureConnectionArchitecture.md for details on certificate pinning implementation void NativeHandleServerCertificateValidation(web::http::client::native_handle handle, const Certificates::PinningConfiguration& pinningConfiguration, ThreadLocalStorage::ThreadGlobals* threadGlobals) { decltype(threadGlobals->SetForCurrentThread()) previousThreadGlobals;