Hello all! I'm wondering if there is any reason I can't/shouldn't be persisting the cert in my application? I'm creating a package in PHP for other developers to use and was/am planning on providing a number of providers to choose from, but essentially I'll use something like redis/database/file to persist the cert. Of course, if it's not valid (validFrom/validTo) then I'll attempt to go out and get a new cert, which I'll then persist for the next request. Is this fine to do? I can't imagine I'd need to download the cert on every request, but I'm wondering if there is anything in terms of security or best practice that I need to be sure to do, other then checking the validFrom/validTo dates (as well as the other things related to verifying the cert and url itself, checking the host, making sure the appId is valid, etc, etc)? Thanks in advance!
Bonus question: can anybody by chance tell me what exactly "All certificates in the chain combine to create a chain of trust to a trusted root CA certificate" means? I'm using PHP's openssl library which doesn't have a "makeSureTheseTHingsCombineAndCreateAChainOfTrustedRootCACertificate" method/function, so I'm wondering what exactly it is that I'm checking here. Thank you, and sorry for the newb question!
Hey Kevin, Don't apologise for n00b questions - you're posting in the Getting Started forum, and so it's the perfect place to ask this stuff - and in doing so might help others too :) I don't speak for Amazon, I'm just another developer like you - so please take what I say with a bag of salt... I've been thinking about this a lot as I'm working to implement proper request cert checking but are stuck due to running my apps on Google App Engine, and not being able to use many Python SSL / crypto libraries to process pem cert files correctly. Amazon would probably want you to fetch the certificate with each request so that if they need to swap it out (for any reason, not just expiring) that you don't break the user experience with Alexa failing to return a response back to the Echo that initiated the app session. You'll need the public key from the echo-api-cert.pem cert file to verify each request signature of course, and so if the underlying file doesn't change, then you won't technically need to fetch it each time imho. Each fetch of the cert also adds latency to your app's overall roundtrip response back to Alexa, which could also impact the UX. For my case - I'm thinking that I'll process the cert and then cache the public key for X number of future requests, over Y hours, before I re-fetch from source and process again afresh. If I notice that I can't process the requests due to the cached public key not working, or the cert URL changes, validity expires, etc. - then I'll force a re-fetch + process immediately. Providing you correctly process the cert URL, timestamp, etc. and nothing changes, then if Amazon continue to sign their requests to your app with the same public key, then I would assume a cert re-fetch is an unnecessary overhead. From:
https://developer.amazon.com/public/solutions/devices/echo/alexa-app-kit/docs/developing-your-app-with-the-alexa-appkit "This chain is provided at runtime so that the certificate may be updated periodically, so your web service should be resilient to different URLs with different content." ...there's no express stated requirement to fetch the cert pem on every single request - I can make my app very 'resilient' without needing to make that fetch each time :) For your bonus question - you need to ensure that all the certs in echo-api-cert.pem are chained correctly back to a root CA. Their pem currently contains three:
echo-api.amazon.com - the Alexa request signing host (which isn't the request sending/issuing server in this case) VeriSign Intermediate - used to generate server cert VeriSign Public Primary Certification Authority - used to generate the intermediate cert ...so it's just a case of ensuring that the certs within the pem file are correctly signed down the chain. I've not used PHP for a while, but it sounds like you're using the right library - you'll want to have a poke about with the x509-related functions, like:
http://php.net/manual/en/function.openssl-x509-parse.php ...to parse the pem file although it's not clear if that function will validate it too... so maybe have a look at the example code under here too:
http://php.net/manual/en/function.openssl-verify.php HTH; let me know how you get on. Cheers, James
Hello, Regarding the caching of certificates, we do provide the URL of the certificate on every request, but you can cache the certificate per URL. What this means is that the day we change the certificate, we will store it at a different URL. If you put this type of cache in place, fetches are going to be extremely rare. Thank you for bringing this up, we should definitely clarify this point in our documentation. Thanks, Nick
Hey James, I just wanted to say, first, that I'm very sorry I didn't respond earlier to your message! Your comment/information was extremely helpful, and helped to confirm many of my suspicions and assumptions. I've used this info to make an open-source package (here:
https://forums.developer.amazon.com/forums/thread.jspa?threadID=5564&tstart=0). I am not downloading the cert every request - in line with Nick's comment, I hash or store the URL for the chain, and only when it changes do I get a new copy of the chain. Thanks again for the help guys!