init
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const forge = require('node-forge');
|
||||
|
||||
const rootDir = path.resolve(__dirname, '..');
|
||||
const rawConfigText = fs.readFileSync(path.join(rootDir, 'config.json'), 'utf8');
|
||||
const configText = rawConfigText.charCodeAt(0) === 0xfeff ? rawConfigText.slice(1) : rawConfigText;
|
||||
const config = JSON.parse(configText);
|
||||
const certDir = path.resolve(rootDir, config.certDir || 'certs');
|
||||
const keyPath = path.join(certDir, 'rootCA.key.pem');
|
||||
const certPath = path.join(certDir, 'rootCA.cert.pem');
|
||||
const certDerPath = path.join(certDir, 'rootCA.cert.cer');
|
||||
|
||||
fs.mkdirSync(certDir, { recursive: true });
|
||||
|
||||
if (fs.existsSync(keyPath) || fs.existsSync(certPath) || fs.existsSync(certDerPath)) {
|
||||
console.error('Root CA already exists. Delete certs/rootCA.* first if you intentionally want to regenerate it.');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('Generating 2048-bit RSA root CA...');
|
||||
const keys = forge.pki.rsa.generateKeyPair(2048);
|
||||
const cert = forge.pki.createCertificate();
|
||||
cert.publicKey = keys.publicKey;
|
||||
cert.serialNumber = forge.util.bytesToHex(forge.random.getBytesSync(16)).replace(/^00/, '01');
|
||||
cert.validity.notBefore = new Date(Date.now() - 60 * 1000);
|
||||
cert.validity.notAfter = new Date(Date.now() + 10 * 365 * 24 * 60 * 60 * 1000);
|
||||
cert.setSubject([
|
||||
{ name: 'commonName', value: 'Local Node MITM Proxy Root CA' },
|
||||
{ name: 'organizationName', value: 'Local Development' },
|
||||
{ shortName: 'OU', value: 'Debug Proxy' },
|
||||
]);
|
||||
cert.setIssuer(cert.subject.attributes);
|
||||
cert.setExtensions([
|
||||
{ name: 'basicConstraints', cA: true, critical: true },
|
||||
{ name: 'keyUsage', keyCertSign: true, cRLSign: true, critical: true },
|
||||
{ name: 'subjectKeyIdentifier' },
|
||||
]);
|
||||
cert.sign(keys.privateKey, forge.md.sha256.create());
|
||||
|
||||
const keyPem = forge.pki.privateKeyToPem(keys.privateKey);
|
||||
const certPem = forge.pki.certificateToPem(cert);
|
||||
const certDer = Buffer.from(forge.asn1.toDer(forge.pki.certificateToAsn1(cert)).getBytes(), 'binary');
|
||||
|
||||
fs.writeFileSync(keyPath, keyPem, 'utf8');
|
||||
fs.writeFileSync(certPath, certPem, 'utf8');
|
||||
fs.writeFileSync(certDerPath, certDer);
|
||||
|
||||
console.log(`Created private key: ${keyPath}`);
|
||||
console.log(`Created PEM cert: ${certPath}`);
|
||||
console.log(`Created DER cert: ${certDerPath}`);
|
||||
console.log('Keep rootCA.key.pem private. Anyone with it can mint trusted certificates on this machine.');
|
||||
@@ -0,0 +1,9 @@
|
||||
param()
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$certPath = Join-Path $PSScriptRoot '..\certs\rootCA.cert.cer'
|
||||
$resolved = Resolve-Path $certPath
|
||||
|
||||
Write-Host "Installing root CA into CurrentUser\Root: $resolved"
|
||||
Import-Certificate -FilePath $resolved -CertStoreLocation Cert:\CurrentUser\Root | Out-Null
|
||||
Write-Host 'Installed. Restart browsers/apps that cache trust settings.'
|
||||
@@ -0,0 +1,36 @@
|
||||
param(
|
||||
[switch]$Enable,
|
||||
[switch]$Disable,
|
||||
[string]$ProxyServer = '127.0.0.1:8888',
|
||||
[string]$Override = '<local>'
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$key = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings'
|
||||
|
||||
if ($Enable -eq $Disable) {
|
||||
throw 'Pass exactly one of -Enable or -Disable.'
|
||||
}
|
||||
|
||||
if ($Enable) {
|
||||
Set-ItemProperty -Path $key -Name ProxyEnable -Type DWord -Value 1
|
||||
Set-ItemProperty -Path $key -Name ProxyServer -Type String -Value $ProxyServer
|
||||
Set-ItemProperty -Path $key -Name ProxyOverride -Type String -Value $Override
|
||||
Write-Host "Enabled Windows proxy: $ProxyServer"
|
||||
} else {
|
||||
Set-ItemProperty -Path $key -Name ProxyEnable -Type DWord -Value 0
|
||||
Write-Host 'Disabled Windows proxy.'
|
||||
}
|
||||
|
||||
$source = @"
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
public static class WinInetNative {
|
||||
[DllImport("wininet.dll", SetLastError = true)]
|
||||
public static extern bool InternetSetOption(IntPtr hInternet, int dwOption, IntPtr lpBuffer, int dwBufferLength);
|
||||
}
|
||||
"@
|
||||
|
||||
Add-Type -TypeDefinition $source -ErrorAction SilentlyContinue | Out-Null
|
||||
[WinInetNative]::InternetSetOption([IntPtr]::Zero, 39, [IntPtr]::Zero, 0) | Out-Null
|
||||
[WinInetNative]::InternetSetOption([IntPtr]::Zero, 37, [IntPtr]::Zero, 0) | Out-Null
|
||||
@@ -0,0 +1,20 @@
|
||||
param()
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$subject = 'CN=Local Node MITM Proxy Root CA'
|
||||
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store('Root', 'CurrentUser')
|
||||
$store.Open('ReadWrite')
|
||||
try {
|
||||
$matches = @($store.Certificates | Where-Object { $_.Subject -eq $subject })
|
||||
if ($matches.Count -eq 0) {
|
||||
Write-Host "No matching certificate found: $subject"
|
||||
exit 0
|
||||
}
|
||||
foreach ($cert in $matches) {
|
||||
Write-Host "Removing $($cert.Subject) thumbprint=$($cert.Thumbprint)"
|
||||
$store.Remove($cert)
|
||||
}
|
||||
Write-Host 'Removed matching root CA certificate(s).'
|
||||
} finally {
|
||||
$store.Close()
|
||||
}
|
||||
Reference in New Issue
Block a user