Skip to content

Commit 47014cb

Browse files
Add [1.2.0] rollup CHANGELOG entry for 2026-04-11 work
Consolidates the four PRs merged today into a single semver entry for humans, and triggers a new CI release whose body will link back to the individual timestamp-tagged releases (2308, 2314, 2344, 2347). The entry credits @aysiu explicitly for the PEM client cert contribution in PR #2, which was the original spark for the mTLS feature. PFX + Credential Manager and the strategy-priority refactor were layered on as maintainer tweaks. Also documents: - xUnit test suite + dotnet test CI integration (PR #3) - Node.js 24 opt-in for JavaScript Actions (PR #5) - REG_DWORD/QWORD handling fix in GetRegistryValue, closing #4 (PR #6)
1 parent 7a6b1b3 commit 47014cb

1 file changed

Lines changed: 109 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,115 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and 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

Comments
 (0)