Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,24 +257,23 @@ Toolkit versions ≤ v1.0.3 stored acme-dns credentials using DPAPI in `CurrentU
- `%ProgramData%\win-acme\acme-v02.api.letsencrypt.org\Log\log-*.txt` contains `ConvertTo-SecureString : ... CryptographicException` and `Failed to decrypt password. This usually means the credential was stored by a different user or on a different machine.`
- The credential JSON in `%ProgramData%\WinCertManager\Config\acme-dns\` reports `"StorageMethod": "DPAPI"`

**Fix:** `scripts/Recovery/Repair-AcmeDnsCredential.ps1` re-encrypts the credential under DPAPI `LocalMachine` scope (so SYSTEM can decrypt it) without changing the acme-dns subdomain registration — no DNS changes required. Run it once per affected host. Toolkit ≥ v1.0.4 stores new credentials in `LocalMachine` scope by default, so fresh installs are unaffected.
**Fix:** `scripts/Recovery/Repair-AcmeDnsCredential.ps1` re-encrypts the credential under DPAPI `LocalMachine` scope (so SYSTEM can decrypt it) without changing the acme-dns subdomain registration — no DNS changes required. Run it once per affected host as the same admin that originally registered the domain; the script then recovers the password from the existing DPAPI blob automatically, so you don't need it from a password manager. It also clears any stale win-acme ARI cache entries that may be holding a "replacement" slot for the failed cert and offers to run the renewal interactively. Toolkit ≥ v1.0.4 stores new credentials in `LocalMachine` scope by default, so fresh installs are unaffected.

> **Verify the script before running it.** Open it in a text editor or run `Get-AuthenticodeSignature` against a copy from a signed release ZIP. The script will prompt for the original acme-dns password (the `password` field returned by `/register`, retrievable from your password manager).
> **Verify the script before running it.** Open it in a text editor or run `Get-AuthenticodeSignature` against a copy from a signed release ZIP. If you're running as a different operator from the one that originally registered the domain, the script will fall back to prompting for the `password` field returned by `/register` (retrievable from your password manager).

```powershell
# On the affected host, in an elevated PowerShell session:
# On the affected host, in an elevated PowerShell session,
# signed in as the admin that originally registered the domain:
$url = 'https://raw.githubusercontent.com/realworldtech/wincertmanager/main/scripts/Recovery/Repair-AcmeDnsCredential.ps1'
$dest = Join-Path $env:TEMP 'Repair-AcmeDnsCredential.ps1'
Invoke-WebRequest -Uri $url -OutFile $dest -UseBasicParsing

# REVIEW the file before executing:
notepad $dest

# Then run for the affected domain (will prompt for the acme-dns password):
# Then run for the affected domain. Auto-recovers the password,
# clears the ARI cache, and prompts to run wacs.exe --renew:
& $dest -Domain 'dc01.internal.example.com'

# After repair, force a renewal to confirm:
& 'C:\Tools\win-acme\wacs.exe' --renew --force --verbose
```

If you prefer a signed copy, download the latest release ZIP from the [Releases page](https://github.com/realworldtech/wincertmanager/releases), verify the SHA256, and run the script from `scripts/Recovery/` inside the extracted directory.
Expand Down
9 changes: 5 additions & 4 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,17 +194,18 @@ The renewal log will show the error inside `Get-AcmeDnsCredential.ps1` while run

**Solutions:**

For cause 1 (DPAPI scope mismatch), use the recovery tool to re-encrypt under machine scope without losing the existing acme-dns subdomain registration (no DNS changes needed):
For cause 1 (DPAPI scope mismatch), use the recovery tool to re-encrypt under machine scope without losing the existing acme-dns subdomain registration (no DNS changes needed). Run it as the same admin that originally registered the domain — the script then unwraps the password from the existing CurrentUser DPAPI blob and you don't need to supply it:

```powershell
.\scripts\Recovery\Repair-AcmeDnsCredential.ps1 -Domain "example.com"
# Prompts for the original acme-dns password from /register
```

After the repair, force a renewal to confirm:
The script also clears stale win-acme ARI cache entries for the domain (so the next `new-order` doesn't fail with `urn:ietf:params:acme:error:alreadyReplaced` because of leftover pending orders from earlier failed attempts) and prompts to run `wacs.exe --renew --force --verbose` immediately. For unattended runs, pass `-RunRenewal Yes` (or `No`) to skip the prompt; if you're running as a different operator from the one that registered, pass `-Password` (a `[SecureString]`) explicitly:

```powershell
C:\Tools\win-acme\wacs.exe --renew --force --verbose
# Unattended, original user not available:
$pw = ConvertTo-SecureString $env:ACMEDNS_PASSWORD -AsPlainText -Force
.\scripts\Recovery\Repair-AcmeDnsCredential.ps1 -Password $pw -RunRenewal Yes -Confirm:$false
```

Toolkit ≥ v1.0.4 registers new credentials with `StorageMethod = DPAPI-LocalMachine` by default, so this issue does not affect fresh installs. Existing legacy installs only need the repair script run once.
Expand Down
Loading