// Demonstrates the workaround for the bug in @azure/keyvault-certificates: // Since importCertificate() silently drops policy.contentType, we call // updateCertificatePolicy() first to shift the stored content_type to the // new format before importing. Azure then validates incoming bytes correctly. // // Requirements: openssl in PATH // Usage: KEYVAULT_NAME= node docs/bug-workaround.mjs import { execSync } from 'node:child_process'; import { mkdtempSync, readFileSync, rmSync } from 'node:fs'; import { randomBytes } from 'node:crypto'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { DefaultAzureCredential } from '@azure/identity'; import { CertificateClient } from '@azure/keyvault-certificates'; const vaultName = process.env.KEYVAULT_NAME; if (!vaultName) { console.error('Set KEYVAULT_NAME'); process.exit(1); } const vaultUrl = `https://${vaultName}.vault.azure.net`; const CERT_NAME = `bug-workaround-${randomBytes(4).toString('hex')}`; const PFX_PASSWORD = 'test-password-123'; const tmp = mkdtempSync(join(tmpdir(), 'kv-workaround-')); try { console.log('Generating self-signed certificate...'); execSync( `openssl req -x509 -newkey rsa:2048 -keyout "${join(tmp, 'key.pem')}" -out "${join(tmp, 'cert.pem')}" -days 365 -nodes -subj "/CN=bug-workaround-test"`, { stdio: 'pipe' }, ); execSync( `openssl pkcs12 -export -out "${join(tmp, 'cert.pfx')}" -inkey "${join(tmp, 'key.pem')}" -in "${join(tmp, 'cert.pem')}" -passout pass:${PFX_PASSWORD}`, { stdio: 'pipe' }, ); const pemBytes = Buffer.concat([readFileSync(join(tmp, 'cert.pem')), readFileSync(join(tmp, 'key.pem'))]); const pfxBytes = readFileSync(join(tmp, 'cert.pfx')); const credential = new DefaultAzureCredential(); const client = new CertificateClient(vaultUrl, credential); console.log(`\nStep 1: importing '${CERT_NAME}' as PEM...`); try { await client.importCertificate(CERT_NAME, pemBytes, { policy: { contentType: 'application/x-pem-file', issuerName: 'Unknown', subject: 'CN=bug-workaround-test' }, }); console.log(' OK — PEM import succeeded.'); } catch (err) { console.error(` FAILED — ${err.message}`); process.exit(1); } console.log(`\nStep 2: updating policy to application/x-pkcs12 before importing PFX...`); await client.updateCertificatePolicy(CERT_NAME, { contentType: 'application/x-pkcs12', issuerName: 'Unknown', subject: 'CN=bug-workaround-test', }); console.log(' OK — policy updated.'); console.log(`\nStep 3: importing '${CERT_NAME}' as PFX...`); await client.importCertificate(CERT_NAME, pfxBytes, { password: PFX_PASSWORD, }); console.log(' OK — PFX import succeeded.'); console.log('\nWorkaround confirmed: updateCertificatePolicy() before import allows format change.'); } finally { rmSync(tmp, { recursive: true }); }