Open danielweck opened 5 years ago
Fixed in the feature/latest-working-build-config
branch (Pull Request #49)
https://github.com/readium/readium-lcp-client/commit/f89dcacf127b7e0f526193692d5714f80cb318b7
Follow-up fix for more general UTF8 validation checks: https://github.com/readium/readium-lcp-client/commit/1c4bb3f86b3fe6fd902cc4572a66c74f0b39e45d
The KeyCheck is correctly verified in
DecryptUserKey()
:https://github.com/readium/readium-lcp-client/blob/e4c02fdd396157062b80dcd6b787a2c6a72a0da0/src/lcp-client-lib/CryptoppCryptoProvider.cpp#L232-L276
However, it should also be verified in
DecryptContentKey()
:https://github.com/readium/readium-lcp-client/blob/e4c02fdd396157062b80dcd6b787a2c6a72a0da0/src/lcp-client-lib/CryptoppCryptoProvider.cpp#L278-L310
The only reason why the current code "works" is because of a fortunate side effect from the CryptoPP lib, which emits an error when an attempt to decrypt a cypher using the wrong key is made, because of incorrect padding number parsing:
https://github.com/readium/readium-lcp-client/blob/e4c02fdd396157062b80dcd6b787a2c6a72a0da0/src/third-parties/cryptopp/filters.cpp#L762
The source of the problem is
DecryptLicenseByStorage()
:https://github.com/readium/readium-lcp-client/blob/e4c02fdd396157062b80dcd6b787a2c6a72a0da0/src/lcp-client-lib/LcpService.cpp#L410-L459
...more specifically
m_storageProvider->EnumerateVault
which will find the first existing user key that "works", without actually verifying the KeyCheck!This is the call chain:
OpenLicense()
=>CheckDecrypted()
=>DecryptLicenseOnOpening()
=>DecryptLicenseByStorage()
Then
DecryptLicenseByUserKey()
=>DecryptContentKey()
where the KeyCheck verification is missing. Thankfully, we have the CryptoPP "crash" to simulate the KeyCheck verification, but this is VERY hacky!The line that crashes: https://github.com/readium/readium-lcp-client/blob/e4c02fdd396157062b80dcd6b787a2c6a72a0da0/src/lcp-client-lib/CryptoppCryptoProvider.cpp#L301
...is caught here:
https://github.com/readium/readium-lcp-client/blob/e4c02fdd396157062b80dcd6b787a2c6a72a0da0/src/lcp-client-lib/CryptoppCryptoProvider.cpp#L306-L309
...which allows graceful continuation of the
m_storageProvider->EnumerateVault
iteration, here:https://github.com/readium/readium-lcp-client/blob/e4c02fdd396157062b80dcd6b787a2c6a72a0da0/src/lcp-client-lib/LcpService.cpp#L454-L456