( certificate: Buffer, intermediates?: Buffer[], )
| 297 | * Verifies certificate chain against OS trust store |
| 298 | */ |
| 299 | export async function verifyCertificateChain( |
| 300 | certificate: Buffer, |
| 301 | intermediates?: Buffer[], |
| 302 | ): Promise<boolean> { |
| 303 | let tempDir: string | null = null; |
| 304 | |
| 305 | try { |
| 306 | tempDir = await mkdtemp(join(tmpdir(), "mcpb-verify-")); |
| 307 | const certChainPath = join(tempDir, "chain.pem"); |
| 308 | const certChain = [certificate, ...(intermediates || [])].join("\n"); |
| 309 | await writeFile(certChainPath, certChain); |
| 310 | |
| 311 | // Platform-specific verification |
| 312 | if (process.platform === "darwin") { |
| 313 | try { |
| 314 | await execFileAsync("security", [ |
| 315 | "verify-cert", |
| 316 | "-c", |
| 317 | certChainPath, |
| 318 | "-p", |
| 319 | "codeSign", |
| 320 | ]); |
| 321 | return true; |
| 322 | } catch (error) { |
| 323 | return false; |
| 324 | } |
| 325 | } else if (process.platform === "win32") { |
| 326 | const psCommand = ` |
| 327 | $ErrorActionPreference = 'Stop' |
| 328 | $certCollection = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection |
| 329 | $certCollection.Import('${certChainPath}') |
| 330 | |
| 331 | if ($certCollection.Count -eq 0) { |
| 332 | Write-Error 'No certificates found' |
| 333 | exit 1 |
| 334 | } |
| 335 | |
| 336 | $leafCert = $certCollection[0] |
| 337 | $chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain |
| 338 | |
| 339 | # Enable revocation checking |
| 340 | $chain.ChainPolicy.RevocationMode = 'Online' |
| 341 | $chain.ChainPolicy.RevocationFlag = 'EntireChain' |
| 342 | $chain.ChainPolicy.UrlRetrievalTimeout = New-TimeSpan -Seconds 30 |
| 343 | |
| 344 | # Add code signing application policy |
| 345 | $codeSignOid = New-Object System.Security.Cryptography.Oid '1.3.6.1.5.5.7.3.3' |
| 346 | $chain.ChainPolicy.ApplicationPolicy.Add($codeSignOid) |
| 347 | |
| 348 | # Add intermediate certificates to extra store |
| 349 | for ($i = 1; $i -lt $certCollection.Count; $i++) { |
| 350 | [void]$chain.ChainPolicy.ExtraStore.Add($certCollection[$i]) |
| 351 | } |
| 352 | |
| 353 | # Build and validate chain |
| 354 | $result = $chain.Build($leafCert) |
| 355 | |
| 356 | if ($result) { |
no outgoing calls
no test coverage detected
searching dependent graphs…