From a3b39ff42244dc6fe2853c021699cadf12b0cb71 Mon Sep 17 00:00:00 2001 From: Markus Tacker Date: Tue, 5 Dec 2023 16:58:38 +0100 Subject: [PATCH] fix(iot-hub): use certificates according to docs See https://learn.microsoft.com/en-us/azure/iot-hub/migrate-tls-certificate --- .../create-and-provision-device-cert.ts | 41 +++++++++---------- cli/commands/create-simulator-cert.ts | 23 +++++++++-- data/DigiCertTLSECCP384RootG5.crt.pem | 14 ------- ...crosoftRSARootCertificateAuthority2017.pem | 15 +++++++ feature-runner/steps/device.ts | 10 ++--- feature-runner/steps/device/connectDevice.ts | 23 +++++++---- 6 files changed, 74 insertions(+), 52 deletions(-) delete mode 100644 data/DigiCertTLSECCP384RootG5.crt.pem create mode 100644 data/MicrosoftRSARootCertificateAuthority2017.pem diff --git a/cli/commands/create-and-provision-device-cert.ts b/cli/commands/create-and-provision-device-cert.ts index c0057a327..e496bbae6 100644 --- a/cli/commands/create-and-provision-device-cert.ts +++ b/cli/commands/create-and-provision-device-cert.ts @@ -30,7 +30,6 @@ import { CommandDefinition } from './CommandDefinition.js' export const defaultPort = '/dev/ttyACM0' export const defaultSecTag = 11 -export const defaultSecondarySecTag = defaultSecTag + 1 export const createAndProvisionDeviceCertCommand = ({ certsDir: certsDirPromise, @@ -60,10 +59,6 @@ export const createAndProvisionDeviceCertCommand = ({ flags: '-s, --sec-tag ', description: `Use this secTag, defaults to ${defaultSecTag}`, }, - { - flags: '-S, --secondary-sec-tag ', - description: `Use this secTag, defaults to ${defaultSecTag}`, - }, { flags: '-X, --delete-private-key', description: `Delete the private key (needed if a private key exists with the secTag)`, @@ -94,7 +89,6 @@ export const createAndProvisionDeviceCertCommand = ({ intermediateCertId, expires, secTag, - secondarySecTag, deletePrivateKey, }) => { const logFn = debug === true ? log : undefined @@ -185,18 +179,28 @@ export const createAndProvisionDeviceCertCommand = ({ const intermediateCert = await readFile(caIntermediateFiles.cert, 'utf-8') - const effectiveSecondarySecTag = secondarySecTag ?? defaultSecondarySecTag - const caCerts = await Promise.all([ + const [ + // Keep the Baltimore CyberTrust Root in your devices' trusted root store. + BaltimoreCyberTrustRoot, + // Add the DigiCert Global Root G2 + DigiCertGlobalRootG2, + // and the Microsoft RSA Root Certificate Authority 2017 certificates + MicrosoftRSARootCertificateAuthority2017, + ] = await Promise.all([ readFile( path.resolve(process.cwd(), 'data', 'BaltimoreCyberTrustRoot.pem'), 'utf-8', ), readFile( - path.resolve(process.cwd(), 'data', 'DigiCertTLSECCP384RootG5.crt.pem'), + path.resolve(process.cwd(), 'data', 'DigiCertGlobalRootG2.pem'), 'utf-8', ), readFile( - path.resolve(process.cwd(), 'data', 'DigiCertGlobalRootG2.pem'), + path.resolve( + process.cwd(), + 'data', + 'MicrosoftRSARootCertificateAuthority2017.pem', + ), 'utf-8', ), ]) @@ -206,18 +210,11 @@ export const createAndProvisionDeviceCertCommand = ({ clientCert: [await readFile(cert, 'utf-8'), intermediateCert].join( os.EOL, ), - caCert: caCerts.join(os.EOL), - secondaryCaCert: { - secTag: effectiveSecondarySecTag, - caCert: await readFile( - path.resolve( - process.cwd(), - 'data', - 'DigiCertTLSECCP384RootG5.crt.pem', - ), - 'utf-8', - ), - }, + caCert: [ + BaltimoreCyberTrustRoot, + DigiCertGlobalRootG2, + MicrosoftRSARootCertificateAuthority2017, + ].join(os.EOL), }) success('Certificate written to device') diff --git a/cli/commands/create-simulator-cert.ts b/cli/commands/create-simulator-cert.ts index b1b109092..69190e3f8 100644 --- a/cli/commands/create-simulator-cert.ts +++ b/cli/commands/create-simulator-cert.ts @@ -118,17 +118,28 @@ export const createSimulatorCertCommand = ({ }) await readFile(intermediateCAFiles.cert, 'utf-8') const idScope = await idScopePromise() - const caCerts = await Promise.all([ + const [ + // Keep the Baltimore CyberTrust Root in your devices' trusted root store. + BaltimoreCyberTrustRoot, + // Add the DigiCert Global Root G2 + DigiCertGlobalRootG2, + // and the Microsoft RSA Root Certificate Authority 2017 certificates + MicrosoftRSARootCertificateAuthority2017, + ] = await Promise.all([ readFile( path.resolve(process.cwd(), 'data', 'BaltimoreCyberTrustRoot.pem'), 'utf-8', ), readFile( - path.resolve(process.cwd(), 'data', 'DigiCertTLSECCP384RootG5.crt.pem'), + path.resolve(process.cwd(), 'data', 'DigiCertGlobalRootG2.pem'), 'utf-8', ), readFile( - path.resolve(process.cwd(), 'data', 'DigiCertGlobalRootG2.pem'), + path.resolve( + process.cwd(), + 'data', + 'MicrosoftRSARootCertificateAuthority2017.pem', + ), 'utf-8', ), ]) @@ -140,7 +151,11 @@ export const createSimulatorCertCommand = ({ await readFile(cert, 'utf-8'), await readFile(intermediateCAFiles.cert, 'utf-8'), ].join(os.EOL), - caCert: caCerts.join(os.EOL), + caCert: [ + BaltimoreCyberTrustRoot, + DigiCertGlobalRootG2, + MicrosoftRSARootCertificateAuthority2017, + ].join(os.EOL), } await writeFile(certJSON, JSON.stringify(simulatorJSON, null, 2), 'utf-8') success(`${certJSON} written`) diff --git a/data/DigiCertTLSECCP384RootG5.crt.pem b/data/DigiCertTLSECCP384RootG5.crt.pem deleted file mode 100644 index cc89bbeb8..000000000 --- a/data/DigiCertTLSECCP384RootG5.crt.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURp -Z2lDZXJ0IFRMUyBFQ0MgUDM4NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2 -MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ -bmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQgUm9vdCBHNTB2MBAG -ByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1TzvdlHJS -7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp -0zVozptjn4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICIS -B4CIfBFqMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49 -BAMDA2gAMGUCMQCJao1H5+z8blUD2WdsJk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQ -LgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIxAJSdYsiJvRmEFOml+wG4 -DXZDjC5Ty3zfDBeWUA== ------END CERTIFICATE----- \ No newline at end of file diff --git a/data/MicrosoftRSARootCertificateAuthority2017.pem b/data/MicrosoftRSARootCertificateAuthority2017.pem new file mode 100644 index 000000000..e3be2a5bb --- /dev/null +++ b/data/MicrosoftRSARootCertificateAuthority2017.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- diff --git a/feature-runner/steps/device.ts b/feature-runner/steps/device.ts index 06311d789..fb1155854 100644 --- a/feature-runner/steps/device.ts +++ b/feature-runner/steps/device.ts @@ -56,18 +56,18 @@ export const deviceStepRunners = ({ path.resolve(process.cwd(), 'data', 'BaltimoreCyberTrustRoot.pem'), 'utf-8', ), + readFile( + path.resolve(process.cwd(), 'data', 'DigiCertGlobalRootG2.pem'), + 'utf-8', + ), readFile( path.resolve( process.cwd(), 'data', - 'DigiCertTLSECCP384RootG5.crt.pem', + 'MicrosoftRSARootCertificateAuthority2017.pem', ), 'utf-8', ), - readFile( - path.resolve(process.cwd(), 'data', 'DigiCertGlobalRootG2.pem'), - 'utf-8', - ), ]) const simulatorJSON: DeviceCertificateJSON = { clientId: deviceId, diff --git a/feature-runner/steps/device/connectDevice.ts b/feature-runner/steps/device/connectDevice.ts index d9cdbd8c9..7454b159c 100644 --- a/feature-runner/steps/device/connectDevice.ts +++ b/feature-runner/steps/device/connectDevice.ts @@ -29,27 +29,32 @@ export const connectDevice = async ({ certsDir, id: intermediateCertId, }) + const [ deviceKey, deviceCert, intermediateCA, - baltimore, - digiCertG5, - digiCert, + BaltimoreCyberTrustRoot, + DigiCertGlobalRootG2, + MicrosoftRSARootCertificateAuthority2017, ] = await Promise.all([ fs.readFile(deviceFiles.privateKey, 'utf-8'), fs.readFile(deviceFiles.cert, 'utf-8'), fs.readFile(intermediateCAFiles.cert, 'utf-8'), fs.readFile( - path.join(process.cwd(), 'data', 'BaltimoreCyberTrustRoot.pem'), + path.resolve(process.cwd(), 'data', 'BaltimoreCyberTrustRoot.pem'), 'utf-8', ), fs.readFile( - path.resolve(process.cwd(), 'data', 'DigiCertTLSECCP384RootG5.crt.pem'), + path.resolve(process.cwd(), 'data', 'DigiCertGlobalRootG2.pem'), 'utf-8', ), fs.readFile( - path.join(process.cwd(), 'data', 'DigiCertGlobalRootG2.pem'), + path.resolve( + process.cwd(), + 'data', + 'MicrosoftRSARootCertificateAuthority2017.pem', + ), 'utf-8', ), ]) @@ -94,7 +99,11 @@ export const connectDevice = async ({ username: `${iotHub}/${deviceId}/?api-version=2020-09-30`, protocolVersion: 4, clean: true, - ca: [baltimore, digiCertG5, digiCert].join(os.EOL), + ca: [ + BaltimoreCyberTrustRoot, + DigiCertGlobalRootG2, + MicrosoftRSARootCertificateAuthority2017, + ].join(os.EOL), }) client.on('connect', async () => { log?.('Connected', deviceId)