How can I verify that all certificates in the chain are combined to create a chain of trust to a trusted root CA certificate?
So I'm trying to manually validate a request for an Alexa skill I'm developing, but can't "verify that all certificates in the chain are combined to create a chain of trust to a trusted root CA certificate". As shown in step 3.c of the documentation .
Working with these certificates is completely new territory for me, and since I've built up this skill without using the suggested Amazon Ask-SDK, I figured it would be faster to implement the verification manually instead of adapting my skills to using the SDK. But now I'm stuck and need help.
I don't quite understand how caStore works and think I may not be initializing it properly. I've tried using the Amazon Signing certificate provided in the skill request along with the two root certificates (URLs in the code) without success.
this is the code
const rp = require('request-promise')
const pki = require('node-forge').pki
const AlexaSkill = {
validate: async (request) => {
if (request.headers) {
const signature = request.headers.signature
const signatureCertChainUrl = request.headers.signaturecertchainurl
if (signature && signatureCertChainUrl) {
let urlPieces = signatureCertChainUrl.replace('../', '').split('echo.api/')
if (urlPieces.length > 1) {
const normalizedUrl = `${urlPieces[0]}echo.api/${urlPieces[urlPieces.length - 1]}`
if (normalizedUrl.startsWith('https://s3.amazonaws.com:443/echo.api/') || normalizedUrl.startsWith('https://s3.amazonaws.com/echo.api/')) {
const pem = await rp(signatureCertChainUrl)
const amazonSigningPem = pem.substring(0, pem.indexOf('END CERTIFICATE-----\n') + 21)
const amazonSigningCert = pki.certificateFromPem(amazonSigningPem)
const pem1 = await rp('https://www.amazontrust.com/repository/AmazonRootCA1.pem')
const amazonRootCert1 = pki.certificateFromPem(pem1)
const pem2 = await rp('https://www.amazontrust.com/repository/AmazonRootCA2.pem')
const amazonRootCert2 = pki.certificateFromPem(pem2)
// const pem3 = await rp('https://www.amazontrust.com/repository/AmazonRootCA3.pem')
// const amazonRootCert3 = pki.certificateFromPem(pem3)
// const pem4 = await rp('https://www.amazontrust.com/repository/AmazonRootCA4.pem')
// const amazonRootCert4 = pki.certificateFromPem(pem4)
const caStore = pki.createCaStore([ amazonSigningCert ])
const caStore1 = pki.createCaStore([ amazonRootCert1 ])
const caStore2 = pki.createCaStore([ amazonRootCert2 ])
// const caStore3 = pki.createCaStore([ amazonRootCert3 ])
// const caStore4 = pki.createCaStore([ amazonRootCert4 ])
const certChain = pem.substring(pem.indexOf('END CERTIFICATE-----\n') + 21)
.split('-----END CERTIFICATE-----\n')
.filter(cert => cert.length > 0)
.map(cert => pki.certificateFromPem(`${cert}-----END CERTIFICATE-----\n`))
try {
const v = pki.verifyCertificateChain(caStore, certChain)
console.log('Passed!', v)
} catch (e) {
console.log('Error!', JSON.stringify(e))
}
try {
const v1 = pki.verifyCertificateChain(caStore1, certChain)
console.log('Passed!', v1)
} catch (e) {
console.log('Error!', JSON.stringify(e))
}
try {
const v2 = pki.verifyCertificateChain(caStore2, certChain)
console.log('Passed!', v2)
} catch (e) {
console.log('Error!', JSON.stringify(e))
}
}
}
}
}
return false
}
}
and output
mistake! {"message": "Certificate not trusted.", "error": "forge.pki.UnknownCertificateAuthority"}
mistake! {"message": "Certificate not trusted.", "error": "forge.pki.UnknownCertificateAuthority"}
mistake! {"message": "Certificate not trusted.", "error": "forge.pki.UnknownCertificateAuthority"}
Thanks in advance.