Recently, the certificate used for the iCloud add-on required an update because they changed the certificate server-side. This has happened before, and is expected to happen again in the future (every couple of months). This requires a new merge request, build & release before the binding works again in the stable release.
I thought I’d spend some time to see if we can retrieve the certificate dynamically, so that the binding doesn’t have to be update manually every couple of months.I’ve already been doing some discussing with @rkrisi I’m comfortable with the code, but I need some hints/guidance on what the desired solution should be in openhab. The idea is to retrieve the certificate from the iCloud host on startup of the binding, and allow the binding to retrieve the certificate if the currently used certificate is absent or expired. Obviously the binding should the keep track of the certificate for further use.
Specifically, I’m running into the following things:
- is it acceptable to retrieve the certificate dynamically? This means that there is no check that the server is running the correct/expected certificate (potential security hole if the iCloud server is hacked); I highly doubt that the current certificate that is assumed is checked in any way, so I’m happy enough to ignore this?
- I can see that the ICloudConnection-class uses the HttpRequestBuilder, which in the end relies on the ExtensibleTrustManager to provide an SSLContext. Since I believe this is only provided with the certificate once during binding startup (via iCloudTlsCertificateProvider), it’ll be hard to update this. I think we can update the TlsCertificateProvider in the ExtensibleTrustManager, but is it ok to get a hold of this in the binding itself? And if so, how can we do this, via @Reference? Another option is to write a custom Connection-implementation that allows dynamic updating of the certificate, as implemented in the digitalstorm-binding, but this feels rather bloated and not the way to go?
- The TlsCertificateProvider interface requires a URL to be returned. This implies that the certificate that we want to dynamically retrieve, has to be stored somewhere for it to be returned as a URL. What would be the proper location for this, and is this the desired route? When retrieve we’ve simply got the base64-encoded byte-stream, so technically there’s no need for it to be stored before use in the SSLContext.
Any pointers/decisions on how to proceed would be greatly appreciated!