feat: add bug reproduction and workaround scripts for importCertificate policy.contentType issue

This commit is contained in:
2026-05-23 09:32:23 +02:00
parent 4867672562
commit b7fe873dc9
3 changed files with 351 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
// Reproduces the bug in @azure/keyvault-certificates:
// CertificateClient.importCertificate() silently drops policy.contentType,
// so Azure validates incoming bytes against the existing stored policy.
// Importing PFX into a certificate previously stored as PEM fails with:
// "The specified PEM X.509 certificate content is in an unexpected format."
//
// Requirements: openssl in PATH
// Usage: KEYVAULT_NAME=<vault> node docs/bug-reproduce.mjs
import { execSync } from 'node:child_process';
import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
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-reproduce-test';
const PFX_PASSWORD = 'test-password-123';
const tmp = mkdtempSync(join(tmpdir(), 'kv-bug-'));
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-reproduce-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-reproduce-test' },
});
console.log(' OK — PEM import succeeded.');
} catch (err) {
console.error(` FAILED — ${err.message}`);
process.exit(1);
}
console.log(`\nStep 2: re-importing '${CERT_NAME}' as PFX (policy.contentType should tell Azure to expect PFX)...`);
try {
await client.importCertificate(CERT_NAME, pfxBytes, {
password: PFX_PASSWORD,
policy: { contentType: 'application/x-pkcs12', issuerName: 'Unknown', subject: 'CN=bug-reproduce-test' },
});
console.log(' OK — PFX import succeeded (bug may be fixed in this SDK version).');
} catch (err) {
console.error(` FAILED — ${err.message}`);
console.error('\n This confirms the bug: policy.contentType was silently dropped.');
console.error(' Azure validated the PFX bytes against the existing PEM policy and rejected them.');
}
} finally {
rmSync(tmp, { recursive: true });
}