@@ -5,6 +5,115 @@ All notable changes to this project will be documented in this file.
55The format is based on [ Keep a Changelog] ( https://keepachangelog.com/en/1.0.0/ ) ,
66and this project adheres to [ Semantic Versioning] ( https://semver.org/spec/v2.0.0.html ) .
77
8+ ## [ 1.2.0] - 2026-04-11
9+
10+ Rollup of four PRs merged on the same day, covering a major mTLS
11+ feature contributed by an external contributor, a full xUnit test
12+ suite, CI modernization, and a pre-existing registry bug fix surfaced
13+ by the Copilot review of the test suite PR.
14+
15+ This version corresponds to four CI-generated releases on ` main ` :
16+
17+ - [ ` v2026.04.11.2308 ` ] ( https://github.com/windowsadmins/crypt-escrow/releases/tag/v2026.04.11.2308 ) — mTLS client authentication (PR #2 )
18+ - [ ` v2026.04.11.2314 ` ] ( https://github.com/windowsadmins/crypt-escrow/releases/tag/v2026.04.11.2314 ) — xUnit test suite (PR #3 )
19+ - [ ` v2026.04.11.2344 ` ] ( https://github.com/windowsadmins/crypt-escrow/releases/tag/v2026.04.11.2344 ) — Node.js 24 opt-in for Actions (PR #5 )
20+ - [ ` v2026.04.11.2347 ` ] ( https://github.com/windowsadmins/crypt-escrow/releases/tag/v2026.04.11.2347 ) — REG_DWORD handling fix, closes #4 (PR #6 )
21+
22+ ### Added
23+
24+ - ** mTLS client certificate authentication** with three strategies,
25+ tried in priority order (most secure first). Contributed by
26+ [ @aysiu ] ( https://github.com/aysiu ) in
27+ [ #2 ] ( https://github.com/windowsadmins/crypt-escrow/pull/2 ) , with
28+ maintainer tweaks layered on top.
29+ 1 . ** Windows Certificate Store** (preferred) — looked up by
30+ ` certificate_subject ` or ` certificate_thumbprint ` in
31+ ` LocalMachine\My ` / ` CurrentUser\My ` . Private key is
32+ DPAPI-protected and can be marked non-exportable; deployable via
33+ Intune / Group Policy. This was the original implementation and
34+ remains the recommended path for production.
35+ 2 . ** PFX file + passphrase from Credential Manager** — loads a
36+ ` .pfx ` from disk where the decryption passphrase is pulled from a
37+ Windows Credential Manager entry (DPAPI-protected). The
38+ passphrase never touches YAML, environment variables, or the
39+ registry. Provision with
40+ ` cmdkey /generic:<name> /user:<anything> /pass:<secret> ` .
41+ 3 . ** PEM certificate + unencrypted key file** — contributed by
42+ [ @aysiu ] ( https://github.com/aysiu ) . Least preferred — private key
43+ sits in plaintext on disk protected only by filesystem ACLs. Kept
44+ for environments where importing into the Cert Store isn't
45+ feasible, with a documented ` icacls ` lock-down recipe.
46+ - ** New ` Services/CredentialManager.cs ` ** — ~ 60 LOC ` LibraryImport `
47+ wrapper over ` advapi32!CredReadW ` . Trim/AOT-friendly; no new NuGet
48+ dependency.
49+ - ** Four new ` AuthConfig ` fields** : ` ClientCertPath ` , ` ClientKeyPath ` ,
50+ ` PfxPath ` , ` PfxPasswordCredential ` . All routed through the existing
51+ env-var → registry → YAML helper pattern so Intune CSP/OMA-URI
52+ deployment works for the new fields.
53+ - ** New env vars and registry values** documented in the README:
54+ ` CRYPT_PFX_PATH ` , ` CRYPT_PFX_PASSWORD_CRED ` , ` CRYPT_CLIENT_CERT_PATH ` ,
55+ ` CRYPT_CLIENT_KEY_PATH ` .
56+ - ** ` tests/CryptEscrow.Tests/ ` xUnit test project** with 39 tests
57+ covering ` ConfigService ` priority chains, ` CryptServerClient ` HTTP
58+ behavior, ` CredentialManager ` round-trip, and ` GetClientCertificate `
59+ strategy ordering. Tests run in ~ 1 second and require no admin
60+ rights. CI now gates publishing on ` dotnet test ` .
61+ - ** 22 additional regression tests** (61 total) added with the #6 fix
62+ — unit + integration + end-to-end coverage for DWORD/QWORD registry
63+ value conversion.
64+ - ** ` [InternalsVisibleTo] ` + three test seams** on production code:
65+ ` CryptServerClient ` internal test constructor accepting an
66+ ` HttpMessageHandler ` , ` GetClientCertificate ` promoted
67+ ` private → internal ` , and ` ConfigService.ConfigPathOverride ` +
68+ ` RegistryReaderOverride ` seams (both default null, zero production
69+ impact).
70+
71+ ### Changed
72+
73+ - ** ` GetClientCertificate ` strategy priority** : Cert Store is now
74+ tried before any file-based strategy, matching the documented
75+ security ranking. ` LoadFromCertStore ` short-circuits when neither
76+ thumbprint nor subject is configured, so file-only users pay no
77+ cost and don't get misleading error logs. (Surfaced by Copilot
78+ review of the test suite PR.)
79+ - ** Obsolete ` new X509Certificate2(byte[]) ` ctor replaced** with
80+ ` X509CertificateLoader.LoadPkcs12 ` (removes ` SYSLIB0057 ` warning
81+ on .NET 9+). The PFX round-trip on Windows is still needed so
82+ ` HttpClient ` can use the private key during the TLS handshake;
83+ the byte buffer is now cleared after use, and the resulting cert
84+ is tracked on the instance so ` Dispose() ` cleans it up.
85+ - ** GitHub Actions JavaScript actions opt-in to Node.js 24** via
86+ ` FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true ` , ahead of the June 2, 2026
87+ forced migration and Node 20 runner removal on September 16, 2026
88+ (PR #5 ).
89+ - ** README Authentication section rewritten** to rank the three
90+ mTLS strategies by security with provisioning examples for each.
91+
92+ ### Fixed
93+
94+ - ** ` ConfigService.GetRegistryValue ` silently dropped REG_DWORD /
95+ REG_QWORD values.** The method read raw values with
96+ ` key?.GetValue(name) as string ` , which returns null for any
97+ non-string registry type. Every CSP-deployed boolean or integer
98+ policy using the standard DWORD wire format was silently ignored,
99+ breaking ` GetUseMtls ` , ` GetAutoRotate ` , ` GetSkipCertCheck ` ,
100+ ` GetCleanupOldProtectors ` , ` GetKeyEscrowIntervalHours ` , and
101+ ` GetValidateKey ` for any Intune deployment that didn't explicitly
102+ use string values. Factored out ` ConvertToConfigString ` as an
103+ internal pure helper handling ` REG_SZ ` , ` REG_DWORD ` , and ` REG_QWORD `
104+ consistently. Closes [ #4 ] ( https://github.com/windowsadmins/crypt-escrow/issues/4 ) .
105+ (PR #6 )
106+
107+ ### Credits
108+
109+ Huge thanks to [ @aysiu ] ( https://github.com/aysiu ) for contributing the
110+ PEM client certificate authentication path in
111+ [ #2 ] ( https://github.com/windowsadmins/crypt-escrow/pull/2 ) . The PFX +
112+ Credential Manager strategy and the refactor to unify the three
113+ strategies behind a single priority-ordered dispatch were layered on
114+ top as maintainer tweaks; aysiu is credited as co-author on the squash
115+ merge.
116+
8117## [ 1.1.0] - 2026-01-20
9118
10119### Changed
0 commit comments