From f1fee7b3c1a532e7e629e4f8d36d8a29a09f6acc Mon Sep 17 00:00:00 2001 From: danielweck Date: Thu, 2 Mar 2017 21:29:33 +0000 Subject: [PATCH 01/42] disable LCP profile URI / name customization, as all encryption specs can be discovered via their URI (and the server can generate both basic and v1.0 profile with identical specs) --- platform/apple/src/LCPError.h | 2 ++ src/lcp-client-lib/CryptoLcpNode.cpp | 4 +++ src/lcp-client-lib/CryptoppCryptoProvider.cpp | 26 ++++++++++++++++++- src/lcp-client-lib/EncryptionProfileNames.cpp | 1 + src/lcp-client-lib/EncryptionProfileNames.h | 1 + .../EncryptionProfilesManager.cpp | 13 +++++++++- .../EncryptionProfilesManager.h | 11 ++++++++ src/lcp-client-lib/IEncryptionProfile.h | 2 ++ .../Lcp1dot0EncryptionProfile.cpp | 7 +++++ .../Lcp1dot0EncryptionProfile.h | 2 ++ src/lcp-client-lib/LcpService.cpp | 9 +++++++ test/lcp-client-lib/tests/CertificateTest.cpp | 25 ++++++++++++++++++ .../tests/CryptoppCryptoProviderTest.cpp | 2 ++ 13 files changed, 103 insertions(+), 2 deletions(-) diff --git a/platform/apple/src/LCPError.h b/platform/apple/src/LCPError.h index 7fd2aaf..f5ff5d4 100644 --- a/platform/apple/src/LCPError.h +++ b/platform/apple/src/LCPError.h @@ -34,7 +34,9 @@ extern NSString *const LCPErrorExtensionKey; // @see LcpStatus.h for documentation extern NSInteger const LCPErrorCommonNoNetProvider; extern NSInteger const LCPErrorCommonNoStorageProvider; +#if ENABLE_PROFILE_NAMES extern NSInteger const LCPErrorCommonEncryptionProfileNotFound; +#endif //ENABLE_PROFILE_NAMES extern NSInteger const LCPErrorCommonAlgorithmMismatch; extern NSInteger const LCPErrorOpeningLicenseNotValid; extern NSInteger const LCPErrorOpeningLicenseNotStarted; diff --git a/src/lcp-client-lib/CryptoLcpNode.cpp b/src/lcp-client-lib/CryptoLcpNode.cpp index 10dda22..839856d 100644 --- a/src/lcp-client-lib/CryptoLcpNode.cpp +++ b/src/lcp-client-lib/CryptoLcpNode.cpp @@ -96,11 +96,15 @@ namespace lcp Status CryptoLcpNode::VerifyNode(ILicense * license, IClientProvider * clientProvider, ICryptoProvider * cryptoProvider) { +#if ENABLE_PROFILE_NAMES m_encryptionProfile = m_encryptionProfilesManager->GetProfile(m_cryptoInfo.encryptionProfile); if (m_encryptionProfile == nullptr) { return Status(StatusCode::ErrorCommonEncryptionProfileNotFound, "ErrorCommonEncryptionProfileNotFound"); } +#else + m_encryptionProfile = m_encryptionProfilesManager->GetProfile(); +#endif //ENABLE_PROFILE_NAMES if (m_encryptionProfile->ContentKeyAlgorithmCBC() != m_cryptoInfo.contentKeyAlgorithm && m_encryptionProfile->ContentKeyAlgorithmGCM() != m_cryptoInfo.contentKeyAlgorithm) { diff --git a/src/lcp-client-lib/CryptoppCryptoProvider.cpp b/src/lcp-client-lib/CryptoppCryptoProvider.cpp index 360f1b8..e5aed8f 100644 --- a/src/lcp-client-lib/CryptoppCryptoProvider.cpp +++ b/src/lcp-client-lib/CryptoppCryptoProvider.cpp @@ -104,11 +104,15 @@ namespace lcp { try { +#if ENABLE_PROFILE_NAMES IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(license->Crypto()->EncryptionProfile()); if (profile == nullptr) { return Status(StatusCode::ErrorCommonEncryptionProfileNotFound, "ErrorCommonEncryptionProfileNotFound"); } +#else + IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(); +#endif //ENABLE_PROFILE_NAMES if (rootCertificateBase64.empty()) { @@ -190,11 +194,15 @@ namespace lcp { try { +#if ENABLE_PROFILE_NAMES IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(license->Crypto()->EncryptionProfile()); if (profile == nullptr) { return Status(StatusCode::ErrorCommonEncryptionProfileNotFound, "ErrorCommonEncryptionProfileNotFound"); } +#else + IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(); +#endif //ENABLE_PROFILE_NAMES std::unique_ptr hashAlgorithm(profile->CreateUserKeyAlgorithm()); hashAlgorithm->UpdateHash(userPassphrase); @@ -226,11 +234,15 @@ namespace lcp { try { +#if ENABLE_PROFILE_NAMES IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(license->Crypto()->EncryptionProfile()); if (profile == nullptr) { return Status(StatusCode::ErrorCommonEncryptionProfileNotFound, "ErrorCommonEncryptionProfileNotFound"); } +#else + IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(); +#endif //ENABLE_PROFILE_NAMES //http://www.w3.org/2009/xmlenc11#aes256-gcm //http://www.w3.org/2001/04/xmlenc#aes256-cbc @@ -333,11 +345,15 @@ namespace lcp { try { +#if ENABLE_PROFILE_NAMES IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(license->Crypto()->EncryptionProfile()); if (profile == nullptr) { return Status(StatusCode::ErrorCommonEncryptionProfileNotFound, "ErrorCommonEncryptionProfileNotFound"); } +#else + IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(); +#endif //ENABLE_PROFILE_NAMES //http://www.w3.org/2009/xmlenc11#aes256-gcm //http://www.w3.org/2001/04/xmlenc#aes256-cbc @@ -365,11 +381,15 @@ namespace lcp { try { +#if ENABLE_PROFILE_NAMES IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(license->Crypto()->EncryptionProfile()); if (profile == nullptr) { return Status(StatusCode::ErrorCommonEncryptionProfileNotFound, "ErrorCommonEncryptionProfileNotFound"); } +#else + IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(); +#endif //ENABLE_PROFILE_NAMES std::unique_ptr algo(profile->CreatePublicationAlgorithm(keyProvider->ContentKey(), algorithm)); *decryptedDataLength = algo->Decrypt( @@ -394,11 +414,15 @@ namespace lcp { try { +#if ENABLE_PROFILE_NAMES IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(license->Crypto()->EncryptionProfile()); if (profile == nullptr) { return Status(StatusCode::ErrorCommonEncryptionProfileNotFound, "ErrorCommonEncryptionProfileNotFound"); } +#else + IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(); +#endif //ENABLE_PROFILE_NAMES Status res(StatusCode::ErrorCommonSuccess); std::unique_ptr algo(profile->CreatePublicationAlgorithm(keyProvider->ContentKey(), algorithm)); @@ -451,4 +475,4 @@ namespace lcp return Status(StatusCode::ErrorCommonSuccess); } #endif //!DISABLE_CRL -} \ No newline at end of file +} diff --git a/src/lcp-client-lib/EncryptionProfileNames.cpp b/src/lcp-client-lib/EncryptionProfileNames.cpp index 441cd72..a73f51c 100644 --- a/src/lcp-client-lib/EncryptionProfileNames.cpp +++ b/src/lcp-client-lib/EncryptionProfileNames.cpp @@ -30,4 +30,5 @@ namespace lcp { /*static*/ std::string EncryptionProfileNames::Lcp1dot0ProfileId = "http://readium.org/lcp/profile-1.0"; + /*static*/ std::string EncryptionProfileNames::LcpBasicProfileId = "http://readium.org/lcp/basic-profile"; } \ No newline at end of file diff --git a/src/lcp-client-lib/EncryptionProfileNames.h b/src/lcp-client-lib/EncryptionProfileNames.h index f816e48..0213475 100644 --- a/src/lcp-client-lib/EncryptionProfileNames.h +++ b/src/lcp-client-lib/EncryptionProfileNames.h @@ -36,6 +36,7 @@ namespace lcp { public: static std::string Lcp1dot0ProfileId; + static std::string LcpBasicProfileId; }; } diff --git a/src/lcp-client-lib/EncryptionProfilesManager.cpp b/src/lcp-client-lib/EncryptionProfilesManager.cpp index 9787a09..635fa33 100644 --- a/src/lcp-client-lib/EncryptionProfilesManager.cpp +++ b/src/lcp-client-lib/EncryptionProfilesManager.cpp @@ -32,10 +32,15 @@ namespace lcp { EncryptionProfilesManager::EncryptionProfilesManager() { +#if ENABLE_PROFILE_NAMES std::unique_ptr lcp1dot0(new Lcp1dot0EncryptionProfile()); m_profilesMap.insert(std::make_pair(lcp1dot0->Name(), std::move(lcp1dot0))); +#else + m_profile.reset(new Lcp1dot0EncryptionProfile()); +#endif //ENABLE_PROFILE_NAMES } +#if ENABLE_PROFILE_NAMES bool EncryptionProfilesManager::RegisterProfile(std::unique_ptr profile) { std::unique_lock locker(m_profilesSync); @@ -53,4 +58,10 @@ namespace lcp } return nullptr; } -} \ No newline at end of file +#else + IEncryptionProfile * EncryptionProfilesManager::GetProfile() const + { + return m_profile.get(); + } +#endif //ENABLE_PROFILE_NAMES +} diff --git a/src/lcp-client-lib/EncryptionProfilesManager.h b/src/lcp-client-lib/EncryptionProfilesManager.h index 09e6d6e..4725c5b 100644 --- a/src/lcp-client-lib/EncryptionProfilesManager.h +++ b/src/lcp-client-lib/EncryptionProfilesManager.h @@ -28,9 +28,12 @@ #ifndef __ENCRYPTION_PROFILES_MANAGER_H__ #define __ENCRYPTION_PROFILES_MANAGER_H__ +#if ENABLE_PROFILE_NAMES #include #include #include +#endif //ENABLE_PROFILE_NAMES + #include "IEncryptionProfile.h" #include "NonCopyable.h" @@ -40,13 +43,21 @@ namespace lcp { public: EncryptionProfilesManager(); +#if ENABLE_PROFILE_NAMES bool RegisterProfile(std::unique_ptr profile); IEncryptionProfile * GetProfile(const std::string & name) const; +#else + IEncryptionProfile * GetProfile() const; +#endif //ENABLE_PROFILE_NAMES private: +#if ENABLE_PROFILE_NAMES typedef std::map > ProfilesMap; ProfilesMap m_profilesMap; mutable std::mutex m_profilesSync; +#else + std::unique_ptr m_profile; +#endif //ENABLE_PROFILE_NAMES }; } diff --git a/src/lcp-client-lib/IEncryptionProfile.h b/src/lcp-client-lib/IEncryptionProfile.h index 4d0546c..3f89595 100644 --- a/src/lcp-client-lib/IEncryptionProfile.h +++ b/src/lcp-client-lib/IEncryptionProfile.h @@ -41,7 +41,9 @@ namespace lcp class IEncryptionProfile { public: +#if ENABLE_PROFILE_NAMES virtual std::string Name() const = 0; +#endif //ENABLE_PROFILE_NAMES virtual std::string UserKeyAlgorithm() const = 0; virtual std::string PublicationAlgorithmGCM() const = 0; virtual std::string PublicationAlgorithmCBC() const = 0; diff --git a/src/lcp-client-lib/Lcp1dot0EncryptionProfile.cpp b/src/lcp-client-lib/Lcp1dot0EncryptionProfile.cpp index 1b4a7a8..df7b9db 100644 --- a/src/lcp-client-lib/Lcp1dot0EncryptionProfile.cpp +++ b/src/lcp-client-lib/Lcp1dot0EncryptionProfile.cpp @@ -96,11 +96,18 @@ namespace lcp throw StatusException(Status(StatusCode::ErrorCommonAlgorithmMismatch, "ErrorCommonAlgorithmMismatch")); } +#if ENABLE_PROFILE_NAMES std::string Lcp1dot0EncryptionProfile::Name() const { //http://readium.org/lcp/profile-1.0 return EncryptionProfileNames::Lcp1dot0ProfileId; + + ...OR? + + //http://readium.org/lcp/basic-profile + return EncryptionProfileNames::LcpBasicProfileId } +#endif //ENABLE_PROFILE_NAMES std::string Lcp1dot0EncryptionProfile::UserKeyAlgorithm() const { diff --git a/src/lcp-client-lib/Lcp1dot0EncryptionProfile.h b/src/lcp-client-lib/Lcp1dot0EncryptionProfile.h index 2d3a0fb..257dcf5 100644 --- a/src/lcp-client-lib/Lcp1dot0EncryptionProfile.h +++ b/src/lcp-client-lib/Lcp1dot0EncryptionProfile.h @@ -36,7 +36,9 @@ namespace lcp class Lcp1dot0EncryptionProfile : public IEncryptionProfile { public: +#if ENABLE_PROFILE_NAMES virtual std::string Name() const; +#endif //ENABLE_PROFILE_NAMES virtual std::string UserKeyAlgorithm() const; virtual std::string PublicationAlgorithmGCM() const; virtual std::string PublicationAlgorithmCBC() const; diff --git a/src/lcp-client-lib/LcpService.cpp b/src/lcp-client-lib/LcpService.cpp index 20b7402..1507c96 100644 --- a/src/lcp-client-lib/LcpService.cpp +++ b/src/lcp-client-lib/LcpService.cpp @@ -448,11 +448,16 @@ namespace lcp return Status(StatusCode::ErrorDecryptionLicenseEncrypted, "ErrorDecryptionLicenseEncrypted"); } +#if ENABLE_PROFILE_NAMES IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(license->Crypto()->EncryptionProfile()); if (profile == nullptr) { return Status(StatusCode::ErrorCommonEncryptionProfileNotFound, "ErrorCommonEncryptionProfileNotFound"); } +#else + IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(); +#endif //ENABLE_PROFILE_NAMES + if (algorithm != profile->PublicationAlgorithmGCM() && algorithm != profile->PublicationAlgorithmCBC()) { return Status(StatusCode::ErrorCommonAlgorithmMismatch, "ErrorCommonAlgorithmMismatch"); @@ -499,11 +504,15 @@ namespace lcp return Status(StatusCode::ErrorDecryptionLicenseEncrypted, "ErrorDecryptionLicenseEncrypted"); } +#if ENABLE_PROFILE_NAMES IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(license->Crypto()->EncryptionProfile()); if (profile == nullptr) { return Status(StatusCode::ErrorCommonEncryptionProfileNotFound, "ErrorCommonEncryptionProfileNotFound"); } +#else + IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(); +#endif //ENABLE_PROFILE_NAMES if (algorithm != profile->PublicationAlgorithmGCM() && algorithm != profile->PublicationAlgorithmCBC()) { diff --git a/test/lcp-client-lib/tests/CertificateTest.cpp b/test/lcp-client-lib/tests/CertificateTest.cpp index 4e10330..ca0339f 100644 --- a/test/lcp-client-lib/tests/CertificateTest.cpp +++ b/test/lcp-client-lib/tests/CertificateTest.cpp @@ -40,7 +40,12 @@ namespace lcptest TEST(CertificateTest, CertificateDistributionPoints) { lcp::EncryptionProfilesManager profilesManager; + +#if ENABLE_PROFILE_NAMES lcp::IEncryptionProfile * profile = profilesManager.GetProfile("http://readium.org/lcp/profile-1.0"); +#else + lcp::IEncryptionProfile * profile = profilesManager.GetProfile(); +#endif //ENABLE_PROFILE_NAMES ASSERT_NE(profile, nullptr); @@ -55,7 +60,12 @@ namespace lcptest TEST(CertificateTest, CertificateRevocationList_) { lcp::EncryptionProfilesManager profilesManager; + +#if ENABLE_PROFILE_NAMES lcp::IEncryptionProfile * profile = profilesManager.GetProfile("http://readium.org/lcp/profile-1.0"); +#else + lcp::IEncryptionProfile * profile = profilesManager.GetProfile(); +#endif //ENABLE_PROFILE_NAMES ASSERT_NE(profile, nullptr); @@ -84,7 +94,12 @@ namespace lcptest TEST(CertificateTest, CertificateParse) { lcp::EncryptionProfilesManager profilesManager; + +#if ENABLE_PROFILE_NAMES lcp::IEncryptionProfile * profile = profilesManager.GetProfile("http://readium.org/lcp/profile-1.0"); +#else + lcp::IEncryptionProfile * profile = profilesManager.GetProfile(); +#endif //ENABLE_PROFILE_NAMES ASSERT_NE(profile, nullptr); @@ -98,7 +113,12 @@ namespace lcptest TEST(CertificateTest, CertificateVerifyByRoot) { lcp::EncryptionProfilesManager profilesManager; + +#if ENABLE_PROFILE_NAMES lcp::IEncryptionProfile * profile = profilesManager.GetProfile("http://readium.org/lcp/profile-1.0"); +#else + lcp::IEncryptionProfile * profile = profilesManager.GetProfile(); +#endif //ENABLE_PROFILE_NAMES ASSERT_NE(profile, nullptr); @@ -111,7 +131,12 @@ namespace lcptest TEST(CertificateTest, CertificateVerifySignature) { lcp::EncryptionProfilesManager profilesManager; + +#if ENABLE_PROFILE_NAMES lcp::IEncryptionProfile * profile = profilesManager.GetProfile("http://readium.org/lcp/profile-1.0"); +#else + lcp::IEncryptionProfile * profile = profilesManager.GetProfile(); +#endif //ENABLE_PROFILE_NAMES ASSERT_NE(profile, nullptr); diff --git a/test/lcp-client-lib/tests/CryptoppCryptoProviderTest.cpp b/test/lcp-client-lib/tests/CryptoppCryptoProviderTest.cpp index ec64cca..e5d65a5 100644 --- a/test/lcp-client-lib/tests/CryptoppCryptoProviderTest.cpp +++ b/test/lcp-client-lib/tests/CryptoppCryptoProviderTest.cpp @@ -60,6 +60,7 @@ namespace lcptest ASSERT_EQ(lcp::StatusCode::ErrorCommonSuccess, res.Code); } +#if ENABLE_PROFILE_NAMES TEST_F(CryptoppCryptoProviderTest, VerifyLicense_Return_ErrorCommonEncryptionProfileNotFound) { FakeCryptoImpl crypto; @@ -69,6 +70,7 @@ namespace lcptest lcp::Status res = m_cryptoProvider->VerifyLicense(TestCertificate, &license); ASSERT_EQ(lcp::StatusCode::ErrorCommonEncryptionProfileNotFound, res.Code); } +#endif //ENABLE_PROFILE_NAMES TEST_F(CryptoppCryptoProviderTest, VerifyLicense_Return_ErrorOpeningNoRootCertificate) { From b83ac0659f54ba64338608570af0b2436c20a2f3 Mon Sep 17 00:00:00 2001 From: danielweck Date: Fri, 3 Mar 2017 10:57:43 +0000 Subject: [PATCH 02/42] excluded the actual LCP profile names / URIs from the build --- src/lcp-client-lib/EncryptionProfileNames.cpp | 6 +++++- src/lcp-client-lib/EncryptionProfileNames.h | 4 ++++ src/lcp-client-lib/Lcp1dot0EncryptionProfile.cpp | 6 +++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/lcp-client-lib/EncryptionProfileNames.cpp b/src/lcp-client-lib/EncryptionProfileNames.cpp index a73f51c..a407a1a 100644 --- a/src/lcp-client-lib/EncryptionProfileNames.cpp +++ b/src/lcp-client-lib/EncryptionProfileNames.cpp @@ -27,8 +27,12 @@ #include "EncryptionProfileNames.h" +#if ENABLE_PROFILE_NAMES + namespace lcp { /*static*/ std::string EncryptionProfileNames::Lcp1dot0ProfileId = "http://readium.org/lcp/profile-1.0"; /*static*/ std::string EncryptionProfileNames::LcpBasicProfileId = "http://readium.org/lcp/basic-profile"; -} \ No newline at end of file +} + +#endif //ENABLE_PROFILE_NAMES diff --git a/src/lcp-client-lib/EncryptionProfileNames.h b/src/lcp-client-lib/EncryptionProfileNames.h index 0213475..2b099ed 100644 --- a/src/lcp-client-lib/EncryptionProfileNames.h +++ b/src/lcp-client-lib/EncryptionProfileNames.h @@ -28,6 +28,8 @@ #ifndef __ENCRYPTION_PROFILE_NAMES_H__ #define __ENCRYPTION_PROFILE_NAMES_H__ +#if ENABLE_PROFILE_NAMES + #include namespace lcp @@ -40,4 +42,6 @@ namespace lcp }; } +#endif //ENABLE_PROFILE_NAMES + #endif //__ENCRYPTION_PROFILE_NAMES_H__ diff --git a/src/lcp-client-lib/Lcp1dot0EncryptionProfile.cpp b/src/lcp-client-lib/Lcp1dot0EncryptionProfile.cpp index df7b9db..bbd482f 100644 --- a/src/lcp-client-lib/Lcp1dot0EncryptionProfile.cpp +++ b/src/lcp-client-lib/Lcp1dot0EncryptionProfile.cpp @@ -26,7 +26,11 @@ #include "Lcp1dot0EncryptionProfile.h" + +#if ENABLE_PROFILE_NAMES #include "EncryptionProfileNames.h" +#endif //ENABLE_PROFILE_NAMES + #include "AlgorithmNames.h" #include "LcpUtils.h" @@ -150,4 +154,4 @@ namespace lcp //http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256 return AlgorithmNames::EcdsaSha256Id; } -} \ No newline at end of file +} From cce10e3212cc0dccc77bb5af1c516cfc75b81592 Mon Sep 17 00:00:00 2001 From: danielweck Date: Fri, 3 Mar 2017 13:14:33 +0000 Subject: [PATCH 03/42] fixed Android build (C++ requires std:: imports) --- src/lcp-client-lib/EncryptionProfilesManager.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lcp-client-lib/EncryptionProfilesManager.h b/src/lcp-client-lib/EncryptionProfilesManager.h index 4725c5b..87d7862 100644 --- a/src/lcp-client-lib/EncryptionProfilesManager.h +++ b/src/lcp-client-lib/EncryptionProfilesManager.h @@ -30,10 +30,11 @@ #if ENABLE_PROFILE_NAMES #include -#include #include #endif //ENABLE_PROFILE_NAMES +#include + #include "IEncryptionProfile.h" #include "NonCopyable.h" From 2e5e58ce9f2f0534a974d703d2845364a9e6c1b3 Mon Sep 17 00:00:00 2001 From: danielweck Date: Tue, 7 Mar 2017 12:24:13 +0000 Subject: [PATCH 04/42] Android JNI: added support for UserKey Hint (JSON text_hint in LCPL) --- platform/android/lcp/src/main/jni/License.cpp | 8 ++++++++ platform/android/lcp/src/main/jni/License.h | 3 +++ .../lib/src/main/java/org/readium/sdk/lcp/License.java | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/platform/android/lcp/src/main/jni/License.cpp b/platform/android/lcp/src/main/jni/License.cpp index 02ba883..702cf74 100644 --- a/platform/android/lcp/src/main/jni/License.cpp +++ b/platform/android/lcp/src/main/jni/License.cpp @@ -49,6 +49,14 @@ JNIEXPORT jstring JNICALL Java_org_readium_sdk_lcp_License_nativeGetOriginalCont return res; } +JNIEXPORT jstring JNICALL Java_org_readium_sdk_lcp_License_nativeGetPassphraseHint( + JNIEnv *env, jobject obj, jlong licensePtr) { + lcp::ILicense * license = (lcp::ILicense *) licensePtr; + std::string hint = license->Crypto()->UserKeyHint(); + jstring res = env->NewStringUTF(hint.c_str()); + return res; +} + JNIEXPORT jstring JNICALL Java_org_readium_sdk_lcp_License_nativeGetLinkPublication( JNIEnv *env, jobject obj, jlong licensePtr) { lcp::ILicense * license = (lcp::ILicense *) licensePtr; diff --git a/platform/android/lcp/src/main/jni/License.h b/platform/android/lcp/src/main/jni/License.h index 5faf05c..22a7ed9 100644 --- a/platform/android/lcp/src/main/jni/License.h +++ b/platform/android/lcp/src/main/jni/License.h @@ -45,6 +45,9 @@ JNIEXPORT jboolean JNICALL Java_org_readium_sdk_lcp_License_nativeIsDecrypted( JNIEXPORT jstring JNICALL Java_org_readium_sdk_lcp_License_nativeGetOriginalContent( JNIEnv *env, jobject obj, jlong licensePtr); +JNIEXPORT jstring JNICALL Java_org_readium_sdk_lcp_License_nativeGetPassphraseHint( + JNIEnv *env, jobject obj, jlong licensePtr); + JNIEXPORT jstring JNICALL Java_org_readium_sdk_lcp_License_nativeGetLinkPublication( JNIEnv *env, jobject obj, jlong licensePtr); diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/License.java b/platform/android/lib/src/main/java/org/readium/sdk/lcp/License.java index 4588a32..8163fe0 100644 --- a/platform/android/lib/src/main/java/org/readium/sdk/lcp/License.java +++ b/platform/android/lib/src/main/java/org/readium/sdk/lcp/License.java @@ -43,6 +43,10 @@ public String getOriginalContent() { return this.nativeGetOriginalContent(this.nativePtr); } + public String getPassphraseHint() { + return this.nativeGetPassphraseHint(this.nativePtr); + } + public void decrypt(String passphrase) { this.nativeDecrypt(this.nativePtr, this.servicePtr, passphrase); } @@ -86,6 +90,8 @@ private long getNativePtr() { private native String nativeGetOriginalContent(long nativePtr); + private native String nativeGetPassphraseHint(long nativePtr); + private native String nativeGetLinkPublication(long nativePtr); private native String nativeGetLinkStatus(long nativePtr); From ddeeefe5b143276d5704fcf3abb0608c7705a686 Mon Sep 17 00:00:00 2001 From: danielweck Date: Tue, 7 Mar 2017 14:18:31 +0000 Subject: [PATCH 05/42] added support for empty hint URL --- src/lcp-client-lib/LinksLcpNode.cpp | 20 ++++++++++++++------ src/lcp-client-lib/LinksLcpNode.h | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/lcp-client-lib/LinksLcpNode.cpp b/src/lcp-client-lib/LinksLcpNode.cpp index f153bfc..e303366 100644 --- a/src/lcp-client-lib/LinksLcpNode.cpp +++ b/src/lcp-client-lib/LinksLcpNode.cpp @@ -79,18 +79,20 @@ namespace lcp rapidjson::Type type = linksMember->value.GetType(); + bool checkHref = name != Hint; + if (type == rapidjson::kObjectType) { const rapidjson::Value & linkObject = linksMember->value; - Link link = this->ParseLinkValues(linkObject, reader); + Link link = this->ParseLinkValues(linkObject, reader, checkHref); m_linksMultiMap.insert(std::make_pair(name, link)); } else if (type == rapidjson::kArrayType) { for (auto linkObject = linksMember->value.Begin(); linkObject != linksMember->value.End(); ++linkObject) { - Link link = this->ParseLinkValues(*linkObject, reader); + Link link = this->ParseLinkValues(*linkObject, reader, checkHref); m_linksMultiMap.insert(std::make_pair(name, link)); } } @@ -134,12 +136,14 @@ namespace lcp { throw StatusException(Status(StatusCode::ErrorOpeningLicenseNotValid, "ErrorOpeningLicenseNotValid: links object is not valid")); } + + bool checkHref = true; if (name == Hint) { hintFound = true; + checkHref = false; } - - Link link = this->ParseLinkValues(*linkObject, reader); + Link link = this->ParseLinkValues(*linkObject, reader, checkHref); m_linksMultiMap.insert(std::make_pair(name, link)); } @@ -217,10 +221,14 @@ namespace lcp return new MultiMapIterator(m_linksMultiMap); } - Link LinksLcpNode::ParseLinkValues(const rapidjson::Value & linkObject, JsonValueReader * reader) + Link LinksLcpNode::ParseLinkValues(const rapidjson::Value & linkObject, JsonValueReader * reader, bool checkHref) { Link link; - link.href = reader->ReadStringCheck("href", linkObject); + if (checkHref) { + link.href = reader->ReadStringCheck("href", linkObject); + } else { + link.href = reader->ReadString("href", linkObject); + } link.title = reader->ReadString("title", linkObject); link.type = reader->ReadString("type", linkObject); link.templated = reader->ReadBoolean("templated", linkObject); diff --git a/src/lcp-client-lib/LinksLcpNode.h b/src/lcp-client-lib/LinksLcpNode.h index a3a679d..c8f8802 100644 --- a/src/lcp-client-lib/LinksLcpNode.h +++ b/src/lcp-client-lib/LinksLcpNode.h @@ -52,7 +52,7 @@ namespace lcp virtual bool GetLinks(const std::string & name, std::vector & links) const; private: - Link ParseLinkValues(const rapidjson::Value & linkObject, JsonValueReader * reader); + Link ParseLinkValues(const rapidjson::Value & linkObject, JsonValueReader * reader, bool checkHref); private: typedef std::multimap LinksMap; From be7c82c6fabdd0c8938db0a3adbbebf9ac2f664e Mon Sep 17 00:00:00 2001 From: Cyrille Lebeaupin Date: Fri, 2 Dec 2016 13:27:06 +0100 Subject: [PATCH 06/42] Build lcp with static library --- platform/android/lcp/build.gradle | 6 +- .../static_library_dependency_build.gradle | 122 ++++++++++++++++++ 2 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 platform/android/lcp/static_library_dependency_build.gradle diff --git a/platform/android/lcp/build.gradle b/platform/android/lcp/build.gradle index 7faa8a2..dd6ecb5 100644 --- a/platform/android/lcp/build.gradle +++ b/platform/android/lcp/build.gradle @@ -4,8 +4,12 @@ def ndk_skipX86 = (rootProject.hasProperty("readium_ndk_skipX86") && rootProject def ndk_skipARM = (rootProject.hasProperty("readium_ndk_skipARM") && rootProject.readium_ndk_skipARM) def ndk_clang = (rootProject.hasProperty("readium_ndk_clang") && rootProject.readium_ndk_clang) def ndk_experimental = (rootProject.hasProperty("readium_ndk_experimental") && rootProject.readium_ndk_experimental) +def lcp_client_distribution_dir = rootProject.readium_lcp_client_distribution_dir -if (ndk_experimental) { +if (lcp_client_distribution_dir) { + println "${project.name}: Using Gradle STATIC LIBRARY DEPENDENCY to build LCP lib" + apply from: 'static_library_dependency_build.gradle' +} else if (ndk_experimental) { println "${project.name}: Using Gradle EXPERIMENTAL to build LCP lib" apply from: 'build_experimental.gradle' } else { diff --git a/platform/android/lcp/static_library_dependency_build.gradle b/platform/android/lcp/static_library_dependency_build.gradle new file mode 100644 index 0000000..51b6451 --- /dev/null +++ b/platform/android/lcp/static_library_dependency_build.gradle @@ -0,0 +1,122 @@ +apply plugin: 'com.android.model.native' + +def ndk_skipX86 = (rootProject.hasProperty("readium_ndk_skipX86") && rootProject.readium_ndk_skipX86) +def ndk_skipARM = (rootProject.hasProperty("readium_ndk_skipARM") && rootProject.readium_ndk_skipARM) +def ndk_clang = (rootProject.hasProperty("readium_ndk_clang") && rootProject.readium_ndk_clang) +def ndk_experimental = (rootProject.hasProperty("readium_ndk_experimental") && rootProject.readium_ndk_experimental) +q + +model { + repositories { + libs(PrebuiltLibraries) { + lcp_client { + headers.srcDir "${lcp_client_distribution_dir}/include" + binaries.withType(StaticLibraryBinary) { + staticLibraryFile = file("${lcp_client_distribution_dir}/${targetPlatform.getName()}/lib/libedrlab-lcp-client.a") + } + } + } + } + + android { + compileSdkVersion = 25 + sources { + main { + jni { + source { + srcDirs = [ + './src/main/jni', + '../../../src/lcp-content-filter' + ] + } //source + + exportedHeaders { + srcDir "./src/main/jni" + } + + dependencies { + library "lcp_client" linkage "static" + project ":epub3" linkage "shared" + } + } + } + } //sources + + ndk { + moduleName = "lcp" + + //arguments "-j 4" //Runtime.runtime.availableProcessors() + + toolchain = ndk_clang ? "clang" : "gcc" + toolchainVersion = ndk_clang ? "" : "4.9" //https://github.com/android-ndk/ndk/issues/229 + + def clangWithGnuStl = false + + if (!ndk_clang || clangWithGnuStl) + stl = "gnustl_shared" + else + stl = "c++_shared" + + def arrayFlags = [ + "-fexceptions", + "-fpic", + "-DFEATURES_READIUM", + "-DDISABLE_LSD_", + "-DZLIB_ONLY", + ndk_clang ? "-D_LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49=_LIBCPP_INLINE_VISIBILITY" : "-DREADIUM_GCC", + "-I" + project(':epub3').projectDir + "/include", + "-I${file("../../../src/lcp-client-lib")}".toString(), + "-I${file("../../../src/lcp-client-lib/public")}".toString(), + "-I${file("../../../src/lcp-content-filter")}".toString(), + "-I${file("../../../src/lcp-content-filter/public")}".toString(), + ] + + def arrayFlagsCPP = [ + "-fpermissive", + "-frtti" + ] + + cppFlags.addAll(arrayFlags) + cppFlags.addAll(arrayFlagsCPP) + cppFlags.add((!ndk_clang || clangWithGnuStl) ? "-std=gnu++11" : "-std=c++11") + + CFlags.addAll(arrayFlags) + CFlags.add((!ndk_clang || clangWithGnuStl) ? "-std=gnu11" : "-std=c11") + + ldLibs.addAll(['z', 'android', 'log']) + if (ndk_clang) ldLibs.addAll(['atomic']) + } //ndk + + buildTypes { + release { + + } + debug { + ndk.with { + debuggable = true //"NDK_DEBUG=1" + } + } + } //buildTypes + + productFlavors { + if (!ndk_skipARM) + create("arm") { + ndk.with { + abiFilters.add("armeabi-v7a") + ldFlags.addAll([ + "-L${file("./obj/local/armeabi-v7a")}".toString() + ]) + } + } + if (!ndk_skipX86) + create("x86") { + ndk.with { + abiFilters.add("x86") + ldFlags.addAll([ + "-L${file("./obj/local/x86")}".toString() + ]) + } + } + } //productFlavors + } //android +} //model \ No newline at end of file From a20d0a588c55bd4a5bc320978f974c01b7a44a09 Mon Sep 17 00:00:00 2001 From: "L. Le Meur" Date: Fri, 5 May 2017 11:42:34 +0200 Subject: [PATCH 07/42] update LCP name (Lightweight -> Licensed) and maintainers --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cb11841..816287d 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ readium-lcp-client ================== -This repository is for the Readium Lightweight Content Protection (LCP) client side implementation work. +This repository is for the Readium Licensed Content Protection (LCP) client side implementation work. Created by Artem Brazhnikov, Mickaƫl Menu. +Maintained by Cyrille Lebeaupin, Daniel Weck. ## Overview From 5ed02cee157da648e4968819215ae17f97efef4a Mon Sep 17 00:00:00 2001 From: danielweck Date: Tue, 9 May 2017 11:00:06 +0100 Subject: [PATCH 08/42] see https://github.com/readium/readium-lcp-client/pull/26#issuecomment-300116695 --- src/third-parties/cryptopp/filters.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/third-parties/cryptopp/filters.cpp b/src/third-parties/cryptopp/filters.cpp index b848d99..1cd9d9a 100644 --- a/src/third-parties/cryptopp/filters.cpp +++ b/src/third-parties/cryptopp/filters.cpp @@ -618,8 +618,14 @@ void StreamTransformationFilter::InitializeDerivedAndReturnNewSizes(const NameVa else m_padding = padding; - if (!isBlockCipher && (m_padding == PKCS_PADDING || m_padding == ONE_AND_ZEROS_PADDING)) - throw InvalidArgument("StreamTransformationFilter: PKCS_PADDING and ONE_AND_ZEROS_PADDING cannot be used with " + m_cipher.AlgorithmName()); + if (!isBlockCipher && (m_padding == PKCS_PADDING)) + throw InvalidArgument("StreamTransformationFilter: PKCS_PADDING cannot be used with " + m_cipher.AlgorithmName()); + + if (!isBlockCipher && (m_padding == W3C_PADDING)) + throw InvalidArgument("StreamTransformationFilter: W3C_PADDING cannot be used with " + m_cipher.AlgorithmName()); + + if (!isBlockCipher && (m_padding == ONE_AND_ZEROS_PADDING)) + throw InvalidArgument("StreamTransformationFilter: ONE_AND_ZEROS_PADDING cannot be used with " + m_cipher.AlgorithmName()); firstSize = 0; blockSize = m_cipher.MandatoryBlockSize(); From a5d66277ceafb0b6c7bb38135fa32985d019f901 Mon Sep 17 00:00:00 2001 From: danielweck Date: Tue, 9 May 2017 17:35:55 +0100 Subject: [PATCH 09/42] temp disable CRL (NetProvider hangs on Android) + fixed mixed ECDSA - RSA certs signature and public key scenario (as with T-Systems certs) see https://github.com/readium/readium-lcp-client/issues/37 --- .../android/lcp/build_experimental.gradle | 1 + src/lcp-client-lib/Certificate.cpp | 106 ++++++++++-------- src/lcp-client-lib/Certificate.h | 7 +- src/lcp-client-lib/CryptoppCryptoProvider.cpp | 4 +- .../EcdsaSha256SignatureAlgorithm.cpp | 14 ++- .../EcdsaSha256SignatureAlgorithm.h | 5 +- .../RsaSha256SignatureAlgorithm.cpp | 14 ++- .../RsaSha256SignatureAlgorithm.h | 5 +- 8 files changed, 93 insertions(+), 63 deletions(-) diff --git a/platform/android/lcp/build_experimental.gradle b/platform/android/lcp/build_experimental.gradle index a726d27..a08f981 100644 --- a/platform/android/lcp/build_experimental.gradle +++ b/platform/android/lcp/build_experimental.gradle @@ -63,6 +63,7 @@ model { "-fexceptions", "-fpic", "-DFEATURES_READIUM", + "-DDISABLE_CRL", "-DZLIB_ONLY", ndk_clang ? "-D_LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49=_LIBCPP_INLINE_VISIBILITY" : "-DREADIUM_GCC", "-I" + project(':epub3').projectDir + "/include", diff --git a/src/lcp-client-lib/Certificate.cpp b/src/lcp-client-lib/Certificate.cpp index 8af23da..5a75c61 100644 --- a/src/lcp-client-lib/Certificate.cpp +++ b/src/lcp-client-lib/Certificate.cpp @@ -58,7 +58,6 @@ DEFINE_OID(ASN1::joint_iso_ccitt() + 5, joint_iso_ccitt_ds); DEFINE_OID(joint_iso_ccitt_ds() + 29, id_ce); DEFINE_OID(id_ce() + 31, id_ce_CRLDistributionPoints); - namespace lcp { Certificate::Certificate( @@ -74,7 +73,7 @@ namespace lcp certData.Put(rawDecodedCert.data(), rawDecodedCert.size()); certData.MessageEnd(); - ByteQueue subjectPublicKey; + ByteQueue subjectPublicKey; //CryptoPP::BufferedTransformation BERSequenceDecoder cert(certData); { @@ -98,13 +97,21 @@ namespace lcp // subject CryptoppUtils::Cert::SkipNextSequence(toBeSignedCert); + //subjectPublicKey (RSA or ECDSA) //CryptoppUtils::Cert::ReadSubjectPublicKey(toBeSignedCert, m_publicKeyRSA); - BERSequenceDecoder subjPublicInfoFrom(toBeSignedCert); - DERSequenceEncoder subjPublicInfoOut(subjectPublicKey); - subjPublicInfoFrom.TransferTo(subjPublicInfoOut, subjPublicInfoFrom.RemainingLength()); - subjPublicInfoOut.MessageEnd(); - subjPublicInfoFrom.MessageEnd(); + // subjectPublicKeyInfo + BERSequenceDecoder spki(toBeSignedCert); + DERSequenceEncoder spkiEncoder(subjectPublicKey); + spki.CopyTo(spkiEncoder); + spkiEncoder.MessageEnd(); + spki.SkipAll(); + // ----- EQUIVALENT: +// BERSequenceDecoder subjPublicInfoFrom(toBeSignedCert); +// DERSequenceEncoder subjPublicInfoOut(subjectPublicKey); +// subjPublicInfoFrom.TransferTo(subjPublicInfoOut, subjPublicInfoFrom.RemainingLength()); +// subjPublicInfoOut.MessageEnd(); +// subjPublicInfoFrom.MessageEnd(); while (!toBeSignedCert.EndReached()) @@ -157,39 +164,46 @@ namespace lcp algo = AlgorithmNames::RsaMd5Id; } - if (algo == AlgorithmNames::EcdsaSha256Id) { - m_publicKeyECDSA.BERDecode(subjectPublicKey); - } else { - m_publicKeyRSA.BERDecode(subjectPublicKey); - } +// m_publicKeyQueue = subjectPublicKey; - //this->PublicKey() - ByteQueue publicKeyQueue; - if (algo == AlgorithmNames::EcdsaSha256Id) { - m_publicKeyECDSA.DEREncode(publicKeyQueue); - } else { - m_publicKeyRSA.DEREncode(publicKeyQueue); - } - size_t size = static_cast(publicKeyQueue.MaxRetrievable()); +// if (algo == AlgorithmNames::EcdsaSha256Id) { +// m_publicKeyECDSA.BERDecode(subjectPublicKey); +// } else { +// m_publicKeyRSA.BERDecode(subjectPublicKey); +// } +// +// //this->PublicKey() +// ByteQueue publicKeyQueue; +// if (algo == AlgorithmNames::EcdsaSha256Id) { +// m_publicKeyECDSA.DEREncode(publicKeyQueue); +// } else { +// m_publicKeyRSA.DEREncode(publicKeyQueue); +// } + + size_t size = static_cast(subjectPublicKey.MaxRetrievable()); KeyType outKey(size); - publicKeyQueue.Get(&outKey.at(0), outKey.size()); + subjectPublicKey.Get(&outKey.at(0), outKey.size()); + m_publicKeyType = outKey; - m_signatureAlgorithm.reset(m_encryptionProfile->CreateSignatureAlgorithm(outKey, algo)); + m_signatureAlgorithm.reset(m_encryptionProfile->CreateSignatureAlgorithm(m_publicKeyType, algo)); } KeyType Certificate::PublicKey() const { - ByteQueue publicKeyQueue; - if (m_signatureAlgorithm->Name() == AlgorithmNames::EcdsaSha256Id) { - m_publicKeyECDSA.DEREncode(publicKeyQueue); - } else { - m_publicKeyRSA.DEREncode(publicKeyQueue); - } - - size_t size = static_cast(publicKeyQueue.MaxRetrievable()); - KeyType outKey(size); - publicKeyQueue.Get(&outKey.at(0), outKey.size()); - return outKey; + return m_publicKeyType; + +// ByteQueue publicKeyQueue; +// if (m_signatureAlgorithm->Name() == AlgorithmNames::EcdsaSha256Id) { +// m_publicKeyECDSA.DEREncode(publicKeyQueue); +// } else { +// m_publicKeyRSA.DEREncode(publicKeyQueue); +// } +// +// ByteQueue publicKeyQueue = m_publicKeyQueue; +// size_t size = static_cast(publicKeyQueue.MaxRetrievable()); +// KeyType outKey(size); +// publicKeyQueue.Get(&outKey.at(0), outKey.size()); +// return outKey; } bool Certificate::VerifyMessage(const std::string & message, const std::string & hashBase64) @@ -218,32 +232,32 @@ namespace lcp KeyType rawPublicKey = rootCertificate->PublicKey(); publicKeyQueue.Put(&rawPublicKey.at(0), rawPublicKey.size()); publicKeyQueue.MessageEnd(); - - CryptoPP::ECDSA::PublicKey publicKeyECDSA; - CryptoPP::RSA::PublicKey publicKeyRSA; - - if (m_signatureAlgorithm->Name() == AlgorithmNames::EcdsaSha256Id) { - publicKeyECDSA.BERDecode(publicKeyQueue); - } else { - publicKeyRSA.BERDecode(publicKeyQueue); - } +// +// CryptoPP::ECDSA::PublicKey publicKeyECDSA; +// CryptoPP::RSA::PublicKey publicKeyRSA; +// +// if (m_signatureAlgorithm->Name() == AlgorithmNames::EcdsaSha256Id) { +// publicKeyECDSA.BERDecode(publicKeyQueue); +// } else { +// publicKeyRSA.BERDecode(publicKeyQueue); +// } std::unique_ptr rootVerifierPtr; if (m_signatureAlgorithm->Name() == AlgorithmNames::EcdsaSha256Id) { - rootVerifierPtr.reset(new ECDSA::Verifier(publicKeyECDSA)); + rootVerifierPtr.reset(new ECDSA::Verifier(publicKeyQueue)); } else if (m_signatureAlgorithmId == sha256withRSAEncryption()) { - rootVerifierPtr.reset(new RSASS::Verifier(publicKeyRSA)); + rootVerifierPtr.reset(new RSASS::Verifier(publicKeyQueue)); } else if (m_signatureAlgorithmId == sha1withRSAEncryption()) { - rootVerifierPtr.reset(new RSASS::Verifier(publicKeyRSA)); + rootVerifierPtr.reset(new RSASS::Verifier(publicKeyQueue)); } else if (m_signatureAlgorithmId == md5withRSAEncryption()) { - rootVerifierPtr.reset(new RSASS::Verifier(publicKeyRSA)); + rootVerifierPtr.reset(new RSASS::Verifier(publicKeyQueue)); } else { diff --git a/src/lcp-client-lib/Certificate.h b/src/lcp-client-lib/Certificate.h index 448621b..b90e43e 100644 --- a/src/lcp-client-lib/Certificate.h +++ b/src/lcp-client-lib/Certificate.h @@ -78,8 +78,11 @@ namespace lcp std::string m_notBeforeDate; std::string m_notAfterDate; - CryptoPP::ECDSA::PublicKey m_publicKeyECDSA; - CryptoPP::RSA::PublicKey m_publicKeyRSA; +// CryptoPP::ECDSA::PublicKey m_publicKeyECDSA; +//// CryptoPP::DL_PublicKey_EC m_publicKeyECDSA; +// CryptoPP::RSA::PublicKey m_publicKeyRSA; +// ByteQueue m_publicKeyQueue; + KeyType m_publicKeyType; SecByteBlock m_toBeSignedData; SecByteBlock m_rootSignature; diff --git a/src/lcp-client-lib/CryptoppCryptoProvider.cpp b/src/lcp-client-lib/CryptoppCryptoProvider.cpp index e5aed8f..80a2e8f 100644 --- a/src/lcp-client-lib/CryptoppCryptoProvider.cpp +++ b/src/lcp-client-lib/CryptoppCryptoProvider.cpp @@ -152,7 +152,9 @@ namespace lcp } #endif //!DISABLE_CRL - if (!providerCertificate->VerifyMessage(license->CanonicalContent(), license->Crypto()->Signature())) + //providerCertificate->VerifyMessage + lcp::ISignatureAlgorithm* signatureAlgorithm = profile->CreateSignatureAlgorithm(providerCertificate->PublicKey(), license->Crypto()->SignatureAlgorithm()); + if (!signatureAlgorithm->VerifySignature(license->CanonicalContent(), license->Crypto()->Signature())) { return Status(StatusCode::ErrorOpeningLicenseSignatureNotValid, "ErrorOpeningLicenseSignatureNotValid"); } diff --git a/src/lcp-client-lib/EcdsaSha256SignatureAlgorithm.cpp b/src/lcp-client-lib/EcdsaSha256SignatureAlgorithm.cpp index 9768e88..beedbcf 100644 --- a/src/lcp-client-lib/EcdsaSha256SignatureAlgorithm.cpp +++ b/src/lcp-client-lib/EcdsaSha256SignatureAlgorithm.cpp @@ -33,11 +33,7 @@ namespace lcp { EcdsaSha256SignatureAlgorithm::EcdsaSha256SignatureAlgorithm(const KeyType & publicKey) { - ByteQueue publicKeyQueue; - KeyType rawPublicKey = publicKey; - publicKeyQueue.Put(&rawPublicKey.at(0), rawPublicKey.size()); - publicKeyQueue.MessageEnd(); - m_publicKey.BERDecode(publicKeyQueue); + m_publicKeyType = publicKey; } std::string EcdsaSha256SignatureAlgorithm::Name() const @@ -68,7 +64,13 @@ namespace lcp size_t signatureLength ) { - ThisVerifier verifier(m_publicKey); + ByteQueue publicKeyQueue; + publicKeyQueue.Put(&m_publicKeyType.at(0), m_publicKeyType.size()); + publicKeyQueue.MessageEnd(); +// m_publicKey.BERDecode(publicKeyQueue); +// m_publicKeyQueue = publicKeyQueue; + + ThisVerifier verifier(publicKeyQueue); return verifier.VerifyMessage( message, messageLength, diff --git a/src/lcp-client-lib/EcdsaSha256SignatureAlgorithm.h b/src/lcp-client-lib/EcdsaSha256SignatureAlgorithm.h index 6d9c42b..a3a3539 100644 --- a/src/lcp-client-lib/EcdsaSha256SignatureAlgorithm.h +++ b/src/lcp-client-lib/EcdsaSha256SignatureAlgorithm.h @@ -59,7 +59,10 @@ namespace lcp private: typedef CryptoPP::ECDSA::Verifier ThisVerifier; - CryptoPP::ECDSA::PublicKey m_publicKey; + +// CryptoPP::ECDSA::PublicKey m_publicKey; +// CryptoPP::ByteQueue m_publicKeyQueue; + KeyType m_publicKeyType; }; } diff --git a/src/lcp-client-lib/RsaSha256SignatureAlgorithm.cpp b/src/lcp-client-lib/RsaSha256SignatureAlgorithm.cpp index b6a66cf..a9ec206 100644 --- a/src/lcp-client-lib/RsaSha256SignatureAlgorithm.cpp +++ b/src/lcp-client-lib/RsaSha256SignatureAlgorithm.cpp @@ -33,11 +33,7 @@ namespace lcp { RsaSha256SignatureAlgorithm::RsaSha256SignatureAlgorithm(const KeyType & publicKey) { - ByteQueue publicKeyQueue; - KeyType rawPublicKey = publicKey; - publicKeyQueue.Put(&rawPublicKey.at(0), rawPublicKey.size()); - publicKeyQueue.MessageEnd(); - m_publicKey.BERDecode(publicKeyQueue); + m_publicKeyType = publicKey; } std::string RsaSha256SignatureAlgorithm::Name() const @@ -68,7 +64,13 @@ namespace lcp size_t signatureLength ) { - ThisVerifier verifier(m_publicKey); + ByteQueue publicKeyQueue; + publicKeyQueue.Put(&m_publicKeyType.at(0), m_publicKeyType.size()); + publicKeyQueue.MessageEnd(); +// m_publicKey.BERDecode(publicKeyQueue); +// m_publicKeyQueue = publicKeyQueue; + + ThisVerifier verifier(publicKeyQueue); return verifier.VerifyMessage( message, messageLength, diff --git a/src/lcp-client-lib/RsaSha256SignatureAlgorithm.h b/src/lcp-client-lib/RsaSha256SignatureAlgorithm.h index 1ae3dd2..f154913 100644 --- a/src/lcp-client-lib/RsaSha256SignatureAlgorithm.h +++ b/src/lcp-client-lib/RsaSha256SignatureAlgorithm.h @@ -59,7 +59,10 @@ namespace lcp private: typedef CryptoPP::RSASS::Verifier ThisVerifier; - CryptoPP::RSA::PublicKey m_publicKey; + +// CryptoPP::RSA::PublicKey m_publicKey; +// CryptoPP::ByteQueue m_publicKeyQueue; + KeyType m_publicKeyType; }; } From 6a432ec0176022fccd91abda1fc6ce093845b2eb Mon Sep 17 00:00:00 2001 From: danielweck Date: Tue, 9 May 2017 17:58:19 +0100 Subject: [PATCH 10/42] removed unnecessary / unused functions (also prone to confusion, as message / signature verification rely on CryptoPP verify message...) --- src/lcp-client-lib/Certificate.cpp | 38 +++++++++++++++--------------- src/lcp-client-lib/Certificate.h | 14 +++++------ src/lcp-client-lib/ICertificate.h | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/lcp-client-lib/Certificate.cpp b/src/lcp-client-lib/Certificate.cpp index 5a75c61..f9b2a07 100644 --- a/src/lcp-client-lib/Certificate.cpp +++ b/src/lcp-client-lib/Certificate.cpp @@ -206,25 +206,25 @@ namespace lcp // return outKey; } - bool Certificate::VerifyMessage(const std::string & message, const std::string & hashBase64) - { - return m_signatureAlgorithm->VerifySignature(message, hashBase64); - } - - bool Certificate::VerifyMessage( - const unsigned char * message, - size_t messageLength, - const unsigned char * signature, - size_t signatureLength - ) - { - return m_signatureAlgorithm->VerifySignature( - message, - messageLength, - signature, - signatureLength - ); - } +// bool Certificate::VerifyMessage(const std::string & message, const std::string & hashBase64) +// { +// return m_signatureAlgorithm->VerifySignature(message, hashBase64); +// } +// +// bool Certificate::VerifyMessage( +// const unsigned char * message, +// size_t messageLength, +// const unsigned char * signature, +// size_t signatureLength +// ) +// { +// return m_signatureAlgorithm->VerifySignature( +// message, +// messageLength, +// signature, +// signatureLength +// ); +// } bool Certificate::VerifyCertificate(ICertificate * rootCertificate) { diff --git a/src/lcp-client-lib/Certificate.h b/src/lcp-client-lib/Certificate.h index b90e43e..f656edc 100644 --- a/src/lcp-client-lib/Certificate.h +++ b/src/lcp-client-lib/Certificate.h @@ -63,13 +63,13 @@ namespace lcp KeyType PublicKey() const; bool VerifyCertificate(ICertificate * rootCertificate); - bool VerifyMessage(const std::string & message, const std::string & hashBase64); - bool VerifyMessage( - const unsigned char * message, - size_t messageLength, - const unsigned char * signature, - size_t signatureLength - ); +// bool VerifyMessage(const std::string & message, const std::string & hashBase64); +// bool VerifyMessage( +// const unsigned char * message, +// size_t messageLength, +// const unsigned char * signature, +// size_t signatureLength +// ); ICrlDistributionPoints * DistributionPoints() const; diff --git a/src/lcp-client-lib/ICertificate.h b/src/lcp-client-lib/ICertificate.h index 33ca53b..0658aa8 100644 --- a/src/lcp-client-lib/ICertificate.h +++ b/src/lcp-client-lib/ICertificate.h @@ -48,7 +48,7 @@ namespace lcp virtual std::string NotAfterDate() const = 0; virtual KeyType PublicKey() const = 0; virtual bool VerifyCertificate(ICertificate * rootCertificate) = 0; - virtual bool VerifyMessage(const std::string & message, const std::string & hashBase64) = 0; +// virtual bool VerifyMessage(const std::string & message, const std::string & hashBase64) = 0; virtual ICrlDistributionPoints * DistributionPoints() const = 0; virtual ~ICertificate() {} }; From c94634fc3a619fa7849d658d6089804cb1a7e925 Mon Sep 17 00:00:00 2001 From: Cyrille Lebeaupin Date: Wed, 10 May 2017 14:44:32 +0200 Subject: [PATCH 11/42] Add new ignored patterns --- .gitignore | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 560b024..f02a3d6 100644 --- a/.gitignore +++ b/.gitignore @@ -42,7 +42,10 @@ bld/ [Oo]bj/ ipch/ .vs/ - +dist/ +.externalNativeBuild/ +.gradle/ +.classpath # Windows Thumbs.db @@ -68,5 +71,7 @@ storage.json result.epub *.iml - -platform/android/lcp/libs/ \ No newline at end of file +.settings/ +.project +local.properties +platform/android/lcp/libs/ From bf084dc5c58b481a73a3cb09a2c5cb52d598dcc6 Mon Sep 17 00:00:00 2001 From: Cyrille Lebeaupin Date: Wed, 10 May 2017 15:09:41 +0200 Subject: [PATCH 12/42] Build lib with cmake --- platform/android/README.md | 25 ++ platform/android/build.gradle | 34 ++- .../gradle/wrapper/gradle-wrapper.properties | 5 +- platform/android/lcp/Application.mk | 25 -- platform/android/lcp/Experimental.mk | 76 ------ platform/android/lcp/Stable.mk | 128 ---------- platform/android/lcp/build.gradle | 57 ----- .../android/lcp/build_experimental.gradle | 124 --------- .../static_library_dependency_build.gradle | 122 --------- platform/android/lib/CMakeLists.txt | 57 +++++ platform/android/lib/build.gradle | 236 +++++++++++++++--- platform/android/lib/clientlib.cmake | 34 +++ platform/android/lib/contentfilter.cmake | 5 + platform/android/lib/ndk-stl-config.cmake | 39 +++ .../src/clientlib/cpp}/Acquisition.cpp | 0 .../src/clientlib/cpp}/Acquisition.h | 0 .../clientlib/cpp}/AcquisitionCallback.cpp | 0 .../src/clientlib/cpp}/AcquisitionCallback.h | 0 .../jni => lib/src/clientlib/cpp}/License.cpp | 0 .../jni => lib/src/clientlib/cpp}/License.h | 0 .../src/clientlib/cpp}/NetProvider.cpp | 0 .../src/clientlib/cpp}/NetProvider.h | 0 .../jni => lib/src/clientlib/cpp}/Service.cpp | 9 +- .../jni => lib/src/clientlib/cpp}/Service.h | 0 .../src/clientlib/cpp}/StorageProvider.cpp | 0 .../src/clientlib/cpp}/StorageProvider.h | 0 .../jni => lib/src/clientlib/cpp}/Util.cpp | 0 .../main/jni => lib/src/clientlib/cpp}/Util.h | 0 .../java/org/readium/sdk/lcp/Acquisition.java | 0 .../org/readium/sdk/lcp/DoneCallback.java | 0 .../java/org/readium/sdk/lcp/Lcp.java | 0 .../java/org/readium/sdk/lcp/License.java | 0 .../java/org/readium/sdk/lcp/NetProvider.java | 0 .../readium/sdk/lcp/NetProviderCallback.java | 0 .../java/org/readium/sdk/lcp/Service.java | 0 .../sdk/lcp/StatusDocumentProcessing.java | 0 .../org/readium/sdk/lcp/StorageProvider.java | 0 .../contentfilter/cpp}/CredentialHandler.cpp | 0 .../contentfilter/cpp}/CredentialHandler.h | 0 .../src/contentfilter/cpp}/ServiceFactory.cpp | 2 +- .../src/contentfilter/cpp}/ServiceFactory.h | 0 .../cpp}/StatusDocumentHandler.cpp | 0 .../cpp}/StatusDocumentHandler.h | 0 .../readium/sdk/lcp/CredentialHandler.java | 0 .../org/readium/sdk/lcp/ServiceFactory.java | 0 .../sdk/lcp/StatusDocumentHandler.java | 0 platform/android/settings.gradle | 1 + 47 files changed, 402 insertions(+), 577 deletions(-) create mode 100644 platform/android/README.md delete mode 100644 platform/android/lcp/Application.mk delete mode 100644 platform/android/lcp/Experimental.mk delete mode 100644 platform/android/lcp/Stable.mk delete mode 100644 platform/android/lcp/build.gradle delete mode 100644 platform/android/lcp/build_experimental.gradle delete mode 100644 platform/android/lcp/static_library_dependency_build.gradle create mode 100644 platform/android/lib/CMakeLists.txt create mode 100644 platform/android/lib/clientlib.cmake create mode 100644 platform/android/lib/contentfilter.cmake create mode 100644 platform/android/lib/ndk-stl-config.cmake rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/Acquisition.cpp (100%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/Acquisition.h (100%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/AcquisitionCallback.cpp (100%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/AcquisitionCallback.h (100%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/License.cpp (100%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/License.h (100%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/NetProvider.cpp (100%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/NetProvider.h (100%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/Service.cpp (92%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/Service.h (100%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/StorageProvider.cpp (100%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/StorageProvider.h (100%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/Util.cpp (100%) rename platform/android/{lcp/src/main/jni => lib/src/clientlib/cpp}/Util.h (100%) rename platform/android/lib/src/{main => clientlib}/java/org/readium/sdk/lcp/Acquisition.java (100%) rename platform/android/lib/src/{main => clientlib}/java/org/readium/sdk/lcp/DoneCallback.java (100%) rename platform/android/lib/src/{main => clientlib}/java/org/readium/sdk/lcp/Lcp.java (100%) rename platform/android/lib/src/{main => clientlib}/java/org/readium/sdk/lcp/License.java (100%) rename platform/android/lib/src/{main => clientlib}/java/org/readium/sdk/lcp/NetProvider.java (100%) rename platform/android/lib/src/{main => clientlib}/java/org/readium/sdk/lcp/NetProviderCallback.java (100%) rename platform/android/lib/src/{main => clientlib}/java/org/readium/sdk/lcp/Service.java (100%) rename platform/android/lib/src/{main => clientlib}/java/org/readium/sdk/lcp/StatusDocumentProcessing.java (100%) rename platform/android/lib/src/{main => clientlib}/java/org/readium/sdk/lcp/StorageProvider.java (100%) rename platform/android/{lcp/src/main/jni => lib/src/contentfilter/cpp}/CredentialHandler.cpp (100%) rename platform/android/{lcp/src/main/jni => lib/src/contentfilter/cpp}/CredentialHandler.h (100%) rename platform/android/{lcp/src/main/jni => lib/src/contentfilter/cpp}/ServiceFactory.cpp (99%) rename platform/android/{lcp/src/main/jni => lib/src/contentfilter/cpp}/ServiceFactory.h (100%) rename platform/android/{lcp/src/main/jni => lib/src/contentfilter/cpp}/StatusDocumentHandler.cpp (100%) rename platform/android/{lcp/src/main/jni => lib/src/contentfilter/cpp}/StatusDocumentHandler.h (100%) rename platform/android/lib/src/{main => contentfilter}/java/org/readium/sdk/lcp/CredentialHandler.java (100%) rename platform/android/lib/src/{main => contentfilter}/java/org/readium/sdk/lcp/ServiceFactory.java (100%) rename platform/android/lib/src/{main => contentfilter}/java/org/readium/sdk/lcp/StatusDocumentHandler.java (100%) create mode 100644 platform/android/settings.gradle diff --git a/platform/android/README.md b/platform/android/README.md new file mode 100644 index 0000000..a9a16a5 --- /dev/null +++ b/platform/android/README.md @@ -0,0 +1,25 @@ +# Android + +## Properties + +You can define some properties in local.properties file: + +* ndk.dir: Path to the Ndk +* sdk.dir: Path to the Sdk +* readium.ndk_skipX86: If true, skip X86 compilation +* readium.ndk_skipARM: If true, skip ARM compilation +* readium.ndk_clang: If true, compile with clang +* readium.sdk_lib_dir: Path to readium sdk lib (*.so files) directory +* readium.sdk_include_dir: Path to readium include directory + +## Clean + +``` +./gradlew clean +``` + +## Build + +``` +./gradlew build +``` diff --git a/platform/android/build.gradle b/platform/android/build.gradle index 0685574..bc85075 100644 --- a/platform/android/build.gradle +++ b/platform/android/build.gradle @@ -1,10 +1,38 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { - jcenter() + jcenter() } dependencies { - classpath 'com.android.tools.build:gradle-experimental:0.6.0-alpha5' + Properties properties = new Properties() + properties.load(rootProject.file('local.properties').newDataInputStream()) + + def ndkClang = properties.getProperty('readium.ndk_clang', "false") + ndkClang = (ndkClang == "true") ? true : false; + rootProject.ext.set('readium_ndk_clang', ndkClang) + + def ndkSkipX86 = properties.getProperty('readium.ndk_skipX86', "false") + ndkSkipX86 = (ndkSkipX86 == "true") ? true : false; + rootProject.ext.set('readium_ndk_skipX86', ndkSkipX86) + + def ndkSkipARM = properties.getProperty('readium.ndk_skipARM', "false") + ndkSkipARM = (ndkSkipARM == "true") ? true : false; + rootProject.ext.set('readium_ndk_skipARM', ndkSkipARM) + + def readiumSdkLibDir = properties.getProperty('readium.sdk_lib_dir', null) + rootProject.ext.set('readium_sdk_lib_dir', readiumSdkLibDir) + + def readiumSdkIncludeDir = properties.getProperty('readium.sdk_include_dir', null) + rootProject.ext.set('readium_sdk_include_dir', readiumSdkIncludeDir) + + if (readiumSdkLibDir != null && readiumSdkIncludeDir != null) { + rootProject.ext.set('readium_lcp_build_content_filter', true) + } else { + rootProject.ext.set('readium_lcp_build_content_filter', false) + } + + //https://bintray.com/android/android-tools/com.android.tools.build.gradle/view + classpath "com.android.tools.build:gradle:2.3.1" } } @@ -12,4 +40,4 @@ allprojects { repositories { jcenter() } -} \ No newline at end of file +} diff --git a/platform/android/gradle/wrapper/gradle-wrapper.properties b/platform/android/gradle/wrapper/gradle-wrapper.properties index 60e4196..973db55 100644 --- a/platform/android/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,6 @@ -#Wed Aug 17 23:29:31 BST 2016 +#Wed Apr 12 13:19:28 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -#https://services.gradle.org/distributions -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip diff --git a/platform/android/lcp/Application.mk b/platform/android/lcp/Application.mk deleted file mode 100644 index 04fad3f..0000000 --- a/platform/android/lcp/Application.mk +++ /dev/null @@ -1,25 +0,0 @@ -APP_PLATFORM := android-25 - -ifneq ($(READIUM_SKIPARM),true) - -APP_ABI := armeabi-v7a - -ifneq ($(READIUM_SKIPX86),true) -APP_ABI += x86 -endif - -else - -APP_ABI := x86 - -endif - -ifeq ($(READIUM_CLANG),true) -#NDK_TOOLCHAIN := clang -NDK_TOOLCHAIN_VERSION := clang -APP_STL := c++_shared -else -#NDK_TOOLCHAIN := gcc -NDK_TOOLCHAIN_VERSION := 4.9 -APP_STL := gnustl_shared -endif \ No newline at end of file diff --git a/platform/android/lcp/Experimental.mk b/platform/android/lcp/Experimental.mk deleted file mode 100644 index 6595ff4..0000000 --- a/platform/android/lcp/Experimental.mk +++ /dev/null @@ -1,76 +0,0 @@ -# Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. -# -# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# -# Licensed under Gnu Affero General Public License Version 3 (provided, notwithstanding this -# notice, Readium Foundation reserves the right to license this material under a different -# separate license, and if you have done so, the terms of that separate license control and -# the following references to GPL do not apply). -# -# This program is free software: you can redistribute it and/or modify it under the terms -# of the GNU Affero General Public License as published by the Free Software Foundation, -# either version 3 of the License, or (at your option) any later version. You should have -# received a copy of the GNU Affero General Public License along with this program. If not, -# see . - -#LOCAL_PATH := $(call my-dir) -#THIRD_PARTY_PATH := $(LOCAL_PATH)/../../../src/third-parties -# -########################################################### -# cryptopp -#include $(CLEAR_VARS) -#LOCAL_MODULE := cryptopp -# -#ifeq ($(READIUM_CLANG),true) -#LOCAL_CPPFLAGS := -std=c++11 -fpermissive -#LOCAL_CXXFLAGS := -std=c++11 -fpermissive -#LOCAL_CFLAGS := -std=c11 -#else -#LOCAL_CPPFLAGS := -std=gnu++11 -fpermissive -#LOCAL_CXXFLAGS := -std=gnu++11 -fpermissive -#LOCAL_CFLAGS := -std=gnu11 -#endif -# -#LOCAL_CPP_FEATURES += exceptions rtti -# -#ifeq ($(TARGET_ARCH_ABI),x86) -# LOCAL_CFLAGS += -mtune=atom -mssse3 -mfpmath=sse -#endif -# -#LOCAL_C_INCLUDES := $(THIRD_PARTY_PATH)/cryptopp -#LOCAL_SRC_FILES := $(wildcard $(THIRD_PARTY_PATH)/cryptopp/*.cpp) -# -#include $(BUILD_STATIC_LIBRARY) -# -########################################################### -# ZipLib -#include $(CLEAR_VARS) -#LOCAL_MODULE := ziplib -# -#ifeq ($(READIUM_CLANG),true) -#LOCAL_CPPFLAGS := -std=c++11 -fpermissive -#LOCAL_CXXFLAGS := -std=c++11 -fpermissive -#LOCAL_CFLAGS := -std=c11 -#else -#LOCAL_CPPFLAGS := -std=gnu++11 -fpermissive -#LOCAL_CXXFLAGS := -std=gnu++11 -fpermissive -#LOCAL_CFLAGS := -std=gnu11 -#endif -# -#LOCAL_CPP_FEATURES += exceptions rtti -# -#ifeq ($(TARGET_ARCH_ABI),x86) -# LOCAL_CFLAGS += -mtune=atom -mssse3 -mfpmath=sse -#endif -# -#LOCAL_C_INCLUDES := $(THIRD_PARTY_PATH)/Source/ZipLib -#LOCAL_SRC_FILES := \ -# $(wildcard $(THIRD_PARTY_PATH)/ziplib/Source/ZipLib/extlibs/zlib/*.c) \ -# $(wildcard $(THIRD_PARTY_PATH)/ziplib/Source/ZipLib/extlibs/lzma/unix/*.c) \ -# $(wildcard $(THIRD_PARTY_PATH)/ziplib/Source/ZipLib/extlibs/bzip2/*.c) \ -# $(wildcard $(THIRD_PARTY_PATH)/ziplib/Source/ZipLib/detail/*.cpp) \ -# $(wildcard $(THIRD_PARTY_PATH)/ziplib/Source/ZipLib/*.cpp) -# -#include $(BUILD_STATIC_LIBRARY) -# \ No newline at end of file diff --git a/platform/android/lcp/Stable.mk b/platform/android/lcp/Stable.mk deleted file mode 100644 index 4a13f05..0000000 --- a/platform/android/lcp/Stable.mk +++ /dev/null @@ -1,128 +0,0 @@ -# Copyright (c) 2014 Readium Foundation and/or its licensees. All rights reserved. -# -# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# -# Licensed under Gnu Affero General Public License Version 3 (provided, notwithstanding this -# notice, Readium Foundation reserves the right to license this material under a different -# separate license, and if you have done so, the terms of that separate license control and -# the following references to GPL do not apply). -# -# This program is free software: you can redistribute it and/or modify it under the terms -# of the GNU Affero General Public License as published by the Free Software Foundation, -# either version 3 of the License, or (at your option) any later version. You should have -# received a copy of the GNU Affero General Public License along with this program. If not, -# see . - -LOCAL_PATH := $(call my-dir) -SRC_PATH := $(LOCAL_PATH)/../../../src -LCP_CLIENT_LIB_PATH := $(SRC_PATH)/lcp-client-lib -LCP_CONTENT_FILTER_PATH := $(SRC_PATH)/lcp-content-filter -THIRD_PARTY_PATH := $(SRC_PATH)/third-parties - -########################################################### -# cryptopp -include $(CLEAR_VARS) -LOCAL_MODULE := cryptopp - -ifeq ($(READIUM_CLANG),true) -LOCAL_CPPFLAGS := -std=c++11 -fpermissive -LOCAL_CXXFLAGS := -std=c++11 -fpermissive -LOCAL_CFLAGS := -std=c11 -else -LOCAL_CPPFLAGS := -std=gnu++11 -fpermissive -LOCAL_CXXFLAGS := -std=gnu++11 -fpermissive -LOCAL_CFLAGS := -std=gnu11 -endif - -LOCAL_CPP_FEATURES += exceptions rtti - -ifeq ($(TARGET_ARCH_ABI),x86) - LOCAL_CFLAGS += -mtune=atom -mssse3 -mfpmath=sse -endif - -LOCAL_C_INCLUDES := $(THIRD_PARTY_PATH)/cryptopp -LOCAL_SRC_FILES := $(wildcard $(THIRD_PARTY_PATH)/cryptopp/*.cpp) - -include $(BUILD_STATIC_LIBRARY) - -########################################################### -# ZipLib -include $(CLEAR_VARS) -LOCAL_MODULE := ziplib - -ifeq ($(READIUM_CLANG),true) -LOCAL_CPPFLAGS := -std=c++11 -fpermissive -DZLIB_ONLY -LOCAL_CXXFLAGS := -std=c++11 -fpermissive -DZLIB_ONLY -LOCAL_CFLAGS := -std=c11 -DZLIB_ONLY -else -LOCAL_CPPFLAGS := -std=gnu++11 -fpermissive -DZLIB_ONLY -LOCAL_CXXFLAGS := -std=gnu++11 -fpermissive -DZLIB_ONLY -LOCAL_CFLAGS := -std=gnu11 -DZLIB_ONLY -endif - -LOCAL_CPP_FEATURES += exceptions rtti - -ifeq ($(TARGET_ARCH_ABI),x86) - LOCAL_CFLAGS += -mtune=atom -mssse3 -mfpmath=sse -endif - -LOCAL_C_INCLUDES := $(THIRD_PARTY_PATH)/Source/ZipLib -LOCAL_SRC_FILES := \ - $(wildcard $(THIRD_PARTY_PATH)/ziplib/Source/ZipLib/extlibs/zlib/*.c) \ - $(wildcard $(THIRD_PARTY_PATH)/ziplib/Source/ZipLib/extlibs/lzma/unix/*.c) \ - $(wildcard $(THIRD_PARTY_PATH)/ziplib/Source/ZipLib/extlibs/bzip2/*.c) \ - $(wildcard $(THIRD_PARTY_PATH)/ziplib/Source/ZipLib/detail/*.cpp) \ - $(wildcard $(THIRD_PARTY_PATH)/ziplib/Source/ZipLib/*.cpp) - -include $(BUILD_STATIC_LIBRARY) - -########################################################### -# Epub3 -include $(CLEAR_VARS) -LOCAL_MODULE := epub3 - -LOCAL_SRC_FILES := $(EPUB3_PATH)/libs/$(TARGET_ARCH_ABI)/libepub3.so - -include $(PREBUILT_SHARED_LIBRARY) - -########################################################### -# Lcp -include $(CLEAR_VARS) -LOCAL_MODULE := lcp - -ifeq ($(READIUM_CLANG),true) -LOCAL_CPPFLAGS := -std=c++11 -fpermissive -LOCAL_CXXFLAGS := -std=c++11 -fpermissive -DFEATURES_READIUM -LOCAL_CFLAGS := -std=c11 -else -LOCAL_CPPFLAGS := -std=gnu++11 -fpermissive -LOCAL_CXXFLAGS := -std=gnu++11 -fpermissive -DFEATURES_READIUM -LOCAL_CFLAGS := -std=gnu11 -endif - -LOCAL_CPP_FEATURES += exceptions rtti - -ifeq ($(TARGET_ARCH_ABI),x86) - LOCAL_CFLAGS += -mtune=atom -mssse3 -mfpmath=sse -endif - -LOCAL_STATIC_LIBRARIES := cryptopp ziplib -LOCAL_SHARED_LIBRARIES := epub3 -LOCAL_LDLIBS := -lz -landroid -llog - -LOCAL_C_INCLUDES += \ - $(EPUB3_PATH)/include \ - $(LCP_CLIENT_LIB_PATH) \ - $(LCP_CLIENT_LIB_PATH)/public \ - $(LCP_CONTENT_FILTER_PATH) \ - $(LCP_CONTENT_FILTER_PATH)/public \ - $(THIRD_PARTY_PATH) - -LOCAL_SRC_FILES := \ - $(wildcard $(THIRD_PARTY_PATH)/time64/*.c) \ - $(wildcard $(LCP_CLIENT_LIB_PATH)/*.cpp) \ - $(wildcard $(LCP_CONTENT_FILTER_PATH)/*.cpp) \ - $(wildcard $(LOCAL_PATH)/src/main/jni/*.cpp) - -include $(BUILD_SHARED_LIBRARY) diff --git a/platform/android/lcp/build.gradle b/platform/android/lcp/build.gradle deleted file mode 100644 index dd6ecb5..0000000 --- a/platform/android/lcp/build.gradle +++ /dev/null @@ -1,57 +0,0 @@ -import org.apache.tools.ant.taskdefs.condition.Os - -def ndk_skipX86 = (rootProject.hasProperty("readium_ndk_skipX86") && rootProject.readium_ndk_skipX86) -def ndk_skipARM = (rootProject.hasProperty("readium_ndk_skipARM") && rootProject.readium_ndk_skipARM) -def ndk_clang = (rootProject.hasProperty("readium_ndk_clang") && rootProject.readium_ndk_clang) -def ndk_experimental = (rootProject.hasProperty("readium_ndk_experimental") && rootProject.readium_ndk_experimental) -def lcp_client_distribution_dir = rootProject.readium_lcp_client_distribution_dir - -if (lcp_client_distribution_dir) { - println "${project.name}: Using Gradle STATIC LIBRARY DEPENDENCY to build LCP lib" - apply from: 'static_library_dependency_build.gradle' -} else if (ndk_experimental) { - println "${project.name}: Using Gradle EXPERIMENTAL to build LCP lib" - apply from: 'build_experimental.gradle' -} else { - println "${project.name}: Using Gradle STABLE to build LCP lib" -} - -task buildMk(type: Exec) { - // Retrieve ndk dir - Properties properties = new Properties() - properties.load(project.rootProject.file('local.properties').newDataInputStream()) - def ndkDir = properties.getProperty('ndk.dir', null) - - // Call ndk build - def ndkBuildExt = Os.isFamily(Os.FAMILY_WINDOWS) ? ".cmd" : "" - def projectPath = file('.').absolutePath - def buildScript = (ndk_experimental) ? "Experimental.mk" : "Stable.mk" - - environment 'EPUB3_PATH', project(':epub3').projectDir - - if (ndk_skipX86) environment 'READIUM_SKIPX86', 'true' - if (ndk_skipARM) environment 'READIUM_SKIPARM', 'true' - if (ndk_clang) environment 'READIUM_CLANG', 'true' - if (ndk_experimental) environment 'READIUM_DEBUG', 'true' - - commandLine "$ndkDir/ndk-build${ndkBuildExt}", - "-j", "4", //Runtime.runtime.availableProcessors() - '-C', projectPath, - 'NDK_APPLICATION_MK=Application.mk', - "APP_BUILD_SCRIPT=${buildScript}", - "NDK_PROJECT_PATH=${projectPath}", - "NDK_DEBUG=1" -} - -tasks.whenTaskAdded { task -> - def taskName = task.name - - if (taskName.startsWith("compile")) { - - if (ndk_experimental) { - println "${project.name} - ${taskName}: Using Gradle EXPERIMENTAL, no need to invoke external NDK / Makefile to build LCP lib" - } else { - task.dependsOn "buildMk" - } - } -} diff --git a/platform/android/lcp/build_experimental.gradle b/platform/android/lcp/build_experimental.gradle deleted file mode 100644 index a726d27..0000000 --- a/platform/android/lcp/build_experimental.gradle +++ /dev/null @@ -1,124 +0,0 @@ -apply plugin: 'com.android.model.native' - -def ndk_skipX86 = (rootProject.hasProperty("readium_ndk_skipX86") && rootProject.readium_ndk_skipX86) -def ndk_skipARM = (rootProject.hasProperty("readium_ndk_skipARM") && rootProject.readium_ndk_skipARM) -def ndk_clang = (rootProject.hasProperty("readium_ndk_clang") && rootProject.readium_ndk_clang) -def ndk_experimental = (rootProject.hasProperty("readium_ndk_experimental") && rootProject.readium_ndk_experimental) - -model { - android { - compileSdkVersion = 25 - sources { - main { - jni { - source { - srcDirs = [ - './src/main/jni', - '../../../src/lcp-client-lib', - '../../../src/lcp-content-filter', - '../../../src/third-parties' - ] - - excludes.add('curl/**/*.*') - excludes.add('gtest/**/*.*') - excludes.add('rapidjson/**/*.*') - excludes.add('utf8-cpp/**/*.*') - excludes.add('cryptopp/*test.cpp') - excludes.add('cryptopp/TestScripts/*.*') - excludes.add('cryptopp/bench*.cpp') - excludes.add('cryptopp/validat*.cpp') - excludes.add('cryptopp/adhoc.cpp') - excludes.add('ziplib/Source/Sample/*.*') - excludes.add('ziplib/Source/ZipLib/extlibs/lzma/*.c') - excludes.add('ziplib/Source/ZipLib/extlibs/lzma/**/*.c') - } //source - - exportedHeaders { - srcDir "./src/main/jni" - } - - dependencies { - project ":epub3" linkage "shared" - } - } - } - } //sources - - ndk { - moduleName = "lcp" - - //arguments "-j 4" //Runtime.runtime.availableProcessors() - - toolchain = ndk_clang ? "clang" : "gcc" - toolchainVersion = ndk_clang ? "" : "4.9" //https://github.com/android-ndk/ndk/issues/229 - - def clangWithGnuStl = false - - if (!ndk_clang || clangWithGnuStl) - stl = "gnustl_shared" - else - stl = "c++_shared" - - def arrayFlags = [ - "-fexceptions", - "-fpic", - "-DFEATURES_READIUM", - "-DZLIB_ONLY", - ndk_clang ? "-D_LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49=_LIBCPP_INLINE_VISIBILITY" : "-DREADIUM_GCC", - "-I" + project(':epub3').projectDir + "/include", - "-I${file("../../../src/lcp-client-lib")}".toString(), - "-I${file("../../../src/lcp-client-lib/public")}".toString(), - "-I${file("../../../src/lcp-content-filter")}".toString(), - "-I${file("../../../src/lcp-content-filter/public")}".toString(), - "-I${file("../../../src/third-parties")}".toString() - ] - - def arrayFlagsCPP = [ - "-fpermissive", - "-frtti" - ] - - cppFlags.addAll(arrayFlags) - cppFlags.addAll(arrayFlagsCPP) - cppFlags.add((!ndk_clang || clangWithGnuStl) ? "-std=gnu++11" : "-std=c++11") - - CFlags.addAll(arrayFlags) - CFlags.add((!ndk_clang || clangWithGnuStl) ? "-std=gnu11" : "-std=c11") - - ldLibs.addAll(['z', 'android', 'log']) - if (ndk_clang) ldLibs.addAll(['atomic']) - } //ndk - - buildTypes { - release { - - } - debug { - ndk.with { - debuggable = true //"NDK_DEBUG=1" - } - } - } //buildTypes - - productFlavors { - if (!ndk_skipARM) - create("arm") { - ndk.with { - abiFilters.add("armeabi-v7a") - ldFlags.addAll([ - "-L${file("./obj/local/armeabi-v7a")}".toString() - ]) - } - } - if (!ndk_skipX86) - create("x86") { - ndk.with { - abiFilters.add("x86") - ldFlags.addAll([ - "-L${file("./obj/local/x86")}".toString() - ]) - } - } - } //productFlavors - } //android -} //model \ No newline at end of file diff --git a/platform/android/lcp/static_library_dependency_build.gradle b/platform/android/lcp/static_library_dependency_build.gradle deleted file mode 100644 index 51b6451..0000000 --- a/platform/android/lcp/static_library_dependency_build.gradle +++ /dev/null @@ -1,122 +0,0 @@ -apply plugin: 'com.android.model.native' - -def ndk_skipX86 = (rootProject.hasProperty("readium_ndk_skipX86") && rootProject.readium_ndk_skipX86) -def ndk_skipARM = (rootProject.hasProperty("readium_ndk_skipARM") && rootProject.readium_ndk_skipARM) -def ndk_clang = (rootProject.hasProperty("readium_ndk_clang") && rootProject.readium_ndk_clang) -def ndk_experimental = (rootProject.hasProperty("readium_ndk_experimental") && rootProject.readium_ndk_experimental) -q - -model { - repositories { - libs(PrebuiltLibraries) { - lcp_client { - headers.srcDir "${lcp_client_distribution_dir}/include" - binaries.withType(StaticLibraryBinary) { - staticLibraryFile = file("${lcp_client_distribution_dir}/${targetPlatform.getName()}/lib/libedrlab-lcp-client.a") - } - } - } - } - - android { - compileSdkVersion = 25 - sources { - main { - jni { - source { - srcDirs = [ - './src/main/jni', - '../../../src/lcp-content-filter' - ] - } //source - - exportedHeaders { - srcDir "./src/main/jni" - } - - dependencies { - library "lcp_client" linkage "static" - project ":epub3" linkage "shared" - } - } - } - } //sources - - ndk { - moduleName = "lcp" - - //arguments "-j 4" //Runtime.runtime.availableProcessors() - - toolchain = ndk_clang ? "clang" : "gcc" - toolchainVersion = ndk_clang ? "" : "4.9" //https://github.com/android-ndk/ndk/issues/229 - - def clangWithGnuStl = false - - if (!ndk_clang || clangWithGnuStl) - stl = "gnustl_shared" - else - stl = "c++_shared" - - def arrayFlags = [ - "-fexceptions", - "-fpic", - "-DFEATURES_READIUM", - "-DDISABLE_LSD_", - "-DZLIB_ONLY", - ndk_clang ? "-D_LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49=_LIBCPP_INLINE_VISIBILITY" : "-DREADIUM_GCC", - "-I" + project(':epub3').projectDir + "/include", - "-I${file("../../../src/lcp-client-lib")}".toString(), - "-I${file("../../../src/lcp-client-lib/public")}".toString(), - "-I${file("../../../src/lcp-content-filter")}".toString(), - "-I${file("../../../src/lcp-content-filter/public")}".toString(), - ] - - def arrayFlagsCPP = [ - "-fpermissive", - "-frtti" - ] - - cppFlags.addAll(arrayFlags) - cppFlags.addAll(arrayFlagsCPP) - cppFlags.add((!ndk_clang || clangWithGnuStl) ? "-std=gnu++11" : "-std=c++11") - - CFlags.addAll(arrayFlags) - CFlags.add((!ndk_clang || clangWithGnuStl) ? "-std=gnu11" : "-std=c11") - - ldLibs.addAll(['z', 'android', 'log']) - if (ndk_clang) ldLibs.addAll(['atomic']) - } //ndk - - buildTypes { - release { - - } - debug { - ndk.with { - debuggable = true //"NDK_DEBUG=1" - } - } - } //buildTypes - - productFlavors { - if (!ndk_skipARM) - create("arm") { - ndk.with { - abiFilters.add("armeabi-v7a") - ldFlags.addAll([ - "-L${file("./obj/local/armeabi-v7a")}".toString() - ]) - } - } - if (!ndk_skipX86) - create("x86") { - ndk.with { - abiFilters.add("x86") - ldFlags.addAll([ - "-L${file("./obj/local/x86")}".toString() - ]) - } - } - } //productFlavors - } //android -} //model \ No newline at end of file diff --git a/platform/android/lib/CMakeLists.txt b/platform/android/lib/CMakeLists.txt new file mode 100644 index 0000000..163ac2a --- /dev/null +++ b/platform/android/lib/CMakeLists.txt @@ -0,0 +1,57 @@ +# Global options +cmake_minimum_required(VERSION 3.6.0) +set(CMAKE_VERBOSE_MAKEFILE od) + +set(MODULE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(PROJECT_DIR ${MODULE_DIR}/..) +set(ROOT_DIR ${PROJECT_DIR}/../..) +set(DISTRIBUTION_DIR ${PROJECT_DIR}/dist/${CMAKE_BUILD_TYPE}/${ANDROID_ABI}) +set("ndk-stl_DIR" "${CMAKE_CURRENT_SOURCE_DIR}") + +include(${PROJECT_DIR}/lib/clientlib.cmake) +# Android Studio 2.x with CMake support does not pack stl shared libraries, +# so app needs to pack the right shared lib into APK. This sample uses solution +# from https://github.com/jomof/ndk-stl to find the right stl shared lib to use +# and copy it to the right place for Android Studio to pack +# Usage: download ndk-stl-config.cmake into app's directory hosting CMakeLists.txt +# and just use it with the following line +include(${PROJECT_DIR}/lib/ndk-stl-config.cmake) + +# Compiler options +add_definitions("-DZLIB_ONLY") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -fpic -frtti -fexceptions -fpermissive -Wall") + +include_directories( + ${CLIENTLIB_DIR} + ${CLIENTLIB_DIR}/public + ${THIRDPARTY_DIR} + ${MODULE_DIR}/src/clientlib/cpp/) + +# Build clientlib without JNI +add_library("clientlib" STATIC ${CLIENTLIB_ALL_SOURCES}) + +# Build shared library with JNI +file(GLOB CLIENTLIB_JNI_SOURCES ${MODULE_DIR}/src/clientlib/cpp/*.cpp) + +add_library("lcp-min" SHARED ${CLIENTLIB_JNI_SOURCES}) +target_link_libraries("lcp-min" "clientlib") + +# LCP with content filter +add_definitions("-DFEATURES_READIUM -DREADIUM_GCC") +include(${PROJECT_DIR}/lib/contentfilter.cmake) +file(GLOB CONTENTFILTER_JNI_SOURCES ${MODULE_DIR}/src/contentfilter/cpp/*.cpp) +include_directories( + ${CONTENTFILTER_DIR} + ${CONTENTFILTER_DIR}/public + ${RSDK_INCLUDE_DIR} + ${MODULE_DIR}/src/contentfilter/cpp/) + +# Build contentfilter without JNI +add_library("contentfilter" STATIC ${CONTENTFILTER_SOURCES}) + +add_library("lcp" SHARED + ${CLIENTLIB_JNI_SOURCES} + ${CONTENTFILTER_JNI_SOURCES}) + +# Link to lcp-client-lib, lcp-content-filter and rsdk +target_link_libraries("lcp" "clientlib" "contentfilter" ${RSDK_LIB_DIR}/${ANDROID_ABI}/libepub3.so) diff --git a/platform/android/lib/build.gradle b/platform/android/lib/build.gradle index b8d0fa9..d0f60b8 100644 --- a/platform/android/lib/build.gradle +++ b/platform/android/lib/build.gradle @@ -1,55 +1,227 @@ -apply plugin: 'com.android.model.library' +apply plugin: 'com.android.library' -model { - android { - compileSdkVersion = 23 - buildToolsVersion = "23.0.2" +repositories { + mavenCentral() + jcenter() +} - defaultConfig.with { - minSdkVersion.apiLevel = 19 - targetSdkVersion.apiLevel = 23 +dependencies { + compile 'com.android.support:support-v4:25.+' + compile 'commons-io:commons-io:2.4' + compile 'com.koushikdutta.ion:ion:2.+' +} + +def ndk_skipX86 = (rootProject.hasProperty("readium_ndk_skipX86") && rootProject.readium_ndk_skipX86) +def ndk_skipARM = (rootProject.hasProperty("readium_ndk_skipARM") && rootProject.readium_ndk_skipARM) +def ndk_clang = (rootProject.hasProperty("readium_ndk_clang") && rootProject.readium_ndk_clang) +def readiumSdkLibDir = null +def readiumSdkIncludeDir = null +def readiumLcpBuildContentFilter = false + +if (rootProject.hasProperty("readium_sdk_lib_dir")) { + readiumSdkLibDir = rootProject.readium_sdk_lib_dir +} + +if (rootProject.hasProperty("readium_sdk_include_dir")) { + readiumSdkIncludeDir = rootProject.readium_sdk_include_dir +} + +if (rootProject.hasProperty("readium_lcp_build_content_filter")) { + readiumLcpBuildContentFilter = rootProject.readium_lcp_build_content_filter +} + +def toolchain = ndk_clang ? "clang" : "gcc" +def stl = ndk_clang ? "c++_shared" : "gnustl_shared" + +if (!readiumLcpBuildContentFilter) { + try { + def epub3Dir = project(':epub3').projectDir + readiumSdkLibDir = "${epub3Dir}/libs" + readiumSdkIncludeDir = "${epub3Dir}/include" + readiumLcpBuildContentFilter = true + } catch (UnknownProjectException e) { + // No epub3 project is defined + println("Build without rsdk") + } +} else { + println("Build with rsdk") +} + +android { + compileSdkVersion 25 + buildToolsVersion '25.0.2' + + defaultConfig { + minSdkVersion 19 + targetSdkVersion 25 + versionCode 1 + versionName "1.0" + + externalNativeBuild { + cmake { + if (readiumLcpBuildContentFilter) { + targets "clientlib", "contentfilter", "lcp" + } else { + targets "clientlib", "lcp-min" + } + + arguments "-DANDROID_PLATFORM=android-19", + "-DANDROID_TOOLCHAIN=${toolchain}", + "-DANDROID_STL=${stl}", + "-DRSDK_INCLUDE_DIR=${readiumSdkIncludeDir}", + "-DRSDK_LIB_DIR=${readiumSdkLibDir}" + } } + } - sources { + sourceSets { + if (readiumLcpBuildContentFilter) { main { - jniLibs { - dependencies { - project ":lcp" - } + java { + srcDirs = [ + './src/clientlib/java', + './src/contentfilter/java' + ] } } + } else { main { java { - source { - srcDirs = [ - './src/main/java' - ] - } + srcDirs = [ + './src/clientlib/java' + ] } } } + } - buildTypes { - debug { - minifyEnabled = false + buildTypes { + release { + externalNativeBuild { + cmake { + arguments '-DCMAKE_BUILD_TYPE=RELEASE' + } } - release { - minifyEnabled = false - proguardFiles.add(file('proguard-rules.txt')) + } + + debug { + externalNativeBuild { + cmake { + arguments '-DCMAKE_BUILD_TYPE=DEBUG' + } } } + } + + externalNativeBuild { + cmake { + path "CMakeLists.txt" + } + } - productFlavors { - create ("arm") { - ndk.with { - abiFilters.add("armeabi-v7a") + productFlavors { + if (!ndk_skipARM) { + arm7 { + ndk { + abiFilter 'armeabi-v7a' } } - create ("x86") { - ndk.with { - abiFilters.add("x86") + } + if (!ndk_skipX86) { + x86 { + ndk { + abiFilter 'x86' } } } + /*arm8 { + ndk { + abiFilters 'arm64-v8a' + } + } + arm { + ndk { + abiFilter 'armeabi' + } + } + x86_64 { + ndk { + abiFilter 'x86_64' + } + }*/ + } +} + +build.doLast { + println("Copy libs to dist directory") + android.productFlavors.all { flavor -> + android.buildTypes.all { buildType -> + def abiFilter = flavor.ndk.abiFilters.first() + def dstDirPath = "${project.projectDir}/../dist/${buildType.name.toLowerCase()}/${abiFilter}" + + // Copy static libs + def srcDirPath = "${project.projectDir}/.externalNativeBuild/cmake/${flavor.name}${buildType.name.capitalize()}/${abiFilter}" + + copy { + from("${srcDirPath}") { + include("*.a") + } + into("${dstDirPath}") + } + + // Copy shared libs + srcDirPath = "${project.projectDir}/build/intermediates/cmake/${flavor.name}/${buildType.name}/obj/${abiFilter}" + + copy { + from("${srcDirPath}") { + include("*.so") + } + into("${dstDirPath}") + } + + // Copy aar + srcDirPath = "${project.projectDir}/build/outputs/aar" + def srcFilename = "lib-${flavor.name}-${buildType.name}.aar" + + copy { + from("${srcDirPath}") { + include(srcFilename) + } + into("${dstDirPath}") + rename(srcFilename, "liblcp.aar") + } + } + } +} + +clean.doFirst { + println("Clean dist directory") + def dstDirPath = "${project.projectDir}/../dist/" + delete dstDirPath +} + +task copyLibs { + doLast { + println ("Copy shared library to libs") + android.productFlavors.all { flavor -> + android.buildTypes.all { buildType -> + def abiFilter = flavor.ndk.abiFilters.first() + def srcDirPath = "${project.projectDir}/build/intermediates/cmake/${flavor.name}/${buildType.name}/obj/${abiFilter}" + def dstDirPath = "${project.projectDir}/libs/${abiFilter}" + + copy { + from("${srcDirPath}") { + include("liblcp.so") + } + into("${dstDirPath}") + } + } + } + } +} + +tasks.whenTaskAdded { task -> + if (task.name.startsWith('assemble')) { + task.dependsOn copyLibs } -} \ No newline at end of file +} diff --git a/platform/android/lib/clientlib.cmake b/platform/android/lib/clientlib.cmake new file mode 100644 index 0000000..8f0cf0d --- /dev/null +++ b/platform/android/lib/clientlib.cmake @@ -0,0 +1,34 @@ +# Path definitions +set(CLIENTLIB_DIR ${ROOT_DIR}/src/lcp-client-lib) +set(THIRDPARTY_DIR ${ROOT_DIR}/src/third-parties) + +# CryptoPP +file(GLOB_RECURSE CRYPTOPP_SOURCES ${THIRDPARTY_DIR}/cryptopp/*.cpp) +list(FILTER CRYPTOPP_SOURCES EXCLUDE REGEX "TestScripts/.*\.cpp") +list(FILTER CRYPTOPP_SOURCES EXCLUDE REGEX "bench.*\.cpp") +list(FILTER CRYPTOPP_SOURCES EXCLUDE REGEX ".*test\.cpp") +list(FILTER CRYPTOPP_SOURCES EXCLUDE REGEX "validat.*\.cpp") +list(FILTER CRYPTOPP_SOURCES EXCLUDE REGEX "adhoc\.cpp") + +# ZipLib +file(GLOB ZIPLIB_SOURCES + ${THIRDPARTY_DIR}/ziplib/Source/ZipLib/extlibs/zlib/*\.c + ${THIRDPARTY_DIR}/ziplib/Source/ZipLib/extlibs/lzma/unix/*\.c + ${THIRDPARTY_DIR}/ziplib/Source/ZipLib/extlibs/bzip2/*\.c + ${THIRDPARTY_DIR}/ziplib/Source/ZipLib/detail/*\.cpp + ${THIRDPARTY_DIR}/ziplib/Source/ZipLib//*\.cpp + ) + +# Time64 +file(GLOB_RECURSE TIME64_SOURCES ${THIRDPARTY_DIR}/time64/*.c) + + +# Client lib +file(GLOB CLIENTLIB_SOURCES ${CLIENTLIB_DIR}/*.cpp) + +set(CLIENTLIB_ALL_SOURCES + ${CRYPTOPP_SOURCES} + ${ZIPLIB_SOURCES} + ${TIME64_SOURCES} + ${CLIENTLIB_SOURCES} +) diff --git a/platform/android/lib/contentfilter.cmake b/platform/android/lib/contentfilter.cmake new file mode 100644 index 0000000..72c53cc --- /dev/null +++ b/platform/android/lib/contentfilter.cmake @@ -0,0 +1,5 @@ +# Path definitions +set(CONTENTFILTER_DIR ${ROOT_DIR}/src/lcp-content-filter) + +# Content filter +file(GLOB CONTENTFILTER_SOURCES ${CONTENTFILTER_DIR}/*.cpp) \ No newline at end of file diff --git a/platform/android/lib/ndk-stl-config.cmake b/platform/android/lib/ndk-stl-config.cmake new file mode 100644 index 0000000..3133faf --- /dev/null +++ b/platform/android/lib/ndk-stl-config.cmake @@ -0,0 +1,39 @@ +# Copy shared STL files to Android Studio output directory so they can be +# packaged in the APK. +# Usage: +# +# find_package(ndk-stl REQUIRED) +# +# or +# +# find_package(ndk-stl REQUIRED PATHS ".") + +if(NOT ${ANDROID_STL} MATCHES "_shared") + return() +endif() + +function(configure_shared_stl lib_path so_base) + message("Configuring STL ${so_base} for ${ANDROID_ABI}") + configure_file( + "${ANDROID_NDK}/sources/cxx-stl/${lib_path}/libs/${ANDROID_ABI}/lib${so_base}.so" + "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${so_base}.so" + COPYONLY) +endfunction() + +if("${ANDROID_STL}" STREQUAL "libstdc++") + # The default minimal system C++ runtime library. +elseif("${ANDROID_STL}" STREQUAL "gabi++_shared") + # The GAbi++ runtime (shared). + message(FATAL_ERROR "gabi++_shared was not configured by ndk-stl package") +elseif("${ANDROID_STL}" STREQUAL "stlport_shared") + # The STLport runtime (shared). + configure_shared_stl("stlport" "stlport_shared") +elseif("${ANDROID_STL}" STREQUAL "gnustl_shared") + # The GNU STL (shared). + configure_shared_stl("gnu-libstdc++/4.9" "gnustl_shared") +elseif("${ANDROID_STL}" STREQUAL "c++_shared") + # The LLVM libc++ runtime (shared). + configure_shared_stl("llvm-libc++" "c++_shared") +else() + message(FATAL_ERROR "STL configuration ANDROID_STL=${ANDROID_STL} is not supported") +endif() diff --git a/platform/android/lcp/src/main/jni/Acquisition.cpp b/platform/android/lib/src/clientlib/cpp/Acquisition.cpp similarity index 100% rename from platform/android/lcp/src/main/jni/Acquisition.cpp rename to platform/android/lib/src/clientlib/cpp/Acquisition.cpp diff --git a/platform/android/lcp/src/main/jni/Acquisition.h b/platform/android/lib/src/clientlib/cpp/Acquisition.h similarity index 100% rename from platform/android/lcp/src/main/jni/Acquisition.h rename to platform/android/lib/src/clientlib/cpp/Acquisition.h diff --git a/platform/android/lcp/src/main/jni/AcquisitionCallback.cpp b/platform/android/lib/src/clientlib/cpp/AcquisitionCallback.cpp similarity index 100% rename from platform/android/lcp/src/main/jni/AcquisitionCallback.cpp rename to platform/android/lib/src/clientlib/cpp/AcquisitionCallback.cpp diff --git a/platform/android/lcp/src/main/jni/AcquisitionCallback.h b/platform/android/lib/src/clientlib/cpp/AcquisitionCallback.h similarity index 100% rename from platform/android/lcp/src/main/jni/AcquisitionCallback.h rename to platform/android/lib/src/clientlib/cpp/AcquisitionCallback.h diff --git a/platform/android/lcp/src/main/jni/License.cpp b/platform/android/lib/src/clientlib/cpp/License.cpp similarity index 100% rename from platform/android/lcp/src/main/jni/License.cpp rename to platform/android/lib/src/clientlib/cpp/License.cpp diff --git a/platform/android/lcp/src/main/jni/License.h b/platform/android/lib/src/clientlib/cpp/License.h similarity index 100% rename from platform/android/lcp/src/main/jni/License.h rename to platform/android/lib/src/clientlib/cpp/License.h diff --git a/platform/android/lcp/src/main/jni/NetProvider.cpp b/platform/android/lib/src/clientlib/cpp/NetProvider.cpp similarity index 100% rename from platform/android/lcp/src/main/jni/NetProvider.cpp rename to platform/android/lib/src/clientlib/cpp/NetProvider.cpp diff --git a/platform/android/lcp/src/main/jni/NetProvider.h b/platform/android/lib/src/clientlib/cpp/NetProvider.h similarity index 100% rename from platform/android/lcp/src/main/jni/NetProvider.h rename to platform/android/lib/src/clientlib/cpp/NetProvider.h diff --git a/platform/android/lcp/src/main/jni/Service.cpp b/platform/android/lib/src/clientlib/cpp/Service.cpp similarity index 92% rename from platform/android/lcp/src/main/jni/Service.cpp rename to platform/android/lib/src/clientlib/cpp/Service.cpp index f6b625a..c750a94 100644 --- a/platform/android/lcp/src/main/jni/Service.cpp +++ b/platform/android/lib/src/clientlib/cpp/Service.cpp @@ -30,10 +30,7 @@ #include #include -#include - -//#include -extern "C" jboolean javaEPub3_handleSdkError(JNIEnv *env, jstring message, jboolean isSevereEpubError); +//extern "C" jboolean javaEPub3_handleSdkError(JNIEnv *env, jstring message, jboolean isSevereEpubError); //extern "C" jstring toJstring(JNIEnv *env, const char* str, bool freeNative = false); @@ -92,7 +89,7 @@ JNIEXPORT jobject JNICALL Java_org_readium_sdk_lcp_Service_nativeOpenLicense( //jstring test = toJstring(env, "test", false); jstring jmessage = env->NewStringUTF(lcp::Status::ToString(status).c_str()); - jboolean b = javaEPub3_handleSdkError(env, jmessage, (jboolean)true); + //jboolean b = javaEPub3_handleSdkError(env, jmessage, (jboolean)true); env->DeleteLocalRef(jmessage); return nullptr; @@ -100,7 +97,7 @@ JNIEXPORT jobject JNICALL Java_org_readium_sdk_lcp_Service_nativeOpenLicense( } catch (lcp::StatusException &ex) { jstring jmessage = env->NewStringUTF(ex.what()); - jboolean b = javaEPub3_handleSdkError(env, jmessage, (jboolean)true); + //jboolean b = javaEPub3_handleSdkError(env, jmessage, (jboolean)true); env->DeleteLocalRef(jmessage); return nullptr; diff --git a/platform/android/lcp/src/main/jni/Service.h b/platform/android/lib/src/clientlib/cpp/Service.h similarity index 100% rename from platform/android/lcp/src/main/jni/Service.h rename to platform/android/lib/src/clientlib/cpp/Service.h diff --git a/platform/android/lcp/src/main/jni/StorageProvider.cpp b/platform/android/lib/src/clientlib/cpp/StorageProvider.cpp similarity index 100% rename from platform/android/lcp/src/main/jni/StorageProvider.cpp rename to platform/android/lib/src/clientlib/cpp/StorageProvider.cpp diff --git a/platform/android/lcp/src/main/jni/StorageProvider.h b/platform/android/lib/src/clientlib/cpp/StorageProvider.h similarity index 100% rename from platform/android/lcp/src/main/jni/StorageProvider.h rename to platform/android/lib/src/clientlib/cpp/StorageProvider.h diff --git a/platform/android/lcp/src/main/jni/Util.cpp b/platform/android/lib/src/clientlib/cpp/Util.cpp similarity index 100% rename from platform/android/lcp/src/main/jni/Util.cpp rename to platform/android/lib/src/clientlib/cpp/Util.cpp diff --git a/platform/android/lcp/src/main/jni/Util.h b/platform/android/lib/src/clientlib/cpp/Util.h similarity index 100% rename from platform/android/lcp/src/main/jni/Util.h rename to platform/android/lib/src/clientlib/cpp/Util.h diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/Acquisition.java b/platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/Acquisition.java similarity index 100% rename from platform/android/lib/src/main/java/org/readium/sdk/lcp/Acquisition.java rename to platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/Acquisition.java diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/DoneCallback.java b/platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/DoneCallback.java similarity index 100% rename from platform/android/lib/src/main/java/org/readium/sdk/lcp/DoneCallback.java rename to platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/DoneCallback.java diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/Lcp.java b/platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/Lcp.java similarity index 100% rename from platform/android/lib/src/main/java/org/readium/sdk/lcp/Lcp.java rename to platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/Lcp.java diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/License.java b/platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/License.java similarity index 100% rename from platform/android/lib/src/main/java/org/readium/sdk/lcp/License.java rename to platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/License.java diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/NetProvider.java b/platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/NetProvider.java similarity index 100% rename from platform/android/lib/src/main/java/org/readium/sdk/lcp/NetProvider.java rename to platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/NetProvider.java diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/NetProviderCallback.java b/platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/NetProviderCallback.java similarity index 100% rename from platform/android/lib/src/main/java/org/readium/sdk/lcp/NetProviderCallback.java rename to platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/NetProviderCallback.java diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/Service.java b/platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/Service.java similarity index 100% rename from platform/android/lib/src/main/java/org/readium/sdk/lcp/Service.java rename to platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/Service.java diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/StatusDocumentProcessing.java b/platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/StatusDocumentProcessing.java similarity index 100% rename from platform/android/lib/src/main/java/org/readium/sdk/lcp/StatusDocumentProcessing.java rename to platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/StatusDocumentProcessing.java diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/StorageProvider.java b/platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/StorageProvider.java similarity index 100% rename from platform/android/lib/src/main/java/org/readium/sdk/lcp/StorageProvider.java rename to platform/android/lib/src/clientlib/java/org/readium/sdk/lcp/StorageProvider.java diff --git a/platform/android/lcp/src/main/jni/CredentialHandler.cpp b/platform/android/lib/src/contentfilter/cpp/CredentialHandler.cpp similarity index 100% rename from platform/android/lcp/src/main/jni/CredentialHandler.cpp rename to platform/android/lib/src/contentfilter/cpp/CredentialHandler.cpp diff --git a/platform/android/lcp/src/main/jni/CredentialHandler.h b/platform/android/lib/src/contentfilter/cpp/CredentialHandler.h similarity index 100% rename from platform/android/lcp/src/main/jni/CredentialHandler.h rename to platform/android/lib/src/contentfilter/cpp/CredentialHandler.h diff --git a/platform/android/lcp/src/main/jni/ServiceFactory.cpp b/platform/android/lib/src/contentfilter/cpp/ServiceFactory.cpp similarity index 99% rename from platform/android/lcp/src/main/jni/ServiceFactory.cpp rename to platform/android/lib/src/contentfilter/cpp/ServiceFactory.cpp index 5999fb1..9f48b98 100644 --- a/platform/android/lcp/src/main/jni/ServiceFactory.cpp +++ b/platform/android/lib/src/contentfilter/cpp/ServiceFactory.cpp @@ -87,4 +87,4 @@ JNIEXPORT jobject JNICALL Java_org_readium_sdk_lcp_ServiceFactory_nativeBuild( jclass cls = env->FindClass("org/readium/sdk/lcp/Service"); jmethodID methodId = env->GetMethodID(cls, "", "(J)V"); return env->NewObject(cls, methodId, (jlong) service); -} \ No newline at end of file +} diff --git a/platform/android/lcp/src/main/jni/ServiceFactory.h b/platform/android/lib/src/contentfilter/cpp/ServiceFactory.h similarity index 100% rename from platform/android/lcp/src/main/jni/ServiceFactory.h rename to platform/android/lib/src/contentfilter/cpp/ServiceFactory.h diff --git a/platform/android/lcp/src/main/jni/StatusDocumentHandler.cpp b/platform/android/lib/src/contentfilter/cpp/StatusDocumentHandler.cpp similarity index 100% rename from platform/android/lcp/src/main/jni/StatusDocumentHandler.cpp rename to platform/android/lib/src/contentfilter/cpp/StatusDocumentHandler.cpp diff --git a/platform/android/lcp/src/main/jni/StatusDocumentHandler.h b/platform/android/lib/src/contentfilter/cpp/StatusDocumentHandler.h similarity index 100% rename from platform/android/lcp/src/main/jni/StatusDocumentHandler.h rename to platform/android/lib/src/contentfilter/cpp/StatusDocumentHandler.h diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/CredentialHandler.java b/platform/android/lib/src/contentfilter/java/org/readium/sdk/lcp/CredentialHandler.java similarity index 100% rename from platform/android/lib/src/main/java/org/readium/sdk/lcp/CredentialHandler.java rename to platform/android/lib/src/contentfilter/java/org/readium/sdk/lcp/CredentialHandler.java diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/ServiceFactory.java b/platform/android/lib/src/contentfilter/java/org/readium/sdk/lcp/ServiceFactory.java similarity index 100% rename from platform/android/lib/src/main/java/org/readium/sdk/lcp/ServiceFactory.java rename to platform/android/lib/src/contentfilter/java/org/readium/sdk/lcp/ServiceFactory.java diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/StatusDocumentHandler.java b/platform/android/lib/src/contentfilter/java/org/readium/sdk/lcp/StatusDocumentHandler.java similarity index 100% rename from platform/android/lib/src/main/java/org/readium/sdk/lcp/StatusDocumentHandler.java rename to platform/android/lib/src/contentfilter/java/org/readium/sdk/lcp/StatusDocumentHandler.java diff --git a/platform/android/settings.gradle b/platform/android/settings.gradle new file mode 100644 index 0000000..8c2a2e0 --- /dev/null +++ b/platform/android/settings.gradle @@ -0,0 +1 @@ +include ':lib' From 387f28397eace9b027557f45748d6f23622a2b1f Mon Sep 17 00:00:00 2001 From: danielweck Date: Wed, 10 May 2017 18:29:32 +0100 Subject: [PATCH 13/42] major fixes in CRL (Certificate Revocation List) support --- .../android/lcp/build_experimental.gradle | 2 +- .../android/lcp/src/main/jni/NetProvider.cpp | 16 +- .../android/lcp/src/main/jni/NetProvider.h | 2 +- .../java/org/readium/sdk/lcp/NetProvider.java | 156 ++++++++++++------ .../readium/sdk/lcp/NetProviderCallback.java | 4 +- .../CertificateRevocationList.cpp | 89 +++++----- .../CertificateRevocationList.h | 4 +- src/lcp-client-lib/CrlUpdater.cpp | 85 +++++++++- src/lcp-client-lib/CrlUpdater.h | 22 ++- src/lcp-client-lib/CryptoppCryptoProvider.cpp | 100 +++++++++-- src/lcp-client-lib/CryptoppCryptoProvider.h | 21 ++- src/lcp-client-lib/ICertificate.h | 1 + src/lcp-client-lib/ICryptoProvider.h | 2 + src/lcp-client-lib/LcpService.cpp | 10 ++ src/lcp-client-lib/ThreadTimer.cpp | 18 +- src/lcp-client-lib/ThreadTimer.h | 4 + .../public/DefaultFileSystemProvider.h | 12 +- 17 files changed, 418 insertions(+), 130 deletions(-) diff --git a/platform/android/lcp/build_experimental.gradle b/platform/android/lcp/build_experimental.gradle index a08f981..a372fd8 100644 --- a/platform/android/lcp/build_experimental.gradle +++ b/platform/android/lcp/build_experimental.gradle @@ -63,7 +63,7 @@ model { "-fexceptions", "-fpic", "-DFEATURES_READIUM", - "-DDISABLE_CRL", + "-D__DISABLE_CRL__", "-DZLIB_ONLY", ndk_clang ? "-D_LIBCPP_INLINE_VISIBILITY_EXCEPT_GCC49=_LIBCPP_INLINE_VISIBILITY" : "-DREADIUM_GCC", "-I" + project(':epub3').projectDir + "/include", diff --git a/platform/android/lcp/src/main/jni/NetProvider.cpp b/platform/android/lcp/src/main/jni/NetProvider.cpp index 5247cf2..2bbb7ac 100644 --- a/platform/android/lcp/src/main/jni/NetProvider.cpp +++ b/platform/android/lcp/src/main/jni/NetProvider.cpp @@ -26,7 +26,10 @@ #if !DISABLE_NET_PROVIDER +#include #include "NetProvider.h" +#include "BaseDownloadRequest.h" + #include "Util.h" namespace lcp { @@ -49,6 +52,12 @@ namespace lcp { ) { JNIEnv * env = getJNIEnv(); jstring jUrl = env->NewStringUTF(request->Url().c_str()); + + if (!request->HasDestinationPath()) { + // TODO: write to STREAM instead!! + // request->DestinationStream() + } + jstring jDstPath = env->NewStringUTF(request->DestinationPath().c_str()); env->CallVoidMethod(this->jNetProvider, this->jDownloadMethodId, jUrl, jDstPath, (jlong) request, (jlong) callback); @@ -70,9 +79,14 @@ JNIEXPORT void JNICALL Java_org_readium_sdk_lcp_NetProviderCallback_nativeOnRequ } JNIEXPORT void JNICALL Java_org_readium_sdk_lcp_NetProviderCallback_nativeOnRequestEnded( - JNIEnv *env, jobject obj, jlong callbackPtr, jlong requestPtr) { + JNIEnv *env, jobject obj, jlong callbackPtr, jlong requestPtr, jstring path) { lcp::INetProviderCallback * callback = (lcp::INetProviderCallback *) callbackPtr; lcp::IDownloadRequest * request = (lcp::IDownloadRequest *) requestPtr; + lcp::BaseDownloadRequest* request_ = dynamic_cast(request); + if (request_) { + const char *path_ = env->GetStringUTFChars(path, 0); + request_->SetSuggestedFileName(std::string(path_)); + } lcp::Status status(lcp::StatusCode::ErrorCommonSuccess); callback->OnRequestEnded(request, status); } diff --git a/platform/android/lcp/src/main/jni/NetProvider.h b/platform/android/lcp/src/main/jni/NetProvider.h index 50ad522..e9f6414 100644 --- a/platform/android/lcp/src/main/jni/NetProvider.h +++ b/platform/android/lcp/src/main/jni/NetProvider.h @@ -61,7 +61,7 @@ namespace lcp { JNIEXPORT void JNICALL Java_org_readium_sdk_lcp_NetProviderCallback_nativeOnRequestStarted( JNIEnv *env, jobject obj, jlong callbackPtr, jlong requestPtr); JNIEXPORT void JNICALL Java_org_readium_sdk_lcp_NetProviderCallback_nativeOnRequestEnded( - JNIEnv *env, jobject obj, jlong callbackPtr, jlong requestPtr); + JNIEnv *env, jobject obj, jlong callbackPtr, jlong requestPtr, jstring path); JNIEXPORT void JNICALL Java_org_readium_sdk_lcp_NetProviderCallback_nativeOnRequestCanceled( JNIEnv *env, jobject obj, jlong callbackPtr, jlong requestPtr); JNIEXPORT void JNICALL Java_org_readium_sdk_lcp_NetProviderCallback_nativeOnRequestProgressed( diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/NetProvider.java b/platform/android/lib/src/main/java/org/readium/sdk/lcp/NetProvider.java index 0e6c8c1..94e53dd 100644 --- a/platform/android/lib/src/main/java/org/readium/sdk/lcp/NetProvider.java +++ b/platform/android/lib/src/main/java/org/readium/sdk/lcp/NetProvider.java @@ -26,6 +26,7 @@ package org.readium.sdk.lcp; +import android.app.Activity; import android.content.Context; import android.net.Uri; import android.os.AsyncTask; @@ -36,21 +37,28 @@ import com.koushikdutta.async.http.AsyncHttpRequest; import com.koushikdutta.async.http.Headers; import com.koushikdutta.ion.Ion; +import com.koushikdutta.ion.Response; import com.koushikdutta.ion.loader.AsyncHttpRequestFactory; +import org.apache.commons.io.IOUtils; + import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.StringWriter; import java.net.URI; import java.util.HashMap; import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; public class NetProvider { //#if !DISABLE_NET_PROVIDER private Context context; - private Map> requests; + private Activity activity; + private Map>> requests; /** * Cancel request asynchronously @@ -59,7 +67,7 @@ private class CancelRequest extends AsyncTask { @Override protected Void doInBackground(Long... requestPtrs) { for (Long requestPtr: requestPtrs) { - Future request = NetProvider.this.requests.get(requestPtr); + Future> request = NetProvider.this.requests.get(requestPtr); request.cancel(); } @@ -67,26 +75,45 @@ protected Void doInBackground(Long... requestPtrs) { } } - public NetProvider(Context context) { + public NetProvider(Context context, Activity activity) { this.context = context; + this.activity = activity; + this.requests = new HashMap<>(); } - public void download(String url, String dstPath, long requestPtr, long callbackPtr) { + public void download(final String url, String dstPath, final long requestPtr, long callbackPtr) { final NetProviderCallback callback = new NetProviderCallback(callbackPtr, requestPtr); - final String destPath = dstPath; if (dstPath == null || dstPath.isEmpty()) { File outputDir = this.context.getCacheDir(); File outputFile = null; try { - outputFile = File.createTempFile("readium_lcp_download", ".tmp", outputDir); + outputFile = File.createTempFile("readium_TEMP_download", ".tmp", outputDir); dstPath = outputFile.getAbsolutePath(); } catch (IOException e) { e.printStackTrace(); } } + final String destPath = dstPath; + +// Timer timer = new Timer(); +// timer.schedule(new TimerTask() { +// @Override +// public void run() { +// +// } +// }, 500); + +// runOnUiThread(new Runnable() { +// @Override +// public void run() { +// +// new AsyncTask() { +// @Override +// protected Void doInBackground(Void... params) { + // final AsyncHttpRequestFactory current = Ion.getDefault(context).configure().getAsyncHttpRequestFactory(); // Ion.getDefault(context).configure().setAsyncHttpRequestFactory(new AsyncHttpRequestFactory() { // @Override @@ -97,54 +124,77 @@ public void download(String url, String dstPath, long requestPtr, long callbackP // } // }); - - Future request = Ion.with(this.context) - .load("GET", url) - .setLogging("Ion", Log.VERBOSE) - .progress(callback) // not UI thread - //.progressHandler(callback) // UI thread - //.setTimeout(AsyncHttpRequest.DEFAULT_TIMEOUT) //30000 - .setTimeout(6000) - //.setHeader(name, value) - - // UI thread - .asInputStream().setCallback(new FutureCallback() { - @Override - public void onCompleted(Exception e, InputStream inputStream) { - if (e != null) { - callback.onCompleted(e, null); - return; - } - if (inputStream == null) { - callback.onCompleted(null, null); - return; - } - File destFile = new File(destPath); - try { - FileOutputStream outputStream = new FileOutputStream(destFile); - //inputStream.transferTo(outputStream); - - byte[] buf = new byte[4096]; - int n; - int total = 0; - while((n = inputStream.read(buf))>0){ - total += n; - outputStream.write(buf, 0, n); +// this.activity.runOnUiThread(new Runnable() { +// @Override +// public void run() { + + Future> request = Ion.with(NetProvider.this.context) + .load("GET", url) + .setLogging("Readium Ion", Log.VERBOSE) + + //.setTimeout(AsyncHttpRequest.DEFAULT_TIMEOUT) //30000 + .setTimeout(6000) + + // TODO: comment this in production! (this is only for testing a local HTTP server) + //.setHeader("X-Add-Delay", "2s") + + .progress(callback) // not UI thread + //.progressHandler(callback) // UI thread + + .asInputStream() + .withResponse() + + // UI thread + .setCallback(new FutureCallback>() { + @Override + public void onCompleted(Exception e, Response response) { + + InputStream inputStream = response != null ? response.getResult() : null; + int httpResponseCode = response != null ? response.getHeaders().code() : 0; + if (e != null || inputStream == null + || httpResponseCode < 200 || httpResponseCode >= 300) { + + callback.onCompleted(e, null); + return; + } + + File destFile = new File(destPath); + try { + FileOutputStream outputStream = new FileOutputStream(destFile); + //inputStream.transferTo(outputStream); + + byte[] buf = new byte[4096]; + int n; + int total = 0; + while ((n = inputStream.read(buf)) > 0) { + total += n; + outputStream.write(buf, 0, n); + } + outputStream.close(); +// inputStream.close(); + callback.onCompleted(null, destFile); + + } catch (Exception ex) { + ex.printStackTrace(); + callback.onCompleted(ex, null); + } finally { + try { + inputStream.close(); + } catch (IOException ex) { + ex.printStackTrace(); + // ignore + } + } } - outputStream.close(); - inputStream.close(); - callback.onCompleted(null, destFile); - } catch (Exception ex) { - ex.printStackTrace(); - callback.onCompleted(ex, null); - } - } - }) -// .write(new File(dstPath)) -// .setCallback(callback) - ; - - this.requests.put(requestPtr, request); + }); + + NetProvider.this.requests.put(requestPtr, request); + +//// ASYNC TASK +// return null; + +// } +// }); } public void cancel(long requestPtr) { diff --git a/platform/android/lib/src/main/java/org/readium/sdk/lcp/NetProviderCallback.java b/platform/android/lib/src/main/java/org/readium/sdk/lcp/NetProviderCallback.java index 6de0f6c..75ad832 100644 --- a/platform/android/lib/src/main/java/org/readium/sdk/lcp/NetProviderCallback.java +++ b/platform/android/lib/src/main/java/org/readium/sdk/lcp/NetProviderCallback.java @@ -77,7 +77,7 @@ public void onCompleted(Exception e, File result) { // Request timeout this.nativeOnRequestCanceled(this.nativePtr, this.requestPtr); } else if (e == null && result != null) { - this.nativeOnRequestEnded(this.nativePtr, this.requestPtr); + this.nativeOnRequestEnded(this.nativePtr, this.requestPtr, result.getAbsolutePath()); } else { // Other errors this.nativeOnRequestCanceled(this.nativePtr, this.requestPtr); @@ -104,6 +104,6 @@ public void onProgress(long downloaded, long total) { private native void nativeOnRequestStarted(long nativePtr, long requestPtr); private native void nativeOnRequestProgressed(long nativePtr, long requestPtr, float progress); - private native void nativeOnRequestEnded(long nativePtr, long requestPtr); + private native void nativeOnRequestEnded(long nativePtr, long requestPtr, String path); private native void nativeOnRequestCanceled(long nativePtr, long requestPtr); } diff --git a/src/lcp-client-lib/CertificateRevocationList.cpp b/src/lcp-client-lib/CertificateRevocationList.cpp index 482f415..a4499bd 100644 --- a/src/lcp-client-lib/CertificateRevocationList.cpp +++ b/src/lcp-client-lib/CertificateRevocationList.cpp @@ -39,63 +39,66 @@ using namespace CryptoPP; namespace lcp { - CertificateRevocationList::CertificateRevocationList(const Buffer & crlRaw) - { - this->UpdateRevocationList(crlRaw); - } +// CertificateRevocationList::CertificateRevocationList(const Buffer & crlRaw) +// { +// this->UpdateRevocationList(crlRaw); +// } void CertificateRevocationList::UpdateRevocationList(const Buffer & crlRaw) { - std::unique_lock locker(m_sync); + try { + std::unique_lock locker(m_sync); - ByteQueue crlData; - crlData.Put(crlRaw.data(), crlRaw.size()); - crlData.MessageEnd(); + ByteQueue crlData; + crlData.Put(crlRaw.data(), crlRaw.size()); + crlData.MessageEnd(); - BERSequenceDecoder crl(crlData); - { - BERSequenceDecoder toBeSignedCertList(crl); + BERSequenceDecoder crl(crlData); { - word32 version = CryptoppUtils::Cert::ReadVersion(toBeSignedCertList, CertificateVersion::Certificatev2); - if (version != CertificateVersion::Certificatev2) + BERSequenceDecoder toBeSignedCertList(crl); { - throw BERDecodeErr("Wrong version of the crl"); - } + word32 version = CryptoppUtils::Cert::ReadVersion(toBeSignedCertList, + CertificateVersion::Certificatev2); + if (version != CertificateVersion::Certificatev2) { + throw BERDecodeErr("Wrong version of the crl"); + } - // algorithmId - CryptoppUtils::Cert::SkipNextSequence(toBeSignedCertList); - // issuer - CryptoppUtils::Cert::SkipNextSequence(toBeSignedCertList); - // this update - CryptoppUtils::Cert::BERDecodeTime(toBeSignedCertList, m_thisUpdate); - // next update - if (!toBeSignedCertList.EndReached()) - { - byte nextId = toBeSignedCertList.PeekByte(); - if (nextId == UTC_TIME || nextId == GENERALIZED_TIME) - { - CryptoppUtils::Cert::BERDecodeTime(toBeSignedCertList, m_nextUpdate); + // algorithmId + CryptoppUtils::Cert::SkipNextSequence(toBeSignedCertList); + // issuer + CryptoppUtils::Cert::SkipNextSequence(toBeSignedCertList); + // this update + CryptoppUtils::Cert::BERDecodeTime(toBeSignedCertList, m_thisUpdate); + // next update + if (!toBeSignedCertList.EndReached()) { + byte nextId = toBeSignedCertList.PeekByte(); + if (nextId == UTC_TIME || nextId == GENERALIZED_TIME) { + CryptoppUtils::Cert::BERDecodeTime(toBeSignedCertList, m_nextUpdate); + } } - } - if (!toBeSignedCertList.EndReached()) - { - BERSequenceDecoder revokedCertificates(toBeSignedCertList); - { - while (!revokedCertificates.EndReached()) + if (!toBeSignedCertList.EndReached()) { + BERSequenceDecoder revokedCertificates(toBeSignedCertList); { - BERSequenceDecoder nextRevokedCertificate(revokedCertificates); - { - std::string serial = CryptoppUtils::Cert::ReadIntegerAsString(nextRevokedCertificate); - m_revokedSerialNumbers.insert(serial); + while (!revokedCertificates.EndReached()) { + BERSequenceDecoder nextRevokedCertificate(revokedCertificates); + { + std::string serial = CryptoppUtils::Cert::ReadIntegerAsString( + nextRevokedCertificate); + m_revokedSerialNumbers.insert(serial); + } + nextRevokedCertificate.SkipAll(); } - nextRevokedCertificate.SkipAll(); } } + toBeSignedCertList.SkipAll(); } - toBeSignedCertList.SkipAll(); } } + catch (const std::exception & ex) + { + throw; + } } std::string CertificateRevocationList::ThisUpdateDate() const @@ -133,6 +136,12 @@ namespace lcp std::unique_lock locker(m_sync); return m_revokedSerialNumbers; } + + const void CertificateRevocationList::InsertRevokedSerialNumber(std::string serial) + { + std::unique_lock locker(m_sync); + m_revokedSerialNumbers.insert(serial); + } } #endif //!DISABLE_CRL diff --git a/src/lcp-client-lib/CertificateRevocationList.h b/src/lcp-client-lib/CertificateRevocationList.h index fadcc62..3afbf7b 100644 --- a/src/lcp-client-lib/CertificateRevocationList.h +++ b/src/lcp-client-lib/CertificateRevocationList.h @@ -40,7 +40,7 @@ namespace lcp { public: CertificateRevocationList() = default; - explicit CertificateRevocationList(const Buffer & crlRaw); +// explicit CertificateRevocationList(const Buffer & crlRaw); // ICertificateRevocationList virtual void UpdateRevocationList(const Buffer & crlRaw); @@ -50,6 +50,8 @@ namespace lcp virtual std::string NextUpdateDate() const; virtual bool SerialNumberRevoked(const std::string & serialNumber) const; virtual const StringsSet & RevokedSerialNumbers() const; + virtual const void InsertRevokedSerialNumber(std::string serial); + private: mutable std::mutex m_sync; diff --git a/src/lcp-client-lib/CrlUpdater.cpp b/src/lcp-client-lib/CrlUpdater.cpp index 9d24649..1ad0b34 100644 --- a/src/lcp-client-lib/CrlUpdater.cpp +++ b/src/lcp-client-lib/CrlUpdater.cpp @@ -33,8 +33,13 @@ #include "CrlUpdater.h" #if !DISABLE_NET_PROVIDER +#if !DISABLE_CRL_DOWNLOAD_IN_MEMORY #include "SimpleMemoryWritableStream.h" #include "DownloadInMemoryRequest.h" +#else // !DISABLE_CRL_DOWNLOAD_IN_MEMORY +#include "DownloadInFileRequest.h" +#endif // !DISABLE_CRL_DOWNLOAD_IN_MEMORY + #endif //!DISABLE_NET_PROVIDER #include "DateTime.h" @@ -48,16 +53,26 @@ namespace lcp #if !DISABLE_NET_PROVIDER INetProvider * netProvider, #endif //!DISABLE_NET_PROVIDER + + IFileSystemProvider * fileSystemProvider, + ICertificateRevocationList * revocationList, +#if !DISABLE_CRL_BACKGROUND_POLL ThreadTimer * threadTimer, +#endif //!DISABLE_CRL_BACKGROUND_POLL const std::string & defaultCrlUrl ) : m_requestRunning(false) #if !DISABLE_NET_PROVIDER , m_netProvider(netProvider) #endif //!DISABLE_NET_PROVIDER + + , m_fileSystemProvider(fileSystemProvider) + , m_revocationList(revocationList) - , m_threadTimer(threadTimer) +#if !DISABLE_CRL_BACKGROUND_POLL + , m_threadTimer(threadTimer) +#endif //!DISABLE_CRL_BACKGROUND_POLL , m_currentRequestStatus(Status(StatusCode::ErrorCommonSuccess)) { if (!defaultCrlUrl.empty()) @@ -136,10 +151,17 @@ namespace lcp void CrlUpdater::Download(const std::string & url) { #if !DISABLE_NET_PROVIDER - m_crlStream.reset(new SimpleMemoryWritableStream()); + m_requestRunning = true; + +#if !DISABLE_CRL_DOWNLOAD_IN_MEMORY + m_crlStream.reset(new SimpleMemoryWritableStream()); // not actually used! (NetProvider Java operates on File) m_downloadRequest.reset(new DownloadInMemoryRequest(url, m_crlStream.get())); +#else // !DISABLE_CRL_DOWNLOAD_IN_MEMORY + m_crlFile.reset(m_fileSystemProvider->GetFile(PATH_TO_DOWNLOAD)); + m_downloadRequest.reset(new DownloadInFileRequest(url, m_crlFile.get())); +#endif // !DISABLE_CRL_DOWNLOAD_IN_MEMORY + m_netProvider->StartDownloadRequest(m_downloadRequest.get(), this); - m_requestRunning = true; #else m_currentRequestStatus = Status(StatusCode::ErrorCommonSuccess); m_requestRunning = false; @@ -150,10 +172,12 @@ namespace lcp #if !DISABLE_NET_PROVIDER void CrlUpdater::OnRequestStarted(INetRequest * request) { + bool breakpoint = true; } void CrlUpdater::OnRequestProgressed(INetRequest * request, float progress) { + bool breakpoint = true; } void CrlUpdater::OnRequestCanceled(INetRequest * request) @@ -170,7 +194,51 @@ namespace lcp std::unique_lock locker(m_downloadSync); if (Status::IsSuccess(result)) { - m_revocationList->UpdateRevocationList(m_crlStream->Buffer()); +#if !DISABLE_CRL_DOWNLOAD_IN_MEMORY + lcp::BaseDownloadRequest* request_ = dynamic_cast(request); + if (request_) { + std::string path = request_->SuggestedFileName(); + if (path.length()) { + IFile* file = m_fileSystemProvider->GetFile(path, IFileSystemProvider::ReadOnly); + + size_t bufferSize = 1024 * 1024; + std::vector buffer(bufferSize); + + size_t read = 0; + size_t sizeToRead = bufferSize; + size_t fileSize = static_cast(file->Size()); + while (read != fileSize) + { + sizeToRead = (fileSize - read > bufferSize) ? bufferSize : fileSize - read; + file->Read(buffer.data(), sizeToRead); + read += sizeToRead; + } + + delete file; + + m_revocationList->UpdateRevocationList(buffer); //std::vector + } + } + // m_revocationList->UpdateRevocationList(m_crlStream->Buffer()); //std::vector + +#else // !DISABLE_CRL_DOWNLOAD_IN_MEMORY + // IFile == IReadableStream + size_t bufferSize = 1024 * 1024; + std::vector buffer(bufferSize); + + size_t read = 0; + size_t sizeToRead = bufferSize; + size_t fileSize = static_cast(m_crlFile->Size()); + while (read != fileSize) + { + sizeToRead = (fileSize - read > bufferSize) ? bufferSize : fileSize - read; + m_crlFile->Read(buffer.data(), sizeToRead); + read += sizeToRead; + } + + m_revocationList->UpdateRevocationList(buffer); //std::vector +#endif // !DISABLE_CRL_DOWNLOAD_IN_MEMORY + this->ResetNextUpdate(); } m_currentRequestStatus = result; @@ -180,12 +248,15 @@ namespace lcp catch (const std::exception & ex) { m_currentRequestStatus = Status(StatusCode::ErrorNetworkingRequestFailed, "ErrorNetworkingRequestFailed: " + std::string(ex.what())); + m_requestRunning = false; + m_conditionDownload.notify_one(); } } #endif //!DISABLE_NET_PROVIDER void CrlUpdater::ResetNextUpdate() { +#if !DISABLE_CRL_BACKGROUND_POLL if (m_revocationList->HasNextUpdateDate()) { DateTime nextUpdate(m_revocationList->NextUpdateDate()); @@ -205,7 +276,13 @@ namespace lcp m_threadTimer->SetUsage(ThreadTimer::DurationUsage); m_threadTimer->SetDuration(ThreadTimer::DurationType(TenMinutesPeriod)); } +// +//// TODO: remove this, for testing async update only! +// m_threadTimer->SetUsage(ThreadTimer::DurationUsage); +// m_threadTimer->SetDuration(ThreadTimer::DurationType(2000)); //TenMinutesPeriod == 1000 * 60 * 10 + m_threadTimer->SetAutoReset(true); +#endif //!DISABLE_CRL_BACKGROUND_POLL } } diff --git a/src/lcp-client-lib/CrlUpdater.h b/src/lcp-client-lib/CrlUpdater.h index 8b897b5..f603e91 100644 --- a/src/lcp-client-lib/CrlUpdater.h +++ b/src/lcp-client-lib/CrlUpdater.h @@ -37,12 +37,17 @@ #include "ICertificate.h" #if !DISABLE_NET_PROVIDER -#include "SimpleMemoryWritableStream.h" #include "public/INetProvider.h" #endif //!DISABLE_NET_PROVIDER #include "NonCopyable.h" +#if !DISABLE_CRL_DOWNLOAD_IN_MEMORY +#include "SimpleMemoryWritableStream.h" +#endif // !DISABLE_CRL_DOWNLOAD_IN_MEMORY + +#include "IFileSystemProvider.h" + namespace lcp { class ThreadTimer; @@ -62,8 +67,13 @@ namespace lcp #if !DISABLE_NET_PROVIDER INetProvider * netProvider, #endif //!DISABLE_NET_PROVIDER + + IFileSystemProvider * fileSystemProvider, + ICertificateRevocationList * revocationList, +#if !DISABLE_CRL_BACKGROUND_POLL ThreadTimer * threadTimer, +#endif //!DISABLE_CRL_BACKGROUND_POLL const std::string & defaultCrlUrl ); @@ -95,10 +105,20 @@ namespace lcp INetProvider * m_netProvider; #endif //!DISABLE_NET_PROVIDER ICertificateRevocationList * m_revocationList; +#if !DISABLE_CRL_BACKGROUND_POLL ThreadTimer * m_threadTimer; +#endif //!DISABLE_CRL_BACKGROUND_POLL #if !DISABLE_NET_PROVIDER + + IFileSystemProvider * m_fileSystemProvider; + +#if !DISABLE_CRL_DOWNLOAD_IN_MEMORY std::unique_ptr m_crlStream; +#else // !DISABLE_CRL_DOWNLOAD_IN_MEMORY + std::unique_ptr m_crlFile; +#endif // !DISABLE_CRL_DOWNLOAD_IN_MEMORY + std::unique_ptr m_downloadRequest; #endif //!DISABLE_NET_PROVIDER diff --git a/src/lcp-client-lib/CryptoppCryptoProvider.cpp b/src/lcp-client-lib/CryptoppCryptoProvider.cpp index 80a2e8f..a295bc0 100644 --- a/src/lcp-client-lib/CryptoppCryptoProvider.cpp +++ b/src/lcp-client-lib/CryptoppCryptoProvider.cpp @@ -55,22 +55,41 @@ namespace lcp , INetProvider * netProvider #endif //!DISABLE_NET_PROVIDER + , IFileSystemProvider * fileSystemProvider + #if !DISABLE_CRL , const std::string & defaultCrlUrl #endif //!DISABLE_CRL ) - : m_encryptionProfilesManager(encryptionProfilesManager) + : + m_encryptionProfilesManager(encryptionProfilesManager) + + , m_fileSystemProvider(fileSystemProvider) + { #if !DISABLE_CRL m_revocationList.reset(new CertificateRevocationList()); + +#if !DISABLE_CRL_BACKGROUND_POLL m_threadTimer.reset(new ThreadTimer()); +#endif //!DISABLE_CRL_BACKGROUND_POLL m_crlUpdater.reset(new CrlUpdater( #if !DISABLE_NET_PROVIDER netProvider, #endif //!DISABLE_NET_PROVIDER - m_revocationList.get(), m_threadTimer.get(), defaultCrlUrl)); + m_fileSystemProvider, + + m_revocationList.get(), + +#if !DISABLE_CRL_BACKGROUND_POLL + m_threadTimer.get(), +#endif //!DISABLE_CRL_BACKGROUND_POLL + + defaultCrlUrl)); + +#if !DISABLE_CRL_BACKGROUND_POLL m_threadTimer->SetHandler(std::bind(&CrlUpdater::Update, m_crlUpdater.get())); m_threadTimer->SetAutoReset(false); @@ -80,6 +99,8 @@ namespace lcp m_threadTimer->SetDuration(ThreadTimer::DurationType(ThreadTimer::DurationType::zero())); m_threadTimer->Start(); } +#endif //!DISABLE_CRL_BACKGROUND_POLL + #endif //!DISABLE_CRL } @@ -89,7 +110,10 @@ namespace lcp try { m_crlUpdater->Cancel(); + +#if !DISABLE_CRL_BACKGROUND_POLL m_threadTimer->Stop(); +#endif //!DISABLE_CRL_BACKGROUND_POLL } catch (...) { @@ -438,6 +462,43 @@ namespace lcp } #if !DISABLE_CRL + + Status CryptoppCryptoProvider::CheckRevokation(ILicense* license) { + +#if ENABLE_PROFILE_NAMES + IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(license->Crypto()->EncryptionProfile()); + if (profile == nullptr) + { + return Status(StatusCode::ErrorCommonEncryptionProfileNotFound, "ErrorCommonEncryptionProfileNotFound"); + } +#else + IEncryptionProfile * profile = m_encryptionProfilesManager->GetProfile(); +#endif //ENABLE_PROFILE_NAMES + + std::unique_ptr providerCertificate; + try { + providerCertificate.reset( + new lcp::Certificate(license->Crypto()->SignatureCertificate(), profile)); + } + catch (std::exception &ex) { + return Status(StatusCode::ErrorOpeningContentProviderCertificateNotValid, + "ErrorOpeningContentProviderCertificateNotValid: " + + std::string(ex.what())); + } + + return this->CheckRevokation(providerCertificate.get()); + } + + Status CryptoppCryptoProvider::CheckRevokation(ICertificate * providerCertificate) { + + if (m_revocationList->SerialNumberRevoked(providerCertificate->SerialNumber())) { + return Status(StatusCode::ErrorOpeningContentProviderCertificateRevoked, + "ErrorOpeningContentProviderCertificateRevoked"); + } + + return StatusCode::ErrorCommonSuccess; + } + Status CryptoppCryptoProvider::ProcessRevokation(ICertificate * rootCertificate, ICertificate * providerCertificate) { m_crlUpdater->UpdateCrlUrls(rootCertificate->DistributionPoints()); @@ -447,33 +508,52 @@ namespace lcp std::unique_lock locker(m_processRevocationSync); if (m_crlUpdater->ContainsAnyUrl() && !m_revocationList->HasThisUpdateDate()) { +#if !DISABLE_CRL_BACKGROUND_POLL if (m_threadTimer->IsRunning()) { m_threadTimer->Stop(); } +#endif //!DISABLE_CRL_BACKGROUND_POLL - // Check once more, the CRL state could've been changed during the stop process - if (!m_revocationList->HasThisUpdateDate()) - { - // If CRL is absent, update it right before certificate verification - m_crlUpdater->Update(); - } +// // Check once more, the CRL state could've been changed during the stop process +// if (!m_revocationList->HasThisUpdateDate()) +// { +// // If CRL is absent, update it right before certificate verification +// m_crlUpdater->Update(); +// } +#if !DISABLE_CRL_BACKGROUND_POLL // Start timer which will check CRL for updates periodically or by time point m_threadTimer->SetAutoReset(true); m_threadTimer->SetUsage(ThreadTimer::DurationUsage); + + //std::function + m_threadTimer->SetHandler([&]{ + m_crlUpdater->Update(); + }); // std::bind(&CrlUpdater::Update, &m_crlUpdater); + m_threadTimer->SetDuration(ThreadTimer::DurationType(CrlUpdater::TenMinutesPeriod)); m_threadTimer->Start(); +#endif //!DISABLE_CRL_BACKGROUND_POLL } locker.unlock(); +#if !DISABLE_CRL_BACKGROUND_POLL // If exception occurred in the timer thread, re-throw it m_threadTimer->RethrowExceptionIfAny(); +#endif //!DISABLE_CRL_BACKGROUND_POLL + - if (m_revocationList->SerialNumberRevoked(providerCertificate->SerialNumber())) + Status resx = this->CheckRevokation(providerCertificate); + if (!Status::IsSuccess(resx)) { - return Status(StatusCode::ErrorOpeningContentProviderCertificateRevoked, "ErrorOpeningContentProviderCertificateRevoked"); + return resx; } +// +// // TODO: only for testing fake mock revocation!! +// // TODO: REMOVE ! +// m_revocationList->InsertRevokedSerialNumber(providerCertificate->SerialNumber()); + return Status(StatusCode::ErrorCommonSuccess); } #endif //!DISABLE_CRL diff --git a/src/lcp-client-lib/CryptoppCryptoProvider.h b/src/lcp-client-lib/CryptoppCryptoProvider.h index 63074ef..0b802cd 100644 --- a/src/lcp-client-lib/CryptoppCryptoProvider.h +++ b/src/lcp-client-lib/CryptoppCryptoProvider.h @@ -30,6 +30,7 @@ #include #include +#include "public/IFileSystemProvider.h" #include "ICryptoProvider.h" #include "NonCopyable.h" @@ -60,6 +61,9 @@ class ICertificateRevocationList; , INetProvider * netProvider #endif //!DISABLE_NET_PROVIDER + , IFileSystemProvider * fileSystemProvider + + #if !DISABLE_CRL , const std::string & defaultCrlUrl #endif //!DISABLE_CRL @@ -125,16 +129,27 @@ class ICertificateRevocationList; const std::string & algorithm ); +#if !DISABLE_CRL + public: + Status CheckRevokation(ILicense* license); + private: + Status CheckRevokation(ICertificate * providerCertificate); Status ProcessRevokation(ICertificate * rootCertificate, ICertificate * providerCertificate); - private: -#if !DISABLE_CRL + std::unique_ptr m_revocationList; + +#if !DISABLE_CRL_BACKGROUND_POLL std::unique_ptr m_threadTimer; +#endif //!DISABLE_CRL_BACKGROUND_POLL + + IFileSystemProvider * m_fileSystemProvider; + std::unique_ptr m_crlUpdater; -#endif //!DISABLE_CRL std::mutex m_processRevocationSync; +#endif //!DISABLE_CRL + EncryptionProfilesManager * m_encryptionProfilesManager; }; } diff --git a/src/lcp-client-lib/ICertificate.h b/src/lcp-client-lib/ICertificate.h index 0658aa8..675525d 100644 --- a/src/lcp-client-lib/ICertificate.h +++ b/src/lcp-client-lib/ICertificate.h @@ -74,6 +74,7 @@ namespace lcp virtual std::string NextUpdateDate() const = 0; virtual bool SerialNumberRevoked(const std::string & serialNumber) const = 0; virtual const StringsSet & RevokedSerialNumbers() const = 0; + virtual const void InsertRevokedSerialNumber(std::string serial) = 0; virtual ~ICertificateRevocationList() {} }; diff --git a/src/lcp-client-lib/ICryptoProvider.h b/src/lcp-client-lib/ICryptoProvider.h index f18bb34..bd72a59 100644 --- a/src/lcp-client-lib/ICryptoProvider.h +++ b/src/lcp-client-lib/ICryptoProvider.h @@ -46,6 +46,8 @@ namespace lcp ILicense * license ) = 0; + virtual Status CheckRevokation(ILicense* license) = 0; + virtual Status DecryptUserKey( const std::string & userPassphrase, ILicense * license, diff --git a/src/lcp-client-lib/LcpService.cpp b/src/lcp-client-lib/LcpService.cpp index 1507c96..870797e 100644 --- a/src/lcp-client-lib/LcpService.cpp +++ b/src/lcp-client-lib/LcpService.cpp @@ -84,6 +84,8 @@ namespace lcp , m_netProvider #endif //!DISABLE_NET_PROVIDER + , fileSystemProvider + #if !DISABLE_CRL , defaultCrlUrl #endif //!DISABLE_CRL @@ -153,6 +155,14 @@ namespace lcp res = this->CheckDecrypted((*licensePTR)); } +#if !DISABLE_CRL + Status resx = m_cryptoProvider->CheckRevokation((*licensePTR)); + if (!Status::IsSuccess(resx)) + { + return resx; + } +#endif //!DISABLE_CRL + res = this->CheckLicenseStatusDocument((*licensePTR)); return res; diff --git a/src/lcp-client-lib/ThreadTimer.cpp b/src/lcp-client-lib/ThreadTimer.cpp index 5265e62..2120207 100644 --- a/src/lcp-client-lib/ThreadTimer.cpp +++ b/src/lcp-client-lib/ThreadTimer.cpp @@ -26,6 +26,8 @@ #if !DISABLE_CRL +#if !DISABLE_CRL_BACKGROUND_POLL + #include "ThreadTimer.h" namespace lcp @@ -139,6 +141,13 @@ namespace lcp std::unique_lock locker(m_sync); do { + locker.unlock(); + if (m_handler) + { + m_handler(); + } + locker.lock(); + if (m_usageType == UsageTypeEnum::TimePointUsage) { m_conditionRunning.wait_until(locker, m_runTimePoint, [&]() { return !m_isRunning; }); @@ -151,13 +160,6 @@ namespace lcp { throw std::logic_error("Unknown timer usage type"); } - - locker.unlock(); - if (m_handler) - { - m_handler(); - } - locker.lock(); } while (m_isAutoReset && m_isRunning); @@ -184,4 +186,6 @@ namespace lcp } } +#endif //!DISABLE_CRL_BACKGROUND_POLL + #endif //!DISABLE_CRL \ No newline at end of file diff --git a/src/lcp-client-lib/ThreadTimer.h b/src/lcp-client-lib/ThreadTimer.h index 4cb59ac..f91d93b 100644 --- a/src/lcp-client-lib/ThreadTimer.h +++ b/src/lcp-client-lib/ThreadTimer.h @@ -29,6 +29,8 @@ #if !DISABLE_CRL +#if !DISABLE_CRL_BACKGROUND_POLL + #include #include #include @@ -97,6 +99,8 @@ namespace lcp }; } +#endif //!DISABLE_CRL_BACKGROUND_POLL + #endif //!DISABLE_CRL #endif //__THREAD_TIMER_H__ \ No newline at end of file diff --git a/src/lcp-client-lib/public/DefaultFileSystemProvider.h b/src/lcp-client-lib/public/DefaultFileSystemProvider.h index 94fa300..fd66688 100644 --- a/src/lcp-client-lib/public/DefaultFileSystemProvider.h +++ b/src/lcp-client-lib/public/DefaultFileSystemProvider.h @@ -45,13 +45,13 @@ namespace lcp , m_readPosition(0) , m_writePosition(0) { - int mode = 0; - if (openMode == IFileSystemProvider::CreateNew) - mode = std::ios::in | std::ios::out | std::fstream::trunc | std::ios::binary; - else if (openMode == IFileSystemProvider::ReadOnly) - mode = std::ios::in | std::ios::binary; + m_fstream.open(path.c_str(), (openMode == IFileSystemProvider::CreateNew) ? + (std::ios::in | std::ios::out | std::fstream::trunc | std::ios::binary) : + ((openMode == IFileSystemProvider::ReadOnly) ? + (std::ios::in | std::ios::binary) : + std::ios::binary) + ); - m_fstream.open(path, mode); if (!m_fstream.is_open()) { this->ThrowError("Can not open file: "); From 4160f1fa597fe1bbd04d9a4b4af125cf67b0f473 Mon Sep 17 00:00:00 2001 From: Cyrille Lebeaupin Date: Thu, 11 May 2017 10:49:56 +0200 Subject: [PATCH 14/42] Add extra cmake --- platform/android/README.md | 1 + platform/android/build.gradle | 3 +++ platform/android/lib/CMakeLists.txt | 31 ++++++++++++++++++---------- platform/android/lib/build.gradle | 22 +++++++++++++------- platform/android/lib/clientlib.cmake | 1 - 5 files changed, 38 insertions(+), 20 deletions(-) diff --git a/platform/android/README.md b/platform/android/README.md index a9a16a5..433d130 100644 --- a/platform/android/README.md +++ b/platform/android/README.md @@ -11,6 +11,7 @@ You can define some properties in local.properties file: * readium.ndk_clang: If true, compile with clang * readium.sdk_lib_dir: Path to readium sdk lib (*.so files) directory * readium.sdk_include_dir: Path to readium include directory +* readium.extra_cmake: Path to an extra cmake that can modify lib compilation ## Clean diff --git a/platform/android/build.gradle b/platform/android/build.gradle index bc85075..e606cd0 100644 --- a/platform/android/build.gradle +++ b/platform/android/build.gradle @@ -19,6 +19,9 @@ buildscript { ndkSkipARM = (ndkSkipARM == "true") ? true : false; rootProject.ext.set('readium_ndk_skipARM', ndkSkipARM) + def extraCmake = properties.getProperty('readium.extra_cmake', null) + rootProject.ext.set('readium_extra_cmake', extraCmake) + def readiumSdkLibDir = properties.getProperty('readium.sdk_lib_dir', null) rootProject.ext.set('readium_sdk_lib_dir', readiumSdkLibDir) diff --git a/platform/android/lib/CMakeLists.txt b/platform/android/lib/CMakeLists.txt index 163ac2a..2d617d4 100644 --- a/platform/android/lib/CMakeLists.txt +++ b/platform/android/lib/CMakeLists.txt @@ -27,15 +27,9 @@ include_directories( ${THIRDPARTY_DIR} ${MODULE_DIR}/src/clientlib/cpp/) -# Build clientlib without JNI -add_library("clientlib" STATIC ${CLIENTLIB_ALL_SOURCES}) - -# Build shared library with JNI +# Client lib JNI files file(GLOB CLIENTLIB_JNI_SOURCES ${MODULE_DIR}/src/clientlib/cpp/*.cpp) -add_library("lcp-min" SHARED ${CLIENTLIB_JNI_SOURCES}) -target_link_libraries("lcp-min" "clientlib") - # LCP with content filter add_definitions("-DFEATURES_READIUM -DREADIUM_GCC") include(${PROJECT_DIR}/lib/contentfilter.cmake) @@ -46,12 +40,27 @@ include_directories( ${RSDK_INCLUDE_DIR} ${MODULE_DIR}/src/contentfilter/cpp/) -# Build contentfilter without JNI -add_library("contentfilter" STATIC ${CONTENTFILTER_SOURCES}) +# Link libraries used by LCP shared library +SET ( + LCP_LINK_LIBRARIES + "clientlib" + "contentfilter" + "${RSDK_LIB_DIR}/${ANDROID_ABI}/libepub3.so" +) +# Extra cmake called before build +if(EXISTS "${EXTRA_CMAKE}") + include(${EXTRA_CMAKE}) +endif() + +# Targets to build +add_library("clientlib" STATIC ${CLIENTLIB_ALL_SOURCES}) +add_library("lcp-min" SHARED ${CLIENTLIB_JNI_SOURCES}) +add_library("contentfilter" STATIC ${CONTENTFILTER_SOURCES}) add_library("lcp" SHARED ${CLIENTLIB_JNI_SOURCES} ${CONTENTFILTER_JNI_SOURCES}) -# Link to lcp-client-lib, lcp-content-filter and rsdk -target_link_libraries("lcp" "clientlib" "contentfilter" ${RSDK_LIB_DIR}/${ANDROID_ABI}/libepub3.so) +# Target links +target_link_libraries("lcp" ${LCP_LINK_LIBRARIES}) +target_link_libraries("lcp-min" "clientlib") diff --git a/platform/android/lib/build.gradle b/platform/android/lib/build.gradle index d0f60b8..a2828f9 100644 --- a/platform/android/lib/build.gradle +++ b/platform/android/lib/build.gradle @@ -16,7 +16,12 @@ def ndk_skipARM = (rootProject.hasProperty("readium_ndk_skipARM") && rootProject def ndk_clang = (rootProject.hasProperty("readium_ndk_clang") && rootProject.readium_ndk_clang) def readiumSdkLibDir = null def readiumSdkIncludeDir = null -def readiumLcpBuildContentFilter = false +def lcpBuildContentFilter = false +def extraCmake = null + +if (rootProject.hasProperty("readium_extra_cmake")) { + extraCmake = rootProject.readium_extra_cmake +} if (rootProject.hasProperty("readium_sdk_lib_dir")) { readiumSdkLibDir = rootProject.readium_sdk_lib_dir @@ -27,18 +32,18 @@ if (rootProject.hasProperty("readium_sdk_include_dir")) { } if (rootProject.hasProperty("readium_lcp_build_content_filter")) { - readiumLcpBuildContentFilter = rootProject.readium_lcp_build_content_filter + lcpBuildContentFilter = rootProject.readium_lcp_build_content_filter } - +println("Test ${extraCmake}") def toolchain = ndk_clang ? "clang" : "gcc" def stl = ndk_clang ? "c++_shared" : "gnustl_shared" -if (!readiumLcpBuildContentFilter) { +if (!lcpBuildContentFilter) { try { def epub3Dir = project(':epub3').projectDir readiumSdkLibDir = "${epub3Dir}/libs" readiumSdkIncludeDir = "${epub3Dir}/include" - readiumLcpBuildContentFilter = true + lcpBuildContentFilter = true } catch (UnknownProjectException e) { // No epub3 project is defined println("Build without rsdk") @@ -59,7 +64,7 @@ android { externalNativeBuild { cmake { - if (readiumLcpBuildContentFilter) { + if (lcpBuildContentFilter) { targets "clientlib", "contentfilter", "lcp" } else { targets "clientlib", "lcp-min" @@ -69,13 +74,14 @@ android { "-DANDROID_TOOLCHAIN=${toolchain}", "-DANDROID_STL=${stl}", "-DRSDK_INCLUDE_DIR=${readiumSdkIncludeDir}", - "-DRSDK_LIB_DIR=${readiumSdkLibDir}" + "-DRSDK_LIB_DIR=${readiumSdkLibDir}", + "-DEXTRA_CMAKE=${extraCmake}" } } } sourceSets { - if (readiumLcpBuildContentFilter) { + if (lcpBuildContentFilter) { main { java { srcDirs = [ diff --git a/platform/android/lib/clientlib.cmake b/platform/android/lib/clientlib.cmake index 8f0cf0d..6497178 100644 --- a/platform/android/lib/clientlib.cmake +++ b/platform/android/lib/clientlib.cmake @@ -22,7 +22,6 @@ file(GLOB ZIPLIB_SOURCES # Time64 file(GLOB_RECURSE TIME64_SOURCES ${THIRDPARTY_DIR}/time64/*.c) - # Client lib file(GLOB CLIENTLIB_SOURCES ${CLIENTLIB_DIR}/*.cpp) From 213a8464e946d8a33f431c01232fd9b91749ca99 Mon Sep 17 00:00:00 2001 From: danielweck Date: Thu, 11 May 2017 10:27:26 +0100 Subject: [PATCH 15/42] removed unnecssary helper include --- platform/android/lcp/src/main/jni/NetProvider.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/android/lcp/src/main/jni/NetProvider.cpp b/platform/android/lcp/src/main/jni/NetProvider.cpp index 2bbb7ac..c305758 100644 --- a/platform/android/lcp/src/main/jni/NetProvider.cpp +++ b/platform/android/lcp/src/main/jni/NetProvider.cpp @@ -26,7 +26,6 @@ #if !DISABLE_NET_PROVIDER -#include #include "NetProvider.h" #include "BaseDownloadRequest.h" @@ -82,11 +81,15 @@ JNIEXPORT void JNICALL Java_org_readium_sdk_lcp_NetProviderCallback_nativeOnRequ JNIEnv *env, jobject obj, jlong callbackPtr, jlong requestPtr, jstring path) { lcp::INetProviderCallback * callback = (lcp::INetProviderCallback *) callbackPtr; lcp::IDownloadRequest * request = (lcp::IDownloadRequest *) requestPtr; + + // This is a hack, see TODO above in StartDownloadRequest() (Java/JNI NetProvider only supports download-to-file, not memory stream!) lcp::BaseDownloadRequest* request_ = dynamic_cast(request); if (request_) { const char *path_ = env->GetStringUTFChars(path, 0); request_->SetSuggestedFileName(std::string(path_)); } + + lcp::Status status(lcp::StatusCode::ErrorCommonSuccess); callback->OnRequestEnded(request, status); } From 4c25c44b12b449e55a6c6b1b9d6ff0be530a6241 Mon Sep 17 00:00:00 2001 From: danielweck Date: Thu, 11 May 2017 15:01:56 +0100 Subject: [PATCH 16/42] support for legacy user key passphrase hash --- src/lcp-client-lib/CryptoppCryptoProvider.cpp | 28 ++++++++- src/lcp-client-lib/CryptoppCryptoProvider.h | 14 +++-- src/lcp-client-lib/ICryptoProvider.h | 14 +++-- src/lcp-client-lib/LcpService.cpp | 57 +++++++++++++------ src/lcp-client-lib/LcpService.h | 2 +- 5 files changed, 85 insertions(+), 30 deletions(-) diff --git a/src/lcp-client-lib/CryptoppCryptoProvider.cpp b/src/lcp-client-lib/CryptoppCryptoProvider.cpp index a295bc0..8432a0b 100644 --- a/src/lcp-client-lib/CryptoppCryptoProvider.cpp +++ b/src/lcp-client-lib/CryptoppCryptoProvider.cpp @@ -212,10 +212,27 @@ namespace lcp } } + Status CryptoppCryptoProvider::LegacyPassphraseUserKey( + const KeyType & userKey1, + KeyType & userKey2 + ) + { + try + { + userKey2 = userKey1; // noop + return Status(StatusCode::ErrorCommonSuccess); + } + catch (const std::exception & ex) + { + return Status(StatusCode::ErrorDecryptionUserPassphraseNotValid, "ErrorDecryptionUserPassphraseNotValid: " + std::string(ex.what())); + } + } + Status CryptoppCryptoProvider::DecryptUserKey( const std::string & userPassphrase, ILicense * license, - KeyType & userKey + KeyType & userKey1, + KeyType & userKey2 ) { try @@ -232,13 +249,18 @@ namespace lcp std::unique_ptr hashAlgorithm(profile->CreateUserKeyAlgorithm()); hashAlgorithm->UpdateHash(userPassphrase); - userKey = hashAlgorithm->Hash(); + userKey1 = hashAlgorithm->Hash(); + + Status resx = this->LegacyPassphraseUserKey(userKey1, userKey2); + if (!Status::IsSuccess(resx)) { + return resx; + } //http://www.w3.org/2009/xmlenc11#aes256-gcm //http://www.w3.org/2001/04/xmlenc#aes256-cbc const std::string algorithm = license->Crypto()->ContentKeyAlgorithm(); - std::unique_ptr contentKeyAlgorithm(profile->CreateContentKeyAlgorithm(userKey, algorithm)); + std::unique_ptr contentKeyAlgorithm(profile->CreateContentKeyAlgorithm(userKey2, algorithm)); std::string id = contentKeyAlgorithm->Decrypt(license->Crypto()->UserKeyCheck()); if (!EqualsUtf8(id, license->Id())) { diff --git a/src/lcp-client-lib/CryptoppCryptoProvider.h b/src/lcp-client-lib/CryptoppCryptoProvider.h index 0b802cd..621aea0 100644 --- a/src/lcp-client-lib/CryptoppCryptoProvider.h +++ b/src/lcp-client-lib/CryptoppCryptoProvider.h @@ -76,10 +76,16 @@ class ICertificateRevocationList; ); virtual Status DecryptUserKey( - const std::string & userPassphrase, - ILicense * license, - KeyType & userKey - ); + const std::string & userPassphrase, + ILicense * license, + KeyType & userKey1, + KeyType & userKey2 + ); + + virtual Status LegacyPassphraseUserKey( + const KeyType & userKey1, + KeyType & userKey2 + ); virtual Status DecryptContentKey( const KeyType & userKey, diff --git a/src/lcp-client-lib/ICryptoProvider.h b/src/lcp-client-lib/ICryptoProvider.h index bd72a59..6a51bac 100644 --- a/src/lcp-client-lib/ICryptoProvider.h +++ b/src/lcp-client-lib/ICryptoProvider.h @@ -49,10 +49,16 @@ namespace lcp virtual Status CheckRevokation(ILicense* license) = 0; virtual Status DecryptUserKey( - const std::string & userPassphrase, - ILicense * license, - KeyType & userKey - ) = 0; + const std::string & userPassphrase, + ILicense * license, + KeyType & userKey1, + KeyType & userKey2 + ) = 0; + + virtual Status LegacyPassphraseUserKey( + const KeyType & userKey1, + KeyType & userKey2 + ) = 0; virtual Status DecryptContentKey( const KeyType & userKey, diff --git a/src/lcp-client-lib/LcpService.cpp b/src/lcp-client-lib/LcpService.cpp index 870797e..8befc60 100644 --- a/src/lcp-client-lib/LcpService.cpp +++ b/src/lcp-client-lib/LcpService.cpp @@ -223,9 +223,7 @@ namespace lcp Status result = Status(StatusCode::ErrorCommonSuccess); - if ( - false && // TODO comment this! => skips the decryption attempt (from stored passphrase) at first-time load, to test the user prompt - !license->Decrypted()) + if (!license->Decrypted()) // false && // TODO comment this! => skips the decryption attempt (from stored passphrase) at first-time load, to test the user prompt { result = this->DecryptLicenseOnOpening(license); @@ -338,16 +336,17 @@ namespace lcp throw std::invalid_argument("license is nullptr"); } - KeyType userKey; - Status res = m_cryptoProvider->DecryptUserKey(userPassphrase, license, userKey); + KeyType userKey1; + KeyType userKey2; + Status res = m_cryptoProvider->DecryptUserKey(userPassphrase, license, userKey1, userKey2); if (!Status::IsSuccess(res)) return res; - res = this->DecryptLicenseByUserKey(license, userKey); + res = this->DecryptLicenseByUserKey(license, userKey2); if (!Status::IsSuccess(res)) return res; - return this->AddDecryptedUserKey(license, userKey); + return this->AddDecryptedUserKey(license, userKey1); } catch (const StatusException & ex) { @@ -371,15 +370,15 @@ namespace lcp rootNode->SetKeyProvider(std::unique_ptr(new SimpleKeyProvider(userKey, contentKey))); return rootNode->DecryptNode(license, rootNode, m_cryptoProvider.get()); } - - Status LcpService::DecryptLicenseByHexUserKey(ILicense * license, const std::string & hexUserKey) - { - KeyType userKey; - Status res = m_cryptoProvider->ConvertHexToRaw(hexUserKey, userKey); - if (!Status::IsSuccess(res)) - return res; - return this->DecryptLicenseByUserKey(license, userKey); - } +// +// Status LcpService::DecryptLicenseByHexUserKey(ILicense * license, const std::string & hexUserKey) +// { +// KeyType userKey; +// Status res = m_cryptoProvider->ConvertHexToRaw(hexUserKey, userKey); +// if (!Status::IsSuccess(res)) +// return res; +// return this->DecryptLicenseByUserKey(license, userKey); +// } Status LcpService::DecryptLicenseOnOpening(ILicense * license) { @@ -421,7 +420,17 @@ namespace lcp ); if (!userKeyHex.empty()) { - Status res = this->DecryptLicenseByHexUserKey(license, userKeyHex); + KeyType userKey1; + Status res = m_cryptoProvider->ConvertHexToRaw(userKeyHex, userKey1); + if (!Status::IsSuccess(res)) + return res; + + KeyType userKey2; + res = m_cryptoProvider->LegacyPassphraseUserKey(userKey1, userKey2); + if (!Status::IsSuccess(res)) + return res; + + res = this->DecryptLicenseByUserKey(license, userKey2); if (Status::IsSuccess(res)) { return res; } @@ -430,7 +439,19 @@ namespace lcp std::unique_ptr it(m_storageProvider->EnumerateVault(UserKeysVaultId)); for (it->First(); !it->IsDone(); it->Next()) { - Status res = this->DecryptLicenseByHexUserKey(license, it->Current()); + std::string userKeyHex = it->Current(); + + KeyType userKey1; + Status res = m_cryptoProvider->ConvertHexToRaw(userKeyHex, userKey1); + if (!Status::IsSuccess(res)) + continue; + + KeyType userKey2; + res = m_cryptoProvider->LegacyPassphraseUserKey(userKey1, userKey2); + if (!Status::IsSuccess(res)) + continue; + + res = this->DecryptLicenseByUserKey(license, userKey2); if (Status::IsSuccess(res)) return res; } diff --git a/src/lcp-client-lib/LcpService.h b/src/lcp-client-lib/LcpService.h index b3219fa..af01a15 100644 --- a/src/lcp-client-lib/LcpService.h +++ b/src/lcp-client-lib/LcpService.h @@ -131,7 +131,7 @@ namespace lcp Status DecryptLicenseOnOpening(ILicense * license); Status DecryptLicenseByUserKey(ILicense * license, const KeyType & userKey); - Status DecryptLicenseByHexUserKey(ILicense * license, const std::string & hexUserKey); +// Status DecryptLicenseByHexUserKey(ILicense * license, const std::string & hexUserKey); Status DecryptLicenseByStorage(ILicense * license); Status AddDecryptedUserKey(ILicense * license, const KeyType & userKey); From 2687fa9e3d7e71be320c3ba3146af05f6447fddf Mon Sep 17 00:00:00 2001 From: danielweck Date: Thu, 11 May 2017 15:16:11 +0100 Subject: [PATCH 17/42] minor fix --- src/lcp-client-lib/CryptoppCryptoProvider.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lcp-client-lib/CryptoppCryptoProvider.cpp b/src/lcp-client-lib/CryptoppCryptoProvider.cpp index 8432a0b..5db7485 100644 --- a/src/lcp-client-lib/CryptoppCryptoProvider.cpp +++ b/src/lcp-client-lib/CryptoppCryptoProvider.cpp @@ -219,7 +219,8 @@ namespace lcp { try { - userKey2 = userKey1; // noop + userKey2.assign(userKey1.begin(), userKey1.end()); + return Status(StatusCode::ErrorCommonSuccess); } catch (const std::exception & ex) From adb20d14855375dd829e262c4cc05b5c225e2b28 Mon Sep 17 00:00:00 2001 From: danielweck Date: Thu, 11 May 2017 17:10:26 +0100 Subject: [PATCH 18/42] NetProvider compatible iOS ANdroid --- src/lcp-client-lib/CrlUpdater.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lcp-client-lib/CrlUpdater.cpp b/src/lcp-client-lib/CrlUpdater.cpp index 1ad0b34..c9347b8 100644 --- a/src/lcp-client-lib/CrlUpdater.cpp +++ b/src/lcp-client-lib/CrlUpdater.cpp @@ -154,7 +154,7 @@ namespace lcp m_requestRunning = true; #if !DISABLE_CRL_DOWNLOAD_IN_MEMORY - m_crlStream.reset(new SimpleMemoryWritableStream()); // not actually used! (NetProvider Java operates on File) + m_crlStream.reset(new SimpleMemoryWritableStream()); // not actually used with NetProvider Java which operates on File only :( m_downloadRequest.reset(new DownloadInMemoryRequest(url, m_crlStream.get())); #else // !DISABLE_CRL_DOWNLOAD_IN_MEMORY m_crlFile.reset(m_fileSystemProvider->GetFile(PATH_TO_DOWNLOAD)); @@ -198,7 +198,7 @@ namespace lcp lcp::BaseDownloadRequest* request_ = dynamic_cast(request); if (request_) { std::string path = request_->SuggestedFileName(); - if (path.length()) { + if (path.length() && path.at(0) == '/') { // SUPER HACKY!! (because Android NetProvider only handles file download) IFile* file = m_fileSystemProvider->GetFile(path, IFileSystemProvider::ReadOnly); size_t bufferSize = 1024 * 1024; @@ -217,9 +217,10 @@ namespace lcp delete file; m_revocationList->UpdateRevocationList(buffer); //std::vector + } else { + m_revocationList->UpdateRevocationList(m_crlStream->Buffer()); //std::vector } } - // m_revocationList->UpdateRevocationList(m_crlStream->Buffer()); //std::vector #else // !DISABLE_CRL_DOWNLOAD_IN_MEMORY // IFile == IReadableStream @@ -286,4 +287,4 @@ namespace lcp } } -#endif //!DISABLE_CRL \ No newline at end of file +#endif //!DISABLE_CRL From 857197a48703658dc181eee65811ea02e9c6dd92 Mon Sep 17 00:00:00 2001 From: Cyrille Lebeaupin Date: Mon, 29 May 2017 16:14:08 +0200 Subject: [PATCH 19/42] Fix include --- src/lcp-client-lib/CrlUpdater.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lcp-client-lib/CrlUpdater.h b/src/lcp-client-lib/CrlUpdater.h index f603e91..e403978 100644 --- a/src/lcp-client-lib/CrlUpdater.h +++ b/src/lcp-client-lib/CrlUpdater.h @@ -46,7 +46,7 @@ #include "SimpleMemoryWritableStream.h" #endif // !DISABLE_CRL_DOWNLOAD_IN_MEMORY -#include "IFileSystemProvider.h" +#include "public/IFileSystemProvider.h" namespace lcp { From 7808a886411a352d4b625db46817a1147a67f43a Mon Sep 17 00:00:00 2001 From: Cyrille Lebeaupin Date: Mon, 29 May 2017 16:18:52 +0200 Subject: [PATCH 20/42] Add cross platform based on gyp and ninja build engine --- .gitignore | 6 +- platform/cross-platform/README.md | 22 +++ platform/cross-platform/bootstrap.py | 76 +++++++++ platform/cross-platform/build.py | 45 +++++ platform/cross-platform/filenames.gypi | 219 +++++++++++++++++++++++++ platform/cross-platform/lcp.gyp | 205 +++++++++++++++++++++++ platform/cross-platform/utils.py | 12 ++ 7 files changed, 584 insertions(+), 1 deletion(-) create mode 100644 platform/cross-platform/README.md create mode 100644 platform/cross-platform/bootstrap.py create mode 100644 platform/cross-platform/build.py create mode 100644 platform/cross-platform/filenames.gypi create mode 100644 platform/cross-platform/lcp.gyp create mode 100644 platform/cross-platform/utils.py diff --git a/.gitignore b/.gitignore index 560b024..1529fb6 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.lo *.o *.obj +*.pyc # Precompiled Headers *.gch @@ -43,6 +44,9 @@ bld/ ipch/ .vs/ +# cross-platform +platform/cross-platform/out +platform/cross-platform/vendor # Windows Thumbs.db @@ -69,4 +73,4 @@ result.epub *.iml -platform/android/lcp/libs/ \ No newline at end of file +platform/android/lcp/libs/ diff --git a/platform/cross-platform/README.md b/platform/cross-platform/README.md new file mode 100644 index 0000000..74de9d3 --- /dev/null +++ b/platform/cross-platform/README.md @@ -0,0 +1,22 @@ +# Cross platform compilation + +## Bootstrap + +``` +python bootstrap.py +``` + +## Compile + +``` +python build.py +``` + +This build generates static libraries in out/Default/obj directory: + +* liblcp_client.a +* liblcp_content_filter.a +* libbzip2.a +* libzlib.a +* libcryptopp.a +* libtime64.a diff --git a/platform/cross-platform/bootstrap.py b/platform/cross-platform/bootstrap.py new file mode 100644 index 0000000..06b4ce8 --- /dev/null +++ b/platform/cross-platform/bootstrap.py @@ -0,0 +1,76 @@ +#!/usr/bin/python +import os +import shutil +import platform +import utils +import urllib +import zipfile +import tarfile +import tempfile +import subprocess + +# Other variables +SYSTEM = platform.system().lower() + +if SYSTEM == "darwin": + SYSTEM = "mac" + +# Install gyp +def install_gyp(): + if os.path.exists(os.path.join("vendor", "gyp")): + return + + print "Clone gyp" + utils.execute_command(["git", "clone", "https://chromium.googlesource.com/external/gyp.git", "vendor/gyp"]) + +# Install ninja +def install_ninja(): + if not os.path.exists(os.path.join("vendor", "ninja")): + print "Clone ninja" + utils.execute_command(["git", "clone", "https://github.com/ninja-build/ninja.git", "vendor/ninja"]) + + # Configure and build ninja + if SYSTEM == "windows": + cmd_path = (os.path.join("vendor", "ninja", "ninja.exe")) + else: + cmd_path = (os.path.join("vendor", "ninja", "ninja")) + + if not os.path.exists(cmd_path): + print "Build and install ninja" + + # Initialize visual studio environment variables + cmd = ["python", "configure.py", "--bootstrap"] + + if SYSTEM == "windows": + cmd = ["vcvarsall.bat", "&&"] + cmd + + utils.execute_command(cmd, os.path.join("vendor", "ninja")) + +# Apply patches +def apply_patches(): + patch_file_path = os.path.abspath(os.path.join("patches", "%s.diff" % SYSTEM)) + + if not os.path.exists(patch_file_path): + return + + print "Apply patches" + cmd = ["git", "apply"] + + # Add options for windows to manage spaces + if SYSTEM == "windows": + cmd += ["--ignore-space-change", "--ignore-whitespace"] + + cmd += [patch_file_path] + + utils.execute_command(cmd, os.path.join("..", "..")) + +# Download and install vendors +if not os.path.exists("vendor"): + os.mkdir("vendor") + +install_gyp() +install_ninja() + +# Apply patches +apply_patches() + diff --git a/platform/cross-platform/build.py b/platform/cross-platform/build.py new file mode 100644 index 0000000..9316a49 --- /dev/null +++ b/platform/cross-platform/build.py @@ -0,0 +1,45 @@ +#!/usr/bin/python +import os +import subprocess +import platform +import utils + +SYSTEM = platform.system().lower() + +if SYSTEM == "linux": + # Use clang on linux + # print "Use clang compiler" + # os.environ["CC"] = "clang" + # os.environ["CXX"] = "clang++" + # os.environ["GYP_DEFINES"] = "clang=1" + GYP_OS = "linux" +elif SYSTEM == "windows": + # Use msvs version 2015 + print "Use msvs version 2015" + os.environ["GYP_MSVS_VERSION"] = "2015" + GYP_OS = "win" +elif SYSTEM == "darwin": + GYP_OS = "mac" + +# Directories variables +PPAPI_PATH = os.path.abspath(os.getcwd()) +GYP_CMD = os.path.join(PPAPI_PATH, "vendor", "gyp", "gyp_main.py") +NINJA_PATH = os.path.join(PPAPI_PATH, "vendor", "ninja") + +if SYSTEM == "windows": + NINJA_CMD = os.path.join(NINJA_PATH, "ninja.exe") +else: + NINJA_CMD = os.path.join(NINJA_PATH, "ninja") + +# Create ninja build file +print "Create ninja project" +utils.execute_command(["python", GYP_CMD, "--depth=.", "-f", "ninja", "-DOS=%s" % GYP_OS, "lcp.gyp"]) + +# Build ninja project +print "Build ninja project" +cmd = [NINJA_CMD, "-C", os.path.join("out", "Default"), "-f", "build.ninja"] + +if SYSTEM == "windows": + cmd = ["vcvarsall.bat", "&&"] + cmd + +utils.execute_command(cmd) \ No newline at end of file diff --git a/platform/cross-platform/filenames.gypi b/platform/cross-platform/filenames.gypi new file mode 100644 index 0000000..0298447 --- /dev/null +++ b/platform/cross-platform/filenames.gypi @@ -0,0 +1,219 @@ +{ + 'variables': { + 'root_dir': '../../src', + 'third_party_dir': '<(root_dir)/third-parties', + 'lcp_content_filter_dir': '<(root_dir)/lcp-content-filter', + 'lcp_client_lib_dir': '<(root_dir)/lcp-client-lib', + 'cryptopp_dir': '<(third_party_dir)/cryptopp', + 'zip_lib_dir': '<(third_party_dir)/ziplib/Source/ZipLib', + 'zlib_dir': '<(zip_lib_dir)/extlibs/zlib', + 'bzip2_dir': '<(zip_lib_dir)/extlibs/bzip2', + 'time64_dir': '<(third_party_dir)/time64', + 'zlib_sources': [ + '<(zlib_dir)/compress.c', + '<(zlib_dir)/zutil.c', + '<(zlib_dir)/trees.c', + '<(zlib_dir)/inftrees.c', + '<(zlib_dir)/inffast.c', + '<(zlib_dir)/crc32.c', + '<(zlib_dir)/inflate.c', + '<(zlib_dir)/uncompr.c', + '<(zlib_dir)/adler32.c', + '<(zlib_dir)/infback.c', + '<(zlib_dir)/deflate.c' + ], + 'bzip2_sources': [ + '<(bzip2_dir)/blocksort.c', + '<(bzip2_dir)/bzerror.c', + '<(bzip2_dir)/bzlib.c', + '<(bzip2_dir)/compress.c', + '<(bzip2_dir)/crctable.c', + '<(bzip2_dir)/decompress.c', + '<(bzip2_dir)/huffman.c', + '<(bzip2_dir)/randtable.c', + ], + 'zip_lib_sources': [ + '<(zip_lib_dir)/detail/EndOfCentralDirectoryBlock.cpp', + '<(zip_lib_dir)/detail/ZipCentralDirectoryFileHeader.cpp', + '<(zip_lib_dir)/detail/ZipGenericExtraField.cpp', + '<(zip_lib_dir)/detail/ZipLocalFileHeader.cpp', + '<(zip_lib_dir)/ZipArchive.cpp', + '<(zip_lib_dir)/ZipArchiveEntry.cpp', + '<(zip_lib_dir)/ZipFile.cpp' + ], + 'time64_sources': [ + '<(time64_dir)/time64.c' + ], + 'cryptopp_sources': [ + '<(cryptopp_dir)/3way.cpp', + '<(cryptopp_dir)/adhoc.cpp', + '<(cryptopp_dir)/adler32.cpp', + '<(cryptopp_dir)/algebra.cpp', + '<(cryptopp_dir)/algparam.cpp', + '<(cryptopp_dir)/arc4.cpp', + '<(cryptopp_dir)/asn.cpp', + '<(cryptopp_dir)/authenc.cpp', + '<(cryptopp_dir)/base32.cpp', + '<(cryptopp_dir)/base64.cpp', + '<(cryptopp_dir)/basecode.cpp', + '<(cryptopp_dir)/bench2.cpp', + '<(cryptopp_dir)/bench.cpp', + '<(cryptopp_dir)/bfinit.cpp', + '<(cryptopp_dir)/blowfish.cpp', + '<(cryptopp_dir)/blumshub.cpp', + '<(cryptopp_dir)/camellia.cpp', + '<(cryptopp_dir)/cast.cpp', + '<(cryptopp_dir)/casts.cpp', + '<(cryptopp_dir)/cbcmac.cpp', + '<(cryptopp_dir)/ccm.cpp', + '<(cryptopp_dir)/channels.cpp', + '<(cryptopp_dir)/cmac.cpp', + '<(cryptopp_dir)/cpu.cpp', + '<(cryptopp_dir)/crc.cpp', + '<(cryptopp_dir)/cryptlib_bds.cpp', + '<(cryptopp_dir)/cryptlib.cpp', + '<(cryptopp_dir)/datatest.cpp', + '<(cryptopp_dir)/default.cpp', + '<(cryptopp_dir)/des.cpp', + '<(cryptopp_dir)/dessp.cpp', + '<(cryptopp_dir)/dh2.cpp', + '<(cryptopp_dir)/dh.cpp', + '<(cryptopp_dir)/dll.cpp', + '<(cryptopp_dir)/dlltest.cpp', + '<(cryptopp_dir)/dsa.cpp', + '<(cryptopp_dir)/eax.cpp', + '<(cryptopp_dir)/ec2n.cpp', + '<(cryptopp_dir)/eccrypto.cpp', + '<(cryptopp_dir)/ecp.cpp', + '<(cryptopp_dir)/elgamal.cpp', + '<(cryptopp_dir)/emsa2.cpp', + '<(cryptopp_dir)/eprecomp.cpp', + '<(cryptopp_dir)/esign.cpp', + '<(cryptopp_dir)/files.cpp', + '<(cryptopp_dir)/filters.cpp', + '<(cryptopp_dir)/fips140.cpp', + '<(cryptopp_dir)/fipsalgt.cpp', + '<(cryptopp_dir)/fipstest.cpp', + '<(cryptopp_dir)/gcm.cpp', + '<(cryptopp_dir)/gf2_32.cpp', + '<(cryptopp_dir)/gf256.cpp', + '<(cryptopp_dir)/gf2n.cpp', + '<(cryptopp_dir)/gfpcrypt.cpp', + '<(cryptopp_dir)/gost.cpp', + '<(cryptopp_dir)/gzip.cpp', + '<(cryptopp_dir)/hex.cpp', + '<(cryptopp_dir)/hmac.cpp', + '<(cryptopp_dir)/hrtimer.cpp', + '<(cryptopp_dir)/ida.cpp', + '<(cryptopp_dir)/idea.cpp', + '<(cryptopp_dir)/integer.cpp', + '<(cryptopp_dir)/iterhash.cpp', + '<(cryptopp_dir)/luc.cpp', + '<(cryptopp_dir)/mars.cpp', + '<(cryptopp_dir)/marss.cpp', + '<(cryptopp_dir)/md2.cpp', + '<(cryptopp_dir)/md4.cpp', + '<(cryptopp_dir)/md5.cpp', + '<(cryptopp_dir)/misc.cpp', + '<(cryptopp_dir)/modes.cpp', + '<(cryptopp_dir)/mqueue.cpp', + '<(cryptopp_dir)/mqv.cpp', + '<(cryptopp_dir)/nbtheory.cpp', + '<(cryptopp_dir)/network.cpp', + '<(cryptopp_dir)/oaep.cpp', + '<(cryptopp_dir)/osrng.cpp', + '<(cryptopp_dir)/panama.cpp', + '<(cryptopp_dir)/pch.cpp', + '<(cryptopp_dir)/pkcspad.cpp', + '<(cryptopp_dir)/polynomi.cpp', + '<(cryptopp_dir)/pssr.cpp', + '<(cryptopp_dir)/pubkey.cpp', + '<(cryptopp_dir)/queue.cpp', + '<(cryptopp_dir)/rabin.cpp', + '<(cryptopp_dir)/randpool.cpp', + '<(cryptopp_dir)/rc2.cpp', + '<(cryptopp_dir)/rc5.cpp', + '<(cryptopp_dir)/rc6.cpp', + '<(cryptopp_dir)/rdtables.cpp', + '<(cryptopp_dir)/regtest.cpp', + '<(cryptopp_dir)/rijndael.cpp', + '<(cryptopp_dir)/ripemd.cpp', + '<(cryptopp_dir)/rng.cpp', + '<(cryptopp_dir)/rsa.cpp', + '<(cryptopp_dir)/rw.cpp', + '<(cryptopp_dir)/safer.cpp', + '<(cryptopp_dir)/salsa.cpp', + '<(cryptopp_dir)/seal.cpp', + '<(cryptopp_dir)/seed.cpp', + '<(cryptopp_dir)/serpent.cpp', + '<(cryptopp_dir)/sha3.cpp', + '<(cryptopp_dir)/shacal2.cpp', + '<(cryptopp_dir)/sha.cpp', + '<(cryptopp_dir)/sharkbox.cpp', + '<(cryptopp_dir)/shark.cpp', + '<(cryptopp_dir)/simple.cpp', + '<(cryptopp_dir)/skipjack.cpp', + '<(cryptopp_dir)/socketft.cpp', + '<(cryptopp_dir)/sosemanuk.cpp', + '<(cryptopp_dir)/square.cpp', + '<(cryptopp_dir)/squaretb.cpp', + '<(cryptopp_dir)/strciphr.cpp', + '<(cryptopp_dir)/tea.cpp', + '<(cryptopp_dir)/test.cpp', + '<(cryptopp_dir)/tftables.cpp', + '<(cryptopp_dir)/tiger.cpp', + '<(cryptopp_dir)/tigertab.cpp', + '<(cryptopp_dir)/trdlocal.cpp', + '<(cryptopp_dir)/ttmac.cpp', + '<(cryptopp_dir)/twofish.cpp', + '<(cryptopp_dir)/validat1.cpp', + '<(cryptopp_dir)/validat2.cpp', + '<(cryptopp_dir)/validat3.cpp', + '<(cryptopp_dir)/vmac.cpp', + '<(cryptopp_dir)/wait.cpp', + '<(cryptopp_dir)/wake.cpp', + '<(cryptopp_dir)/whrlpool.cpp', + '<(cryptopp_dir)/winpipes.cpp', + '<(cryptopp_dir)/xtr.cpp', + '<(cryptopp_dir)/xtrcrypt.cpp', + '<(cryptopp_dir)/zdeflate.cpp', + '<(cryptopp_dir)/zinflate.cpp', + '<(cryptopp_dir)/zlib.cpp' + ], + 'lcp_client_lib_sources': [ + '<(lcp_client_lib_dir)/Acquisition.cpp', + '<(lcp_client_lib_dir)/AesCbcSymmetricAlgorithm.cpp', + '<(lcp_client_lib_dir)/AlgorithmNames.cpp', + '<(lcp_client_lib_dir)/Certificate.cpp', + '<(lcp_client_lib_dir)/CertificateExtension.cpp', + '<(lcp_client_lib_dir)/CertificateRevocationList.cpp', + '<(lcp_client_lib_dir)/CrlDistributionPoints.cpp', + '<(lcp_client_lib_dir)/CrlUpdater.cpp', + '<(lcp_client_lib_dir)/CryptoLcpNode.cpp', + '<(lcp_client_lib_dir)/CryptoppCryptoProvider.cpp', + '<(lcp_client_lib_dir)/CryptoppUtils.cpp', + '<(lcp_client_lib_dir)/DateTime.cpp', + '<(lcp_client_lib_dir)/EncryptionProfileNames.cpp', + '<(lcp_client_lib_dir)/EncryptionProfilesManager.cpp', + '<(lcp_client_lib_dir)/JsonCanonicalizer.cpp', + '<(lcp_client_lib_dir)/JsonValueReader.cpp', + '<(lcp_client_lib_dir)/Lcp1dot0EncryptionProfile.cpp', + '<(lcp_client_lib_dir)/LcpService.cpp', + '<(lcp_client_lib_dir)/LcpServiceCreator.cpp', + '<(lcp_client_lib_dir)/LcpUtils.cpp', + '<(lcp_client_lib_dir)/LinksLcpNode.cpp', + '<(lcp_client_lib_dir)/RightsLcpNode.cpp', + '<(lcp_client_lib_dir)/RightsService.cpp', + '<(lcp_client_lib_dir)/RootLcpNode.cpp', + '<(lcp_client_lib_dir)/RsaSha256SignatureAlgorithm.cpp', + '<(lcp_client_lib_dir)/Sha256HashAlgorithm.cpp', + '<(lcp_client_lib_dir)/SymmetricAlgorithmEncryptedStream.cpp', + '<(lcp_client_lib_dir)/ThreadTimer.cpp', + '<(lcp_client_lib_dir)/UserLcpNode.cpp' + ], + 'lcp_content_filter_sources': [ + '<(lcp_content_filter_dir)/LcpContentFilter.cpp', + '<(lcp_content_filter_dir)/LcpContentModule.cpp' + ] + } +} diff --git a/platform/cross-platform/lcp.gyp b/platform/cross-platform/lcp.gyp new file mode 100644 index 0000000..afcf7de --- /dev/null +++ b/platform/cross-platform/lcp.gyp @@ -0,0 +1,205 @@ +{ + 'includes': [ + 'filenames.gypi' + ], + 'variables': { + + }, + 'target_defaults': { + 'include_dirs': [ + + ], + 'cflags': [ + '-w', + '-fPIC', + '-fvisibility=hidden', + '-g', # Debug mode + ], + 'defines': [ + 'BUILDING_EPUB3' + ] + }, + 'targets': [ + { + 'target_name': 'lcp_content_filter', + 'type': 'static_library', + 'cflags_cc': [ + '-std=c++11' + ], + 'sources': [ + '<@(lcp_content_filter_sources)' + ] + }, + { + 'target_name': 'lcp_client_lib', + 'type': 'static_library', + 'dependencies': [ + 'cryptopp', + 'zip_lib', + 'time64' + ], + 'include_dirs': [ + '<(third_party_dir)' + ], + 'cflags_cc': [ + '-std=c++11' + ], + 'sources': [ + '<@(lcp_client_lib_sources)' + ] + }, + { + 'target_name': 'cryptopp', + 'type': 'static_library', + 'sources': [ + '<@(cryptopp_sources)' + ] + }, + { + 'target_name': 'zip_lib', + 'type': 'static_library', + 'dependencies': [ + 'zlib', + 'bzip2' + ], + 'cflags_cc': [ + '-std=c++11', + '-fpermissive' + ], + 'sources': [ + '<@(zip_lib_sources)' + ] + }, + { + 'target_name': 'zlib', + 'type': 'static_library', + 'sources': [ + '<@(zlib_sources)' + ] + }, + { + 'target_name': 'bzip2', + 'type': 'static_library', + 'sources': [ + '<@(bzip2_sources)' + ] + }, + { + 'target_name': 'time64', + 'type': 'static_library', + 'sources': [ + '<@(time64_sources)' + ] + } + ], + 'conditions': [ + ['OS=="mac"', { + 'target_defaults': { + 'defines': [ + 'LIBXML_THREAD_ENABLED', + 'CRYPTOPP_DISABLE_ASM', + 'ZLIB_ONLY' + ], + 'cflags_cc': [ + #'-std=c++0x', + #'-stdlib=libc++', + #'-Wtautological-pointer-compare', + #'-Wc++11-extensions' + ], + 'xcode_settings': { + 'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO', + #'MACOSX_DEPLOYMENT_TARGET': '10.8', + 'CLANG_CXX_LANGUAGE_STANDARD': 'gnu++0x', + 'CLANG_CXX_LIBRARY': 'libc++', + 'WARNING_CFLAGS': [ + '-Wno-unknown-warning-option', + '-Wno-parentheses-equality', + '-Wno-unused-function', + '-Wno-sometimes-uninitialized', + '-Wno-pointer-sign', + '-Wno-sign-compare', + '-Wno-string-plus-int', + '-Wno-unused-variable', + '-Wno-deprecated-declarations', + '-Wno-return-type', + '-Wno-gnu-folding-constant', + '-Wno-shift-negative-value', + '-Wno-tautological-pointer-compare', + '-Wno-inconsistent-missing-override', + '-Wno-empty-body', + '-Wno-uninitialized', + '-Wno-potentially-evaluated-expression' + ] + }, + 'ldflags': [ + + ], + 'link_settings': { + 'libraries': [ + + ] + } + } + }], + ['OS=="linux"', { + 'target_defaults': { + 'defines': [ + #'LIBXML_THREAD_ENABLED', + #'_GLIBCXX_USE_CXX11_ABI=0' # to avoid std::locale issue + ], + 'cflags': [ + '-m64', + '-march=x86-64', + ], + 'cflags_cc': [ + ], + 'ldflags': [ + '-m64', + ], + 'link_settings': { + 'libraries': [ + + ] + } + } + }], + ['OS=="win"', { + 'variables': { + }, + 'target_defaults': { + 'defines': [ + 'MSVS_VERSION_2015', + 'NDEBUG', + 'NOMINMAX', + 'WIN32' + ], + 'msvs_disabled_warnings': [ + 4530, + 4577, + 4028, + 4090 + ], + 'msvs_settings': { + 'VCCLCompilerTool': { + 'WarnAsError': 'false', + }, + }, + 'cflags': [ + '/EHsc' + ], + 'cflags_cc': [ + # '-std=c++11', + # '-fpermissive' + ], + 'include_dirs': [ + ], + 'link_settings': { + 'library_dirs': [ + ], + 'libraries': [ + ] + } + } + }], + ] +} diff --git a/platform/cross-platform/utils.py b/platform/cross-platform/utils.py new file mode 100644 index 0000000..b8e87da --- /dev/null +++ b/platform/cross-platform/utils.py @@ -0,0 +1,12 @@ +import subprocess +import os.path + +# Helper to execute command +def execute_command(cmd, cwd=None): + cwd_abs_path = None + + if cwd is not None: + cwd_abs_path = os.path.abspath(cwd) + + p = subprocess.Popen(cmd, cwd=cwd_abs_path) + p.wait() \ No newline at end of file From 60c185076d5fde6ede5f80a54d81159730824e14 Mon Sep 17 00:00:00 2001 From: Cyrille Lebeaupin Date: Mon, 29 May 2017 17:40:52 +0200 Subject: [PATCH 21/42] Add directives -frrti and -fexceptions to fix some errors during compilation --- platform/cross-platform/lcp.gyp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/platform/cross-platform/lcp.gyp b/platform/cross-platform/lcp.gyp index afcf7de..13aba20 100644 --- a/platform/cross-platform/lcp.gyp +++ b/platform/cross-platform/lcp.gyp @@ -42,7 +42,9 @@ '<(third_party_dir)' ], 'cflags_cc': [ - '-std=c++11' + '-std=c++11', + '-frtti', + '-fexceptions', ], 'sources': [ '<@(lcp_client_lib_sources)' @@ -51,6 +53,12 @@ { 'target_name': 'cryptopp', 'type': 'static_library', + 'cflags_cc': [ + '-std=c++11', + '-fpermissive', + '-frtti', + '-fexceptions', + ], 'sources': [ '<@(cryptopp_sources)' ] @@ -64,7 +72,9 @@ ], 'cflags_cc': [ '-std=c++11', - '-fpermissive' + '-fpermissive', + '-frtti', + '-fexceptions', ], 'sources': [ '<@(zip_lib_sources)' From ef08c704836374464afa680b0a3bf62b7a8b9bb3 Mon Sep 17 00:00:00 2001 From: danielweck Date: Tue, 30 May 2017 14:42:38 +0100 Subject: [PATCH 22/42] latest Gradle version --- platform/android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/android/build.gradle b/platform/android/build.gradle index e606cd0..21fe9f7 100644 --- a/platform/android/build.gradle +++ b/platform/android/build.gradle @@ -35,7 +35,7 @@ buildscript { } //https://bintray.com/android/android-tools/com.android.tools.build.gradle/view - classpath "com.android.tools.build:gradle:2.3.1" + classpath "com.android.tools.build:gradle:2.3.2" } } From cb57305ea67f19878a245fc485f2a99beddbbd6c Mon Sep 17 00:00:00 2001 From: danielweck Date: Tue, 30 May 2017 14:44:12 +0100 Subject: [PATCH 23/42] re-instated ReadiumSDK error handler messaging, for builds with FEATURES_READIUM --- platform/android/lib/CMakeLists.txt | 6 ++++- platform/android/lib/build.gradle | 22 +++++++++++++------ .../android/lib/src/clientlib/cpp/Service.cpp | 12 +++++++--- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/platform/android/lib/CMakeLists.txt b/platform/android/lib/CMakeLists.txt index 2d617d4..320cfb0 100644 --- a/platform/android/lib/CMakeLists.txt +++ b/platform/android/lib/CMakeLists.txt @@ -17,6 +17,10 @@ include(${PROJECT_DIR}/lib/clientlib.cmake) # and just use it with the following line include(${PROJECT_DIR}/lib/ndk-stl-config.cmake) +if("${FEATURES_READIUM}") + add_definitions("-DFEATURES_READIUM") +endif() + # Compiler options add_definitions("-DZLIB_ONLY") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -fpic -frtti -fexceptions -fpermissive -Wall") @@ -31,7 +35,7 @@ include_directories( file(GLOB CLIENTLIB_JNI_SOURCES ${MODULE_DIR}/src/clientlib/cpp/*.cpp) # LCP with content filter -add_definitions("-DFEATURES_READIUM -DREADIUM_GCC") +add_definitions("-DREADIUM_GCC") include(${PROJECT_DIR}/lib/contentfilter.cmake) file(GLOB CONTENTFILTER_JNI_SOURCES ${MODULE_DIR}/src/contentfilter/cpp/*.cpp) include_directories( diff --git a/platform/android/lib/build.gradle b/platform/android/lib/build.gradle index a2828f9..c59a800 100644 --- a/platform/android/lib/build.gradle +++ b/platform/android/lib/build.gradle @@ -66,16 +66,24 @@ android { cmake { if (lcpBuildContentFilter) { targets "clientlib", "contentfilter", "lcp" + + arguments "-DFEATURES_READIUM=1", + "-DANDROID_PLATFORM=android-19", + "-DANDROID_TOOLCHAIN=${toolchain}", + "-DANDROID_STL=${stl}", + "-DRSDK_INCLUDE_DIR=${readiumSdkIncludeDir}", + "-DRSDK_LIB_DIR=${readiumSdkLibDir}", + "-DEXTRA_CMAKE=${extraCmake}" } else { targets "clientlib", "lcp-min" - } - arguments "-DANDROID_PLATFORM=android-19", - "-DANDROID_TOOLCHAIN=${toolchain}", - "-DANDROID_STL=${stl}", - "-DRSDK_INCLUDE_DIR=${readiumSdkIncludeDir}", - "-DRSDK_LIB_DIR=${readiumSdkLibDir}", - "-DEXTRA_CMAKE=${extraCmake}" + arguments "-DANDROID_PLATFORM=android-19", + "-DANDROID_TOOLCHAIN=${toolchain}", + "-DANDROID_STL=${stl}", + "-DRSDK_INCLUDE_DIR=${readiumSdkIncludeDir}", + "-DRSDK_LIB_DIR=${readiumSdkLibDir}", + "-DEXTRA_CMAKE=${extraCmake}" + } } } } diff --git a/platform/android/lib/src/clientlib/cpp/Service.cpp b/platform/android/lib/src/clientlib/cpp/Service.cpp index c750a94..d49d78f 100644 --- a/platform/android/lib/src/clientlib/cpp/Service.cpp +++ b/platform/android/lib/src/clientlib/cpp/Service.cpp @@ -30,7 +30,9 @@ #include #include -//extern "C" jboolean javaEPub3_handleSdkError(JNIEnv *env, jstring message, jboolean isSevereEpubError); +#if FEATURES_READIUM +extern "C" jboolean javaEPub3_handleSdkError(JNIEnv *env, jstring message, jboolean isSevereEpubError); +#endif //extern "C" jstring toJstring(JNIEnv *env, const char* str, bool freeNative = false); @@ -87,18 +89,22 @@ JNIEXPORT jobject JNICALL Java_org_readium_sdk_lcp_Service_nativeOpenLicense( if (!lcp::Status::IsSuccess(status)) { +#if FEATURES_READIUM //jstring test = toJstring(env, "test", false); jstring jmessage = env->NewStringUTF(lcp::Status::ToString(status).c_str()); - //jboolean b = javaEPub3_handleSdkError(env, jmessage, (jboolean)true); + jboolean b = javaEPub3_handleSdkError(env, jmessage, (jboolean)true); env->DeleteLocalRef(jmessage); +#endif return nullptr; } } catch (lcp::StatusException &ex) { +#if FEATURES_READIUM jstring jmessage = env->NewStringUTF(ex.what()); - //jboolean b = javaEPub3_handleSdkError(env, jmessage, (jboolean)true); + jboolean b = javaEPub3_handleSdkError(env, jmessage, (jboolean)true); env->DeleteLocalRef(jmessage); +#endif return nullptr; } From 40e53ad3c1435cb80a596387bab15cd7ef4c95bd Mon Sep 17 00:00:00 2001 From: danielweck Date: Thu, 28 Sep 2017 11:36:13 +0100 Subject: [PATCH 24/42] updated Android Studio / Gradle / SDK dependencies (versions) --- platform/android/build.gradle | 2 +- platform/android/lib/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/android/build.gradle b/platform/android/build.gradle index 21fe9f7..10e11e7 100644 --- a/platform/android/build.gradle +++ b/platform/android/build.gradle @@ -35,7 +35,7 @@ buildscript { } //https://bintray.com/android/android-tools/com.android.tools.build.gradle/view - classpath "com.android.tools.build:gradle:2.3.2" + classpath "com.android.tools.build:gradle:2.3.3" } } diff --git a/platform/android/lib/build.gradle b/platform/android/lib/build.gradle index c59a800..e718831 100644 --- a/platform/android/lib/build.gradle +++ b/platform/android/lib/build.gradle @@ -54,7 +54,7 @@ if (!lcpBuildContentFilter) { android { compileSdkVersion 25 - buildToolsVersion '25.0.2' + buildToolsVersion "26.0.2" defaultConfig { minSdkVersion 19 From 9f5b9c06e45d726d2f21665d96342a08e2a9b881 Mon Sep 17 00:00:00 2001 From: danielweck Date: Thu, 28 Sep 2017 18:32:37 +0100 Subject: [PATCH 25/42] Gradle latest is 4.2 (was 3.5) --- platform/android/gradle/wrapper/gradle-wrapper.properties | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/android/gradle/wrapper/gradle-wrapper.properties b/platform/android/gradle/wrapper/gradle-wrapper.properties index 973db55..498c61e 100644 --- a/platform/android/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip +#https://services.gradle.org/distributions +# GRADLE EXPERIMENTAL requires 3.3 +# GRADLE STABLE works with latest (4.2) +distributionUrl=https\://services.gradle.org/distributions/gradle-4.2-all.zip From 273dc2b3dea9cfe059698928415ed8aabf95c35f Mon Sep 17 00:00:00 2001 From: danielweck Date: Mon, 30 Oct 2017 14:31:12 +0000 Subject: [PATCH 26/42] updated Android build tools version to 27 --- platform/android/lib/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/android/lib/build.gradle b/platform/android/lib/build.gradle index e718831..2c3fa72 100644 --- a/platform/android/lib/build.gradle +++ b/platform/android/lib/build.gradle @@ -54,7 +54,7 @@ if (!lcpBuildContentFilter) { android { compileSdkVersion 25 - buildToolsVersion "26.0.2" + buildToolsVersion "27" defaultConfig { minSdkVersion 19 From 8db53bea195d1bd1cbdf56cf5feb23452eb8d05d Mon Sep 17 00:00:00 2001 From: danielweck Date: Fri, 15 Dec 2017 22:36:04 +0000 Subject: [PATCH 27/42] bumped-up Android Studio / platform updates (+ added some console info) --- .../gradle/wrapper/gradle-wrapper.properties | 4 ++-- platform/android/lib/build.gradle | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/platform/android/gradle/wrapper/gradle-wrapper.properties b/platform/android/gradle/wrapper/gradle-wrapper.properties index 498c61e..a1347d8 100644 --- a/platform/android/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/gradle/wrapper/gradle-wrapper.properties @@ -5,5 +5,5 @@ zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists #https://services.gradle.org/distributions # GRADLE EXPERIMENTAL requires 3.3 -# GRADLE STABLE works with latest (4.2) -distributionUrl=https\://services.gradle.org/distributions/gradle-4.2-all.zip +# GRADLE STABLE works with latest (4.4) +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/platform/android/lib/build.gradle b/platform/android/lib/build.gradle index e718831..e5966d5 100644 --- a/platform/android/lib/build.gradle +++ b/platform/android/lib/build.gradle @@ -34,7 +34,7 @@ if (rootProject.hasProperty("readium_sdk_include_dir")) { if (rootProject.hasProperty("readium_lcp_build_content_filter")) { lcpBuildContentFilter = rootProject.readium_lcp_build_content_filter } -println("Test ${extraCmake}") +println("extraCmake ${extraCmake}") def toolchain = ndk_clang ? "clang" : "gcc" def stl = ndk_clang ? "c++_shared" : "gnustl_shared" @@ -44,6 +44,7 @@ if (!lcpBuildContentFilter) { readiumSdkLibDir = "${epub3Dir}/libs" readiumSdkIncludeDir = "${epub3Dir}/include" lcpBuildContentFilter = true + println("Build with rsdk *") } catch (UnknownProjectException e) { // No epub3 project is defined println("Build without rsdk") @@ -51,14 +52,16 @@ if (!lcpBuildContentFilter) { } else { println("Build with rsdk") } - +println "${lcpBuildContentFilter}" +println "${readiumSdkLibDir}" +println "${readiumSdkIncludeDir}" android { - compileSdkVersion 25 - buildToolsVersion "26.0.2" + compileSdkVersion 26 + buildToolsVersion "27.0.2" defaultConfig { minSdkVersion 19 - targetSdkVersion 25 + targetSdkVersion 26 versionCode 1 versionName "1.0" From b9d525a6d13a3c26be9c6db2110e27dfefd59d2b Mon Sep 17 00:00:00 2001 From: danielweck Date: Fri, 15 Dec 2017 22:36:51 +0000 Subject: [PATCH 28/42] explicit relative include path for streambuffs fixes Windows build (ZipLib) see https://github.com/readium/readium-lcp-client/issues/42 --- .../ziplib/Source/ZipLib/streams/compression_decoder_stream.h | 2 +- .../ziplib/Source/ZipLib/streams/compression_encoder_stream.h | 2 +- src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h | 2 +- src/third-parties/ziplib/Source/ZipLib/streams/memstream.h | 2 +- src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h | 2 +- src/third-parties/ziplib/Source/ZipLib/streams/substream.h | 2 +- src/third-parties/ziplib/Source/ZipLib/streams/teestream.h | 2 +- .../ziplib/Source/ZipLib/streams/zip_cryptostream.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/compression_decoder_stream.h b/src/third-parties/ziplib/Source/ZipLib/streams/compression_decoder_stream.h index 401b750..10fee11 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/compression_decoder_stream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/compression_decoder_stream.h @@ -1,6 +1,6 @@ #pragma once #include -#include "streambuffs/compression_decoder_streambuf.h" +#include "./streambuffs/compression_decoder_streambuf.h" /** * \brief Basic generic compression decoder stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/compression_encoder_stream.h b/src/third-parties/ziplib/Source/ZipLib/streams/compression_encoder_stream.h index 078a6b0..1256b52 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/compression_encoder_stream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/compression_encoder_stream.h @@ -1,6 +1,6 @@ #pragma once #include -#include "streambuffs/compression_encoder_streambuf.h" +#include "./streambuffs/compression_encoder_streambuf.h" /** * \brief Basic generic compression encoder stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h b/src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h index cffaa7c..9e1652f 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h @@ -1,6 +1,6 @@ #pragma once #include -#include "streambuffs/crc32_streambuf.h" +#include "./streambuffs/crc32_streambuf.h" /** * \brief Basic CRC32 output stream. Computes CRC32 of input data. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/memstream.h b/src/third-parties/ziplib/Source/ZipLib/streams/memstream.h index 641291e..b5e2472 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/memstream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/memstream.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include "streambuffs/mem_streambuf.h" +#include "./streambuffs/mem_streambuf.h" /** * \brief Basic input memory stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h b/src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h index ad238cb..528883b 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include "streambuffs/null_streambuf.h" +#include "./streambuffs/null_streambuf.h" /** * \brief Basic null stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/substream.h b/src/third-parties/ziplib/Source/ZipLib/streams/substream.h index c1fe45e..6124252 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/substream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/substream.h @@ -1,6 +1,6 @@ #pragma once #include -#include "streambuffs/sub_streambuf.h" +#include "./streambuffs/sub_streambuf.h" /** * \brief Basic input substream. Creates a virtual stream over an existing input stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/teestream.h b/src/third-parties/ziplib/Source/ZipLib/streams/teestream.h index c70b9b2..dd3fe9d 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/teestream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/teestream.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include "streambuffs/tee_streambuff.h" +#include "./streambuffs/tee_streambuff.h" /** * \brief Basic teestream. Distributes the input data into every bound output stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/zip_cryptostream.h b/src/third-parties/ziplib/Source/ZipLib/streams/zip_cryptostream.h index c50396c..e823dab 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/zip_cryptostream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/zip_cryptostream.h @@ -1,6 +1,6 @@ #pragma once #include -#include "streambuffs/zip_crypto_streambuf.h" +#include "./streambuffs/zip_crypto_streambuf.h" template class basic_zip_cryptostream From c3d993a5f9ce0ef4443699269144b9c9a889ee44 Mon Sep 17 00:00:00 2001 From: danielweck Date: Fri, 15 Dec 2017 22:38:02 +0000 Subject: [PATCH 29/42] clean script --- platform/android/clean.sh | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 platform/android/clean.sh diff --git a/platform/android/clean.sh b/platform/android/clean.sh new file mode 100644 index 0000000..f0306e3 --- /dev/null +++ b/platform/android/clean.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +rm -rf build + +rm -rf lib/build From 50c4c68ddd2b27cf02c1f5ef3d3cb704a2ca7c58 Mon Sep 17 00:00:00 2001 From: danielweck Date: Fri, 15 Dec 2017 23:26:49 +0000 Subject: [PATCH 30/42] harmonize version numbers (consistent with other config files) --- platform/android/lib/src/main/AndroidManifest.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/android/lib/src/main/AndroidManifest.xml b/platform/android/lib/src/main/AndroidManifest.xml index a340258..156d6aa 100644 --- a/platform/android/lib/src/main/AndroidManifest.xml +++ b/platform/android/lib/src/main/AndroidManifest.xml @@ -20,6 +20,8 @@ android:versionCode="1" android:versionName="0.1" > - + From 97980f02990e919deb61c09770a8d4452dcc924c Mon Sep 17 00:00:00 2001 From: danielweck Date: Fri, 15 Dec 2017 23:27:18 +0000 Subject: [PATCH 31/42] added folder to clean SH script --- platform/android/clean.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/android/clean.sh b/platform/android/clean.sh index f0306e3..e155c5b 100644 --- a/platform/android/clean.sh +++ b/platform/android/clean.sh @@ -3,3 +3,4 @@ rm -rf build rm -rf lib/build +rm -rf lib/.externalNativeBuild From 688e1e707e1c18a2cf7d3f0a63479807beb7306e Mon Sep 17 00:00:00 2001 From: danielweck Date: Fri, 15 Dec 2017 23:29:00 +0000 Subject: [PATCH 32/42] Revert "explicit relative include path for streambuffs fixes Windows build" This reverts commit b9d525a6d13a3c26be9c6db2110e27dfefd59d2b. --- .../ziplib/Source/ZipLib/streams/compression_decoder_stream.h | 2 +- .../ziplib/Source/ZipLib/streams/compression_encoder_stream.h | 2 +- src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h | 2 +- src/third-parties/ziplib/Source/ZipLib/streams/memstream.h | 2 +- src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h | 2 +- src/third-parties/ziplib/Source/ZipLib/streams/substream.h | 2 +- src/third-parties/ziplib/Source/ZipLib/streams/teestream.h | 2 +- .../ziplib/Source/ZipLib/streams/zip_cryptostream.h | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/compression_decoder_stream.h b/src/third-parties/ziplib/Source/ZipLib/streams/compression_decoder_stream.h index 10fee11..401b750 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/compression_decoder_stream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/compression_decoder_stream.h @@ -1,6 +1,6 @@ #pragma once #include -#include "./streambuffs/compression_decoder_streambuf.h" +#include "streambuffs/compression_decoder_streambuf.h" /** * \brief Basic generic compression decoder stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/compression_encoder_stream.h b/src/third-parties/ziplib/Source/ZipLib/streams/compression_encoder_stream.h index 1256b52..078a6b0 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/compression_encoder_stream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/compression_encoder_stream.h @@ -1,6 +1,6 @@ #pragma once #include -#include "./streambuffs/compression_encoder_streambuf.h" +#include "streambuffs/compression_encoder_streambuf.h" /** * \brief Basic generic compression encoder stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h b/src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h index 9e1652f..cffaa7c 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h @@ -1,6 +1,6 @@ #pragma once #include -#include "./streambuffs/crc32_streambuf.h" +#include "streambuffs/crc32_streambuf.h" /** * \brief Basic CRC32 output stream. Computes CRC32 of input data. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/memstream.h b/src/third-parties/ziplib/Source/ZipLib/streams/memstream.h index b5e2472..641291e 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/memstream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/memstream.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include "./streambuffs/mem_streambuf.h" +#include "streambuffs/mem_streambuf.h" /** * \brief Basic input memory stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h b/src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h index 528883b..ad238cb 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include "./streambuffs/null_streambuf.h" +#include "streambuffs/null_streambuf.h" /** * \brief Basic null stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/substream.h b/src/third-parties/ziplib/Source/ZipLib/streams/substream.h index 6124252..c1fe45e 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/substream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/substream.h @@ -1,6 +1,6 @@ #pragma once #include -#include "./streambuffs/sub_streambuf.h" +#include "streambuffs/sub_streambuf.h" /** * \brief Basic input substream. Creates a virtual stream over an existing input stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/teestream.h b/src/third-parties/ziplib/Source/ZipLib/streams/teestream.h index dd3fe9d..c70b9b2 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/teestream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/teestream.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include "./streambuffs/tee_streambuff.h" +#include "streambuffs/tee_streambuff.h" /** * \brief Basic teestream. Distributes the input data into every bound output stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/zip_cryptostream.h b/src/third-parties/ziplib/Source/ZipLib/streams/zip_cryptostream.h index e823dab..c50396c 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/zip_cryptostream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/zip_cryptostream.h @@ -1,6 +1,6 @@ #pragma once #include -#include "./streambuffs/zip_crypto_streambuf.h" +#include "streambuffs/zip_crypto_streambuf.h" template class basic_zip_cryptostream From 6ae365f9a3d7eca748eed0ba954b2257e377f0f9 Mon Sep 17 00:00:00 2001 From: danielweck Date: Sat, 16 Dec 2017 00:40:21 +0000 Subject: [PATCH 33/42] moving the ZipLib streambufs templated C++ classes fixes the Windows build! see https://github.com/readium/readium-lcp-client/issues/42 --- .../streams/compression_decoder_stream.h | 107 ++++++- .../streams/compression_encoder_stream.h | 132 +++++++- .../Source/ZipLib/streams/crc32stream.h | 107 ++++++- .../ziplib/Source/ZipLib/streams/memstream.h | 203 ++++++++++++- .../ziplib/Source/ZipLib/streams/nullstream.h | 34 ++- .../ziplib/Source/ZipLib/streams/substream.h | 100 +++++- .../ziplib/Source/ZipLib/streams/teestream.h | 65 +++- .../Source/ZipLib/streams/zip_cryptostream.h | 287 +++++++++++++++++- 8 files changed, 1027 insertions(+), 8 deletions(-) diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/compression_decoder_stream.h b/src/third-parties/ziplib/Source/ZipLib/streams/compression_decoder_stream.h index 401b750..3420c5c 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/compression_decoder_stream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/compression_decoder_stream.h @@ -1,6 +1,111 @@ #pragma once #include -#include "streambuffs/compression_decoder_streambuf.h" +// #include "streambuffs/compression_decoder_streambuf.h" + +#include +#include +#include +#include + +#include "../compression/compression_interface.h" + +template +class compression_decoder_streambuf + : public std::basic_streambuf +{ + public: + typedef std::basic_streambuf base_type; + typedef typename std::basic_streambuf::traits_type traits_type; + + typedef typename base_type::char_type char_type; + typedef typename base_type::int_type int_type; + typedef typename base_type::pos_type pos_type; + typedef typename base_type::off_type off_type; + + typedef std::basic_istream istream_type; + typedef std::basic_ostream ostream_type; + + typedef compression_decoder_interface_basic icompression_decoder_type; + typedef std::shared_ptr icompression_decoder_ptr_type; + + compression_decoder_streambuf() + { + + } + + compression_decoder_streambuf(icompression_decoder_ptr_type compressionDecoder, istream_type& stream) + { + init(compressionDecoder, stream); + } + + compression_decoder_streambuf(icompression_decoder_ptr_type compressionDecoder, compression_decoder_properties_interface& props, istream_type& stream) + { + init(compressionDecoder, stream); + } + + void init(icompression_decoder_ptr_type compressionDecoder, istream_type& stream) + { + _compressionDecoder = compressionDecoder; + + // compression decoder init + _compressionDecoder->init(stream); + + // set stream buffer + this->setg(_compressionDecoder->get_buffer_end(), _compressionDecoder->get_buffer_end(), _compressionDecoder->get_buffer_end()); + } + + void init(icompression_decoder_ptr_type compressionDecoder, compression_decoder_properties_interface& props, istream_type& stream) + { + _compressionDecoder = compressionDecoder; + + // compression decoder init + _compressionDecoder->init(stream, props); + + // set stream buffer + this->setg(_compressionDecoder->get_buffer_end(), _compressionDecoder->get_buffer_end(), _compressionDecoder->get_buffer_end()); + } + + bool is_init() const + { + return _compressionDecoder->is_init(); + } + + size_t get_bytes_read() const + { + return _compressionDecoder->get_bytes_read(); + } + + size_t get_bytes_written() const + { + return _compressionDecoder->get_bytes_written(); + } + + protected: + int_type underflow() override + { + // buffer exhausted + if (this->gptr() >= this->egptr()) + { + ELEM_TYPE* base = _compressionDecoder->get_buffer_begin(); + + // how many bytes has been read + size_t n = _compressionDecoder->decode_next(); + + if (n == 0) + { + return traits_type::eof(); + } + + // set buffer pointers + this->setg(base, base, base + n); + } + + return traits_type::to_int_type(*this->gptr()); + } + + private: + icompression_decoder_ptr_type _compressionDecoder; +}; /** * \brief Basic generic compression decoder stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/compression_encoder_stream.h b/src/third-parties/ziplib/Source/ZipLib/streams/compression_encoder_stream.h index 078a6b0..241844e 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/compression_encoder_stream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/compression_encoder_stream.h @@ -1,6 +1,136 @@ #pragma once #include -#include "streambuffs/compression_encoder_streambuf.h" +// #include "streambuffs/compression_encoder_streambuf.h" + +#include +#include +#include +#include +#include +#include + +#include "../compression/compression_interface.h" + +template +class compression_encoder_streambuf + : public std::basic_streambuf +{ + public: + typedef std::basic_streambuf base_type; + typedef typename std::basic_streambuf::traits_type traits_type; + + typedef typename base_type::char_type char_type; + typedef typename base_type::int_type int_type; + typedef typename base_type::pos_type pos_type; + typedef typename base_type::off_type off_type; + + typedef std::basic_istream istream_type; + typedef std::basic_ostream ostream_type; + + typedef compression_encoder_interface_basic icompression_encoder_type; + typedef std::shared_ptr icompression_encoder_ptr_type; + + compression_encoder_streambuf() + { + + } + + compression_encoder_streambuf(icompression_encoder_ptr_type compressionEncoder, ostream_type& stream) + { + init(compressionEncoder, stream); + } + + compression_encoder_streambuf(icompression_encoder_ptr_type compressionEncoder, compression_encoder_properties_interface& props, ostream_type& stream) + { + init(compressionEncoder, props, stream); + } + + virtual ~compression_encoder_streambuf() + { + sync(); + } + + void init(icompression_encoder_ptr_type compressionEncoder, ostream_type& stream) + { + _compressionEncoder = compressionEncoder; + + // compression encoder init + _compressionEncoder->init(stream); + + // set stream buffer + this->setp(_compressionEncoder->get_buffer_begin(), _compressionEncoder->get_buffer_end() - 1); + } + + void init(icompression_encoder_ptr_type compressionEncoder, compression_encoder_properties_interface& props, ostream_type& stream) + { + _compressionEncoder = compressionEncoder; + + // compression encoder init + _compressionEncoder->init(stream, props); + + // set stream buffer + this->setp(_compressionEncoder->get_buffer_begin(), _compressionEncoder->get_buffer_end() - 1); + } + + bool is_init() const + { + return _compressionEncoder->is_init(); + } + + size_t get_bytes_read() const + { + return _compressionEncoder->get_bytes_read(); + } + + size_t get_bytes_written() const + { + return _compressionEncoder->get_bytes_written(); + } + + protected: + int_type overflow(int_type c = traits_type::eof()) override + { + bool is_eof = traits_type::eq_int_type(c, traits_type::eof()); + + // if the input is not EOF, just put it into the buffer + // and increment current pointer + if (!is_eof) + { + *this->pptr() = c; + this->pbump(1); + } + + // if input buffer is full or input is EOF, + // compress the buffer + if (this->pptr() >= this->epptr() || is_eof) + { + process(); + } + + // not eof + return ~traits_type::eof(); + } + + int sync() override + { + process(); + _compressionEncoder->sync(); + + return 0; + } + + private: + void process() + { + std::ptrdiff_t inputLength = this->pptr() - this->pbase(); + _compressionEncoder->encode_next(inputLength); + + // set pointers for new buffer + this->setp(_compressionEncoder->get_buffer_begin(), _compressionEncoder->get_buffer_end() - 1); + } + + icompression_encoder_ptr_type _compressionEncoder; +}; /** * \brief Basic generic compression encoder stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h b/src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h index cffaa7c..61ce88a 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/crc32stream.h @@ -1,6 +1,111 @@ #pragma once #include -#include "streambuffs/crc32_streambuf.h" +// #include "streambuffs/crc32_streambuf.h" + +#include +#include + +#include "substream.h" +#include "../extlibs/zlib/zlib.h" + +template +class crc32_streambuf + : public std::basic_streambuf +{ + public: + typedef std::basic_streambuf base_type; + typedef typename std::basic_streambuf::traits_type traits_type; + + typedef typename base_type::char_type char_type; + typedef typename base_type::int_type int_type; + typedef typename base_type::pos_type pos_type; + typedef typename base_type::off_type off_type; + + crc32_streambuf() + : _inputStream(nullptr) + , _internalBufferPosition(_internalBuffer + INTERNAL_BUFFER_SIZE) + , _internalBufferEnd(_internalBuffer + INTERNAL_BUFFER_SIZE) + , _bytesRead(0) + , _crc32(0) + { + + } + + crc32_streambuf(std::basic_istream& input) + : crc32_streambuf() + { + init(input); + } + + void init(std::basic_istream& input) + { + _inputStream = &input; + + ELEM_TYPE* endOfBuffer = _internalBuffer + INTERNAL_BUFFER_SIZE; + this->setg(endOfBuffer, endOfBuffer, endOfBuffer); + } + + bool is_init() const + { + return (_inputStream != nullptr); + } + + size_t get_bytes_read() const + { + return _bytesRead; + } + + uint32_t get_crc32() const + { + return _crc32; + } + + protected: + int_type underflow() override + { + // buffer exhausted + if (this->gptr() >= _internalBufferEnd) + { + _inputStream->read(_internalBuffer, static_cast(INTERNAL_BUFFER_SIZE)); + size_t n = static_cast(_inputStream->gcount()); + + _bytesRead += n; + + _internalBufferPosition = _internalBuffer; + _internalBufferEnd = _internalBuffer + n; + + if (n == 0) + { + return traits_type::eof(); + } + } + + // set buffer pointers, increment current position + ELEM_TYPE* base = _internalBufferPosition++; + + // setting all pointers to the same position forces calling of this method each time, + // so crc32 really represents the checksum of what really has been read + this->setg(base, base, base + 1); + + _crc32 = crc32(_crc32, reinterpret_cast(this->gptr()), static_cast(sizeof(ELEM_TYPE))); + + return traits_type::to_int_type(*this->gptr()); + } + + private: + enum : size_t + { + INTERNAL_BUFFER_SIZE = 1 << 15 + }; + + ELEM_TYPE _internalBuffer[INTERNAL_BUFFER_SIZE]; + ELEM_TYPE* _internalBufferPosition; + ELEM_TYPE* _internalBufferEnd; + + std::basic_istream* _inputStream; + size_t _bytesRead; + uint32_t _crc32; +}; /** * \brief Basic CRC32 output stream. Computes CRC32 of input data. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/memstream.h b/src/third-parties/ziplib/Source/ZipLib/streams/memstream.h index 641291e..b774794 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/memstream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/memstream.h @@ -1,7 +1,208 @@ #pragma once #include #include -#include "streambuffs/mem_streambuf.h" +// #include "streambuffs/mem_streambuf.h" + +#include +#include +#include + +template +class mem_streambuf + : public std::basic_streambuf +{ + public: + typedef std::basic_streambuf base_type; + typedef typename std::basic_streambuf::traits_type traits_type; + + typedef typename base_type::char_type char_type; + typedef typename base_type::int_type int_type; + typedef typename base_type::pos_type pos_type; + typedef typename base_type::off_type off_type; + + mem_streambuf(ELEM_TYPE* buffer, size_t length) + { + // set stream buffer + ELEM_TYPE* endOfBuffer = buffer + length; + this->setg(buffer, buffer, endOfBuffer); + this->setp(buffer, buffer, endOfBuffer); + } + + protected: + int_type underflow() override + { + // buffer not exhausted + if (this->gptr() < this->egptr()) + { + return traits_type::to_int_type(*this->gptr()); + } + + return traits_type::eof(); + } + + int_type overflow(int_type c = traits_type::eof()) override + { + assert(this->pptr() != nullptr); + + // check if incoming character is not EOF + // also, we might not overflow the buffer + if (!traits_type::eq_int_type(c, traits_type::eof()) && + this->pptr() < this->epptr()) + { + *this->pptr() = c; + this->pbump(1); // shift pptr() by 1 + return c; // return value must not be EOF + } + + return traits_type::eof(); + } + + pos_type seekpos(pos_type pos, std::ios::openmode which = std::ios::in | std::ios::out) override + { + static const off_type BAD_OFFSET(-1); + + // depending on which pointer we move, it must be set + assert(which & std::ios::in ? this->gptr() != nullptr : true); + assert(which & std::ios::out ? this->pptr() != nullptr : true); + + // do not seek over the length of buffer + if (pos <= pos_type(this->egptr() - this->eback())) + { + // position of read buffer + if (which & std::ios::in) + { + // move gptr to the right position + this->gbump(static_cast(this->eback() - this->gptr() + pos)); + + if (which & std::ios::out) + { + // change write position to match + this->setp(this->pbase(), this->gptr(), this->epptr()); + } + } + + // position of write buffer + else if (which & std::ios::out) + { + // move pptr to the right position + this->pbump(static_cast(this->eback() - this->pptr() + pos)); + } + + return pos; + } + + // something went wrong + return pos_type(BAD_OFFSET); + } + + pos_type seekoff(off_type off, std::ios::seekdir dir, std::ios::openmode which = std::ios::in | std::ios::out) override + { + static const off_type BAD_OFFSET(-1); + + // depending on which pointer we move, it must be set + assert(which & std::ios::in ? this->gptr() != nullptr : true); + assert(which & std::ios::out ? this->pptr() != nullptr : true); + + if (which & std::ios::in) + { + // position within read buffer + if (dir == std::ios::end) + { + off += off_type(this->egptr() - this->eback()); + } + else if (dir == std::ios::cur && (which & std::ios::out) == 0) + { + off += off_type(this->gptr() - this->eback()); + } + else if (dir != std::ios::beg) + { + off = BAD_OFFSET; + } + + if (off >= 0 && off <= off_type(this->egptr() - this->eback())) + { + // move gptr to the right position + this->gbump(static_cast(this->eback() - this->gptr() + off)); + if (which & std::ios::out) + { + // change write position to match + this->setp(this->pbase(), this->gptr(), this->epptr()); + } + } + else + { + off = BAD_OFFSET; + } + } + else if (which & std::ios::out) + { + // position within write buffer + if (dir == std::ios::end) + { + off += off_type(this->egptr() - this->eback()); + } + else if (dir == std::ios::cur) + { + off += off_type(this->pptr() - this->eback()); + } + else if (dir != std::ios::beg) + { + // if dir is ios::beg, just leave the offset set as is + // if dir is not neither of the valid directions, set bad offset + off = BAD_OFFSET; + } + + if (off >= 0 && off <= off_type(this->egptr() - this->eback())) + { + // change write position + this->pbump(static_cast(this->eback() - this->pptr() + off)); + } + else + { + off = BAD_OFFSET; + } + } + else + { + // neither read nor write buffer selected, fail + off = BAD_OFFSET; + } + return (pos_type(off)); + } + + int_type pbackfail(int_type c = traits_type::eof()) override + { + assert(this->gptr() != nullptr); + + // put an element back to stream + if (this->gptr() <= this->eback() || // do not underflow + (!traits_type::eq_int_type(traits_type::eof(), c) && + !traits_type::eq(traits_type::to_char_type(c), this->gptr()[-1]))) + { + // can't put back, fail + return (traits_type::eof()); + } + else + { + // back up one position and store put-back character + this->gbump(-1); + + if (!traits_type::eq_int_type(traits_type::eof(), c)) + { + *this->gptr() = traits_type::to_char_type(c); + } + + return (traits_type::not_eof(c)); + } + } + + private: + void setp(ELEM_TYPE* first, ELEM_TYPE* next, ELEM_TYPE* last) + { + this->std::basic_streambuf::setp(first, last); + this->pbump(static_cast(next - first)); + } +}; /** * \brief Basic input memory stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h b/src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h index ad238cb..5444e4c 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/nullstream.h @@ -1,7 +1,39 @@ #pragma once #include #include -#include "streambuffs/null_streambuf.h" +// #include "streambuffs/null_streambuf.h" + +#include + +template +class null_streambuf + : public std::basic_streambuf +{ + public: + typedef std::basic_streambuf base_type; + typedef typename std::basic_streambuf::traits_type traits_type; + + typedef typename base_type::char_type char_type; + typedef typename base_type::int_type int_type; + typedef typename base_type::pos_type pos_type; + typedef typename base_type::off_type off_type; + + null_streambuf() + { + + } + + protected: + std::streamsize xsgetn(char_type* s, std::streamsize count) override + { + return 0; + } + + std::streamsize xsputn(const ELEM_TYPE* ptr, std::streamsize count) override + { + return count; + } +}; /** * \brief Basic null stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/substream.h b/src/third-parties/ziplib/Source/ZipLib/streams/substream.h index c1fe45e..366fe70 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/substream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/substream.h @@ -1,6 +1,104 @@ #pragma once #include -#include "streambuffs/sub_streambuf.h" +// #include "streambuffs/sub_streambuf.h" + +#include +#include +#include + +template +class sub_streambuf : + public std::basic_streambuf +{ + public: + typedef std::basic_streambuf base_type; + typedef typename std::basic_streambuf::traits_type traits_type; + + typedef typename base_type::char_type char_type; + typedef typename base_type::int_type int_type; + typedef typename base_type::pos_type pos_type; + typedef typename base_type::off_type off_type; + + sub_streambuf() + : _inputStream(nullptr) + , _startPosition(0) + , _currentPosition(0) + , _endPosition(0) + { + + } + + sub_streambuf(std::basic_istream& input, pos_type startOffset, size_t length) + : sub_streambuf() + { + init(input, startOffset, length); + } + + void init(std::basic_istream& input, pos_type startOffset, size_t length) + { + _inputStream = &input; + _startPosition = startOffset; + _currentPosition = startOffset; + _endPosition = startOffset + static_cast(length); + _internalBuffer = new ELEM_TYPE[INTERNAL_BUFFER_SIZE]; + + // set stream buffer + ELEM_TYPE* endOfOutputBuffer = _internalBuffer + INTERNAL_BUFFER_SIZE; + this->setg(endOfOutputBuffer, endOfOutputBuffer, endOfOutputBuffer); + } + + bool is_init() const + { + return (_inputStream != nullptr && _internalBuffer != nullptr); + } + + virtual ~sub_streambuf() + { + if (_internalBuffer != nullptr) + { + delete[] _internalBuffer; + } + } + + protected: + int_type underflow() override + { + // buffer exhausted + if (this->gptr() >= this->egptr()) + { + ELEM_TYPE* base = _internalBuffer; + + _inputStream->seekg(_currentPosition, std::ios::beg); + _inputStream->read(_internalBuffer, std::min(static_cast(INTERNAL_BUFFER_SIZE), static_cast(_endPosition - _currentPosition))); + size_t n = static_cast(_inputStream->gcount()); + + _currentPosition += n; + + if (n == 0) + { + return traits_type::eof(); + } + + // set buffer pointers + this->setg(base, base, base + n); + } + + return traits_type::to_int_type(*this->gptr()); + } + + private: + enum : size_t + { + INTERNAL_BUFFER_SIZE = 1 << 15 + }; + + ELEM_TYPE* _internalBuffer; + + std::basic_istream* _inputStream; + pos_type _startPosition; + pos_type _currentPosition; + pos_type _endPosition; +}; /** * \brief Basic input substream. Creates a virtual stream over an existing input stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/teestream.h b/src/third-parties/ziplib/Source/ZipLib/streams/teestream.h index c70b9b2..d89fbf3 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/teestream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/teestream.h @@ -1,7 +1,70 @@ #pragma once #include #include -#include "streambuffs/tee_streambuff.h" +// #include "streambuffs/tee_streambuff.h" + +#include +#include + +template +class tee_streambuf: + public std::basic_streambuf +{ + public: + typedef std::basic_streambuf base_type; + typedef typename std::basic_streambuf::traits_type traits_type; + + typedef typename base_type::char_type char_type; + typedef typename base_type::int_type int_type; + typedef typename base_type::pos_type pos_type; + typedef typename base_type::off_type off_type; + + tee_streambuf& bind(base_type* sb) + { + _sbCollection.push_back(sb); + return *this; + } + + tee_streambuf& bind(std::basic_ostream& stream) + { + _sbCollection.push_back(stream.rdbuf()); + return *this; + } + + protected: + int_type overflow(int_type c = traits_type::eof()) override + { + bool failed = false; + + for (auto* sb : _sbCollection) + { + if (sb->sputc(c) == traits_type::eof()) + { + failed = true; + } + } + + return failed ? traits_type::eof() : c; + } + + int sync() override + { + bool failed = false; + + for (auto* sb : _sbCollection) + { + if (sb->pubsync() == -1) + { + failed = true; + } + } + + return failed ? -1 : 0; + } + + private: + std::vector _sbCollection; +}; /** * \brief Basic teestream. Distributes the input data into every bound output stream. diff --git a/src/third-parties/ziplib/Source/ZipLib/streams/zip_cryptostream.h b/src/third-parties/ziplib/Source/ZipLib/streams/zip_cryptostream.h index c50396c..891cfa6 100644 --- a/src/third-parties/ziplib/Source/ZipLib/streams/zip_cryptostream.h +++ b/src/third-parties/ziplib/Source/ZipLib/streams/zip_cryptostream.h @@ -1,6 +1,291 @@ #pragma once #include -#include "streambuffs/zip_crypto_streambuf.h" +// #include "streambuffs/zip_crypto_streambuf.h" + +#include +#include +#include +#include +#include +#include + +#include "../extlibs/zlib/zlib.h" + +template +class zip_crypto_streambuf + : public std::basic_streambuf +{ + public: + typedef std::basic_streambuf base_type; + typedef typename std::basic_streambuf::traits_type traits_type; + + typedef typename base_type::char_type char_type; + typedef typename base_type::int_type int_type; + typedef typename base_type::pos_type pos_type; + typedef typename base_type::off_type off_type; + + zip_crypto_streambuf() + : _internalBuffer(nullptr) + , _inputStream(nullptr) + , _outputStream(nullptr) + , _finalByte(-1) + , _encryptionHeaderRead(false) + , _encryptionHeaderWritten(false) + { + static_assert(sizeof(ELEM_TYPE) == 1, "size of ELEM_TYPE must be 1"); + } + + zip_crypto_streambuf(std::basic_ostream& stream, const ELEM_TYPE* password) + : zip_crypto_streambuf() + { + static_assert(sizeof(ELEM_TYPE) == 1, "size of ELEM_TYPE must be 1"); + init(stream, password); + } + + zip_crypto_streambuf(std::basic_istream& stream, const ELEM_TYPE* password) + : zip_crypto_streambuf() + { + static_assert(sizeof(ELEM_TYPE) == 1, "size of ELEM_TYPE must be 1"); + init(stream, password); + } + + ~zip_crypto_streambuf() + { + if (_internalBuffer != nullptr) + { + delete[] _internalBuffer; + } + } + + void init(std::basic_ostream& stream, const ELEM_TYPE* password) + { + _inputStream = nullptr; + _outputStream = &stream; + _finalByte = -1; + _encryptionHeaderRead = false; + _encryptionHeaderWritten = false; + + init_internal(password); + } + + void init(std::basic_istream& stream, const ELEM_TYPE* password) + { + _inputStream = &stream; + _outputStream = nullptr; + _finalByte = -1; + _encryptionHeaderRead = false; + _encryptionHeaderWritten = false; + + init_internal(password); + } + + bool is_init() const + { + return (_inputStream != nullptr || _outputStream != nullptr); + } + + void set_final_byte(uint8_t c) + { + _finalByte = int(c); + } + + bool has_correct_password() const + { + return (uint8_t(_finalByte) == _encryptionHeader.u8[11]); + } + + bool prepare_for_decryption() + { + if (_inputStream == nullptr) + { + return false; + } + + _inputStream->read(reinterpret_cast(&_encryptionHeader), sizeof(_encryptionHeader)); + finish_decryption_header(); + _encryptionHeaderRead = true; + + return has_correct_password(); + } + + protected: + int_type overflow(int_type c = traits_type::eof()) override + { + bool is_eof = traits_type::eq_int_type(c, traits_type::eof()); + + // buffering would be great, maybe? + if (!is_eof) + { + if (!_encryptionHeaderWritten) + { + finish_encryption_header(); + _outputStream->write(reinterpret_cast(&_encryptionHeader), sizeof(_encryptionHeader)); + _encryptionHeaderWritten = true; + } + + uint8_t encryptedByte = encrypt_byte(uint8_t(c)); + _outputStream->write(reinterpret_cast(&encryptedByte), sizeof(encryptedByte)); + + return encryptedByte; + } + + return traits_type::eof(); + } + + int_type underflow() override + { + // if we're going to decrypt, + // the call to prepare_for_decryption() is needed + if (!_encryptionHeaderRead) + { + return traits_type::eof(); + } + + // buffer exhausted + if (this->gptr() >= this->egptr()) + { + ELEM_TYPE* base = _internalBuffer; + _inputStream->read(_internalBuffer, INTERNAL_BUFFER_SIZE); + + size_t n = static_cast(_inputStream->gcount()); + + if (n == 0) + { + return traits_type::eof(); + } + + decrypt_internal_buffer(n); + + // set buffer pointers + this->setg(base, base, base + n); + } + + return traits_type::to_int_type(*this->gptr()); + } + + int sync() override + { + return _outputStream->rdbuf()->pubsync(); + } + + private: + static uint32_t crc32_byte(uint32_t prevCrc32, uint8_t c) + { + return uint32_t(get_crc_table()[(prevCrc32 ^ c) & 0xff] ^ (prevCrc32 >> 8)); + } + + bool init_internal(const ELEM_TYPE* password) + { + assert(password != nullptr); + + _keys.u32[0] = 0x12345678; + _keys.u32[1] = 0x23456789; + _keys.u32[2] = 0x34567890; + + do + { + update_keys(uint8_t(*password++)); + } while (*password != '\0'); + + // make encryption header + auto seed = std::chrono::system_clock::now().time_since_epoch().count(); + std::mt19937 generator(static_cast(seed)); + + _encryptionHeader.u32[0] = generator(); + _encryptionHeader.u32[1] = generator(); + _encryptionHeader.u32[2] = generator(); + + // set stream buffer + _internalBuffer = new ELEM_TYPE[INTERNAL_BUFFER_SIZE]; + ELEM_TYPE* endOfInternalBuffer = _internalBuffer + INTERNAL_BUFFER_SIZE; + this->setg(endOfInternalBuffer, endOfInternalBuffer, endOfInternalBuffer); + + return true; + } + + void finish_encryption_header() + { + assert(_finalByte != -1); + + _encryptionHeader.u8[11] = uint8_t(_finalByte); + + for (uint8_t& c : _encryptionHeader.u8) + { + c = encrypt_byte(c); + } + } + + void finish_decryption_header() + { + for (uint8_t& c : _encryptionHeader.u8) + { + c = decrypt_byte(c); + } + } + + uint8_t encrypt_byte(uint8_t c) + { + uint8_t result = uint8_t(c ^ get_magic_byte()); + + update_keys(c); + + return result; + } + + uint8_t decrypt_byte(uint8_t c) + { + uint8_t result = uint8_t(c ^ get_magic_byte()); + + update_keys(result); + + return result; + } + + void decrypt_internal_buffer(size_t length) + { + for (size_t i = 0; i < length; ++i) + { + _internalBuffer[i] = decrypt_byte(_internalBuffer[i]); + } + } + + void update_keys(uint8_t c) + { + _keys.u32[0] = crc32_byte(_keys.u32[0], c); + _keys.u32[1] = _keys.u32[1] + uint8_t(_keys.u32[0] & 0x000000ff); + _keys.u32[1] = _keys.u32[1] * 0x08088405 + 1; + _keys.u32[2] = crc32_byte(_keys.u32[2], _keys.u32[1] >> 24); + } + + uint8_t get_magic_byte() const + { + uint16_t t = uint16_t(uint16_t(_keys.u32[2] & 0xFFFF) | 2); + return uint8_t((t * (t ^ 1)) >> 8); + } + + union encryption_header + { + uint8_t u8[12]; + uint32_t u32[3]; + }; + + ////////////////////////////////////////////////////////////////////////// + + enum : size_t + { + INTERNAL_BUFFER_SIZE = 1 << 15 + }; + + ELEM_TYPE* _internalBuffer; + + std::basic_istream* _inputStream; + std::basic_ostream* _outputStream; + encryption_header _keys; + encryption_header _encryptionHeader; + int _finalByte; + bool _encryptionHeaderRead; + bool _encryptionHeaderWritten; +}; template class basic_zip_cryptostream From dc188e9f4e05ab61e94cfa5cba947bddde83e129 Mon Sep 17 00:00:00 2001 From: danielweck Date: Sat, 16 Dec 2017 03:01:04 +0000 Subject: [PATCH 34/42] ensures the ReadiumSDK lib is correctly inmported from DEBUG or RELEASE --- platform/android/lib/CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/android/lib/CMakeLists.txt b/platform/android/lib/CMakeLists.txt index 320cfb0..f85414c 100644 --- a/platform/android/lib/CMakeLists.txt +++ b/platform/android/lib/CMakeLists.txt @@ -25,6 +25,10 @@ endif() add_definitions("-DZLIB_ONLY") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -fpic -frtti -fexceptions -fpermissive -Wall") +#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11") +#set(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS} -std=gnu11") +#set(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS}) + include_directories( ${CLIENTLIB_DIR} ${CLIENTLIB_DIR}/public @@ -49,7 +53,7 @@ SET ( LCP_LINK_LIBRARIES "clientlib" "contentfilter" - "${RSDK_LIB_DIR}/${ANDROID_ABI}/libepub3.so" + "${RSDK_LIB_DIR}/${CMAKE_BUILD_TYPE}/${ANDROID_ABI}/libepub3.so" ) # Extra cmake called before build From 51d3f556afea29fe720d1645814d645712a23cd0 Mon Sep 17 00:00:00 2001 From: danielweck Date: Wed, 10 Jan 2018 02:04:55 +0000 Subject: [PATCH 35/42] DISABLE_CRL now works (just in case it is needed) --- platform/apple/LCP Client (iOS).xcconfig | 2 +- src/lcp-client-lib/CryptoppCryptoProvider.h | 4 ++-- src/lcp-client-lib/ICryptoProvider.h | 6 ++++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/platform/apple/LCP Client (iOS).xcconfig b/platform/apple/LCP Client (iOS).xcconfig index cd380af..64e6b2a 100644 --- a/platform/apple/LCP Client (iOS).xcconfig +++ b/platform/apple/LCP Client (iOS).xcconfig @@ -26,4 +26,4 @@ PRODUCT_NAME = LCP-client-iOS -GCC_PREPROCESSOR_DEFINITIONS = $(inherited) ENABLE_NET_PROVIDER_ACQUISITION=1 CRYPTOPP_DISABLE_SSE2=1 CRYPTOPP_DISABLE_ASM=1 +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DISABLE_CRL_=1 ENABLE_NET_PROVIDER_ACQUISITION=1 CRYPTOPP_DISABLE_SSE2=1 CRYPTOPP_DISABLE_ASM=1 diff --git a/src/lcp-client-lib/CryptoppCryptoProvider.h b/src/lcp-client-lib/CryptoppCryptoProvider.h index 621aea0..1c45e27 100644 --- a/src/lcp-client-lib/CryptoppCryptoProvider.h +++ b/src/lcp-client-lib/CryptoppCryptoProvider.h @@ -150,11 +150,11 @@ class ICertificateRevocationList; std::unique_ptr m_threadTimer; #endif //!DISABLE_CRL_BACKGROUND_POLL - IFileSystemProvider * m_fileSystemProvider; - std::unique_ptr m_crlUpdater; std::mutex m_processRevocationSync; #endif //!DISABLE_CRL + + IFileSystemProvider * m_fileSystemProvider; EncryptionProfilesManager * m_encryptionProfilesManager; }; diff --git a/src/lcp-client-lib/ICryptoProvider.h b/src/lcp-client-lib/ICryptoProvider.h index 6a51bac..c5bc02c 100644 --- a/src/lcp-client-lib/ICryptoProvider.h +++ b/src/lcp-client-lib/ICryptoProvider.h @@ -46,8 +46,10 @@ namespace lcp ILicense * license ) = 0; +#if !DISABLE_CRL virtual Status CheckRevokation(ILicense* license) = 0; - +#endif //!DISABLE_CRL + virtual Status DecryptUserKey( const std::string & userPassphrase, ILicense * license, @@ -112,4 +114,4 @@ namespace lcp }; } -#endif //__I_CRYPTO_PROVIDER_H__ \ No newline at end of file +#endif //__I_CRYPTO_PROVIDER_H__ From 9a33f286244368e8fa2dd6d0a1b0656a84217a2a Mon Sep 17 00:00:00 2001 From: danielweck Date: Fri, 2 Feb 2018 12:04:07 +0000 Subject: [PATCH 36/42] Android build tools version bump --- platform/android/lib/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/android/lib/build.gradle b/platform/android/lib/build.gradle index e5966d5..02af41a 100644 --- a/platform/android/lib/build.gradle +++ b/platform/android/lib/build.gradle @@ -57,7 +57,7 @@ println "${readiumSdkLibDir}" println "${readiumSdkIncludeDir}" android { compileSdkVersion 26 - buildToolsVersion "27.0.2" + buildToolsVersion "27.0.3" defaultConfig { minSdkVersion 19 From d72e6ff87f4acd8f58108ae6a0999762e7398eed Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Sun, 4 Nov 2018 18:25:26 +0000 Subject: [PATCH 37/42] explicit integerValue for NSNumber (see https://github.com/readium/readium-lcp-client/issues/47 ) --- platform/apple/src/LCPStatusDocumentProcessing.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/apple/src/LCPStatusDocumentProcessing.mm b/platform/apple/src/LCPStatusDocumentProcessing.mm index 3994ce0..7ff6eab 100644 --- a/platform/apple/src/LCPStatusDocumentProcessing.mm +++ b/platform/apple/src/LCPStatusDocumentProcessing.mm @@ -706,7 +706,7 @@ - (bool)parseStatusDocumentJson:(NSString*)json templated = YES; } } else if ([templated_ isKindOfClass:[NSNumber class]]) { - if (((NSNumber*)templated_) > 0) { + if ([((NSNumber*)templated_) integerValue] > 0) { templated = YES; } } From b817e71343c8a54b3fefd2e3da450fa81f3d0fe1 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Sun, 4 Nov 2018 18:26:11 +0000 Subject: [PATCH 38/42] XCode project updated settings (see https://github.com/readium/readium-lcp-client/issues/47 ) --- .../LCP Client.xcodeproj/project.pbxproj | 18 +++++++- .../cryptopp.xcodeproj/project.pbxproj | 44 ++++++++++++++++++- .../ziplib/ziplib.xcodeproj/project.pbxproj | 26 +++++++++-- 3 files changed, 83 insertions(+), 5 deletions(-) diff --git a/platform/apple/LCP Client.xcodeproj/project.pbxproj b/platform/apple/LCP Client.xcodeproj/project.pbxproj index 1219045..f6c011e 100644 --- a/platform/apple/LCP Client.xcodeproj/project.pbxproj +++ b/platform/apple/LCP Client.xcodeproj/project.pbxproj @@ -707,7 +707,7 @@ 5ACE2E031BF21D7900AC0585 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0800; + LastUpgradeCheck = 1010; ORGANIZATIONNAME = Readium; TargetAttributes = { 5ACE2E1A1BF21D8C00AC0585 = { @@ -888,14 +888,22 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -934,14 +942,22 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; diff --git a/src/third-parties/cryptopp/cryptopp.xcodeproj/project.pbxproj b/src/third-parties/cryptopp/cryptopp.xcodeproj/project.pbxproj index 63785d6..9481b65 100644 --- a/src/third-parties/cryptopp/cryptopp.xcodeproj/project.pbxproj +++ b/src/third-parties/cryptopp/cryptopp.xcodeproj/project.pbxproj @@ -930,7 +930,7 @@ 5A5C5FA41C04BAD700185159 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0710; + LastUpgradeCheck = 1010; ORGANIZATIONNAME = "Crypto++"; TargetAttributes = { 5A5C5FAB1C04BAD700185159 = { @@ -1245,8 +1245,24 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; @@ -1261,7 +1277,12 @@ "DEBUG=1", "$(inherited)", ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.3; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; @@ -1278,8 +1299,24 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; @@ -1289,7 +1326,12 @@ GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = "${inherited}"; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.3; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; diff --git a/src/third-parties/ziplib/ziplib.xcodeproj/project.pbxproj b/src/third-parties/ziplib/ziplib.xcodeproj/project.pbxproj index 14b3b82..bb8e6c4 100644 --- a/src/third-parties/ziplib/ziplib.xcodeproj/project.pbxproj +++ b/src/third-parties/ziplib/ziplib.xcodeproj/project.pbxproj @@ -432,7 +432,7 @@ 5AA9E0D01C119EB6006470DD /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0710; + LastUpgradeCheck = 1010; ORGANIZATIONNAME = Readium; TargetAttributes = { 5AA9E0E81C119F19006470DD = { @@ -524,13 +524,23 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -568,13 +578,23 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -600,7 +620,7 @@ 5AA9E0F01C119F19006470DD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -610,7 +630,7 @@ 5AA9E0F11C119F19006470DD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; From 3a992f4a0df5756a02f0d9297756aeeecd87cb8f Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Sun, 4 Nov 2018 20:32:25 +0000 Subject: [PATCH 39/42] debug messages for LSD HTTP responses (not just HTTP code) --- .../apple/src/LCPStatusDocumentProcessing.mm | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/platform/apple/src/LCPStatusDocumentProcessing.mm b/platform/apple/src/LCPStatusDocumentProcessing.mm index 7ff6eab..ce191e5 100644 --- a/platform/apple/src/LCPStatusDocumentProcessing.mm +++ b/platform/apple/src/LCPStatusDocumentProcessing.mm @@ -365,6 +365,15 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task } else if (code < 200 || code >= 300) { + if (_data_TASK_DESCRIPTION_LCP_LSD_FETCH != nil) { + try { + NSString *msg = [[NSString alloc] initWithData:_data_TASK_DESCRIPTION_LCP_LSD_FETCH encoding:NSUTF8StringEncoding]; + NSLog(@"%@", msg); + } + catch (NSException *e) { + NSLog(@"%@", [e reason]); + } + } _data_TASK_DESCRIPTION_LCP_LSD_FETCH = nil; NSLog(@"%@", [NSString stringWithFormat:@"HTTP fail (TASK_DESCRIPTION_LCP_LSD_FETCH) [%@] => (%li)", [(NSHTTPURLResponse *)task.response URL], code]); @@ -427,6 +436,15 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task } else if (code < 200 || code >= 300) { + if (_data_TASK_DESCRIPTION_LCP_LSD_REGISTER != nil) { + try { + NSString *msg = [[NSString alloc] initWithData:_data_TASK_DESCRIPTION_LCP_LSD_REGISTER encoding:NSUTF8StringEncoding]; + NSLog(@"%@", msg); + } + catch (NSException *e) { + NSLog(@"%@", [e reason]); + } + } _data_TASK_DESCRIPTION_LCP_LSD_REGISTER = nil; NSLog(@"%@", [NSString stringWithFormat:@"HTTP fail (TASK_DESCRIPTION_LCP_LSD_REGISTER) [%@] => (%li)", [(NSHTTPURLResponse *)task.response URL], code]); @@ -479,6 +497,15 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task } else if (code < 200 || code >= 300) { + if (_data_TASK_DESCRIPTION_LCP_FETCH != nil) { + try { + NSString *msg = [[NSString alloc] initWithData:_data_TASK_DESCRIPTION_LCP_FETCH encoding:NSUTF8StringEncoding]; + NSLog(@"%@", msg); + } + catch (NSException *e) { + NSLog(@"%@", [e reason]); + } + } _data_TASK_DESCRIPTION_LCP_FETCH = nil; NSLog(@"%@", [NSString stringWithFormat:@"HTTP fail (TASK_DESCRIPTION_LCP_LSD_FETCH) [%@] => (%li)", [(NSHTTPURLResponse *)task.response URL], code]); @@ -533,6 +560,15 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task } else if (code < 200 || code >= 300) { + if (_data_TASK_DESCRIPTION_LCP_LSD_RENEW != nil) { + try { + NSString *msg = [[NSString alloc] initWithData:_data_TASK_DESCRIPTION_LCP_LSD_RENEW encoding:NSUTF8StringEncoding]; + NSLog(@"%@", msg); + } + catch (NSException *e) { + NSLog(@"%@", [e reason]); + } + } _data_TASK_DESCRIPTION_LCP_LSD_RENEW = nil; NSLog(@"%@", [NSString stringWithFormat:@"HTTP fail (TASK_DESCRIPTION_LCP_LSD_RENEW) [%@] => (%li)", [(NSHTTPURLResponse *)task.response URL], code]); @@ -583,6 +619,15 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task } else if (code < 200 || code >= 300) { + if (_data_TASK_DESCRIPTION_LCP_LSD_RETURN != nil) { + try { + NSString *msg = [[NSString alloc] initWithData:_data_TASK_DESCRIPTION_LCP_LSD_RETURN encoding:NSUTF8StringEncoding]; + NSLog(@"%@", msg); + } + catch (NSException *e) { + NSLog(@"%@", [e reason]); + } + } _data_TASK_DESCRIPTION_LCP_LSD_RETURN = nil; NSLog(@"%@", [NSString stringWithFormat:@"HTTP fail (TASK_DESCRIPTION_LCP_LSD_RETURN) [%@] => (%li)", [(NSHTTPURLResponse *)task.response URL], code]); From ca298910b384d46b35adfabca276a139aea66c51 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Wed, 7 Nov 2018 19:25:26 +0000 Subject: [PATCH 40/42] LCP LSD: fixed debug messages, listener is now weak reference, added convenient mathods to access LSD state and exposed links (parsed JSON from initial fetch and potential register) --- .../apple/src/LCPStatusDocumentProcessing.h | 41 ++++++- .../apple/src/LCPStatusDocumentProcessing.mm | 110 ++++++++++++------ 2 files changed, 114 insertions(+), 37 deletions(-) diff --git a/platform/apple/src/LCPStatusDocumentProcessing.h b/platform/apple/src/LCPStatusDocumentProcessing.h index 669cc53..8dca9e1 100644 --- a/platform/apple/src/LCPStatusDocumentProcessing.h +++ b/platform/apple/src/LCPStatusDocumentProcessing.h @@ -25,6 +25,25 @@ #import +@interface StatusDocumentLink : NSObject { + NSString* rel; + NSString* href; + NSString* type; + BOOL templated; + NSString* title; + NSString* profile; +} + +- (instancetype)init_:(NSString*) rel href:(NSString*) href type:(NSString*) type templated:(BOOL) templated title:(NSString*) title profile:(NSString*) profile; + +@property (nonatomic, readonly) NSString* rel; +@property (nonatomic, readonly) NSString* href; +@property (nonatomic, readonly) NSString* type; +@property (nonatomic, readonly) BOOL templated; +@property (nonatomic, readonly) NSString* title; +@property (nonatomic, readonly) NSString* profile; + +@end @protocol DeviceIdManager @@ -61,11 +80,29 @@ typedef void (^DoneCallback)(bool); -(bool)isInitialized; -(bool)hasLicenseUpdatePending; + +- (NSString *)identifier; +- (NSString *)message; + +-(NSString *)status; -(bool)isActive; --(bool)hasRenewLink; --(bool)hasReturnLink; +-(StatusDocumentLink *)licenseLink; + +-(bool)hasRegisterLink; +-(StatusDocumentLink *)registerLink; + +-(bool)hasRenewLink; +-(StatusDocumentLink *)renewLink; -(void)doRenew:(DoneCallback)doneCallback_doRenew; //void(^)(bool) + +-(bool)hasReturnLink; +-(StatusDocumentLink *)returnLink; -(void)doReturn:(DoneCallback)doneCallback_doReturn; //void(^)(bool) +-(NSDate *)potentialRightsEndDate; + +- (NSDate *)statusUpdated; +- (NSDate *)licenseUpdated; + @end diff --git a/platform/apple/src/LCPStatusDocumentProcessing.mm b/platform/apple/src/LCPStatusDocumentProcessing.mm index ce191e5..4c26757 100644 --- a/platform/apple/src/LCPStatusDocumentProcessing.mm +++ b/platform/apple/src/LCPStatusDocumentProcessing.mm @@ -41,29 +41,6 @@ using namespace lcp; - -@interface StatusDocumentLink : NSObject { - - NSString* rel; - NSString* href; - NSString* type; - BOOL templated; - NSString* title; - NSString* profile; -} - -- (instancetype)init_:(NSString*) rel href:(NSString*) href type:(NSString*) type templated:(BOOL) templated title:(NSString*) title profile:(NSString*) profile; - -@property (nonatomic, readonly) NSString* rel; -@property (nonatomic, readonly) NSString* href; -@property (nonatomic, readonly) NSString* type; -@property (nonatomic, readonly) BOOL templated; -@property (nonatomic, readonly) NSString* title; -@property (nonatomic, readonly) NSString* profile; - -@end - - @interface StatusDocumentLink() @end @@ -111,7 +88,7 @@ @implementation LCPStatusDocumentProcessing { id _deviceIDManager; bool _wasCancelled; - id _statusDocumentProcessingListener; + __weak id _statusDocumentProcessingListener; NSString * _statusDocument_ID; NSString * _statusDocument_STATUS; // ready, active, revoked, returned, cancelled, expired @@ -354,7 +331,6 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task if ([task.taskDescription isEqualToString:TASK_DESCRIPTION_LCP_LSD_FETCH]) { if (error) { - _data_TASK_DESCRIPTION_LCP_LSD_FETCH = nil; NSLog(@"%@", [NSString stringWithFormat:@"HTTP error (TASK_DESCRIPTION_LCP_LSD_FETCH) [%@] => (%li) ... %@ [%li]", [(NSHTTPURLResponse *)task.originalRequest URL], code, error.domain, error.code]); @@ -377,7 +353,7 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task _data_TASK_DESCRIPTION_LCP_LSD_FETCH = nil; NSLog(@"%@", [NSString stringWithFormat:@"HTTP fail (TASK_DESCRIPTION_LCP_LSD_FETCH) [%@] => (%li)", [(NSHTTPURLResponse *)task.response URL], code]); - + if (!_wasCancelled) { [_statusDocumentProcessingListener onStatusDocumentProcessingComplete:self]; } @@ -491,7 +467,7 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task _data_TASK_DESCRIPTION_LCP_FETCH = nil; - NSLog(@"%@", [NSString stringWithFormat:@"HTTP error (TASK_DESCRIPTION_LCP_LSD_FETCH) [%@] => (%li) ... %@ [%li]", [(NSHTTPURLResponse *)task.originalRequest URL], code, error.domain, error.code]); + NSLog(@"%@", [NSString stringWithFormat:@"HTTP error (TASK_DESCRIPTION_LCP_FETCH) [%@] => (%li) ... %@ [%li]", [(NSHTTPURLResponse *)task.originalRequest URL], code, error.domain, error.code]); _doneCallback_fetchAndInjectUpdatedLicense(false); @@ -508,7 +484,7 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task } _data_TASK_DESCRIPTION_LCP_FETCH = nil; - NSLog(@"%@", [NSString stringWithFormat:@"HTTP fail (TASK_DESCRIPTION_LCP_LSD_FETCH) [%@] => (%li)", [(NSHTTPURLResponse *)task.response URL], code]); + NSLog(@"%@", [NSString stringWithFormat:@"HTTP fail (TASK_DESCRIPTION_LCP_FETCH) [%@] => (%li)", [(NSHTTPURLResponse *)task.response URL], code]); _doneCallback_fetchAndInjectUpdatedLicense(false); @@ -576,8 +552,16 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task _doneCallback_doRenew(false); } else { - try { + if (_data_TASK_DESCRIPTION_LCP_LSD_RENEW != nil) { + try { + NSString *msg = [[NSString alloc] initWithData:_data_TASK_DESCRIPTION_LCP_LSD_RENEW encoding:NSUTF8StringEncoding]; + NSLog(@"%@", msg); + } + catch (NSException *e) { + NSLog(@"%@", [e reason]); + } + } _data_TASK_DESCRIPTION_LCP_LSD_RENEW = nil; // forces re-check of LSD, now with updated LCP timestamp @@ -637,6 +621,15 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task } else { try { + if (_data_TASK_DESCRIPTION_LCP_LSD_RETURN != nil) { + try { + NSString *msg = [[NSString alloc] initWithData:_data_TASK_DESCRIPTION_LCP_LSD_RETURN encoding:NSUTF8StringEncoding]; + NSLog(@"%@", msg); + } + catch (NSException *e) { + NSLog(@"%@", [e reason]); + } + } _data_TASK_DESCRIPTION_LCP_LSD_RETURN = nil; // forces re-check of LSD, now with updated LCP timestamp @@ -721,7 +714,6 @@ - (bool)parseStatusDocumentJson:(NSString*)json } NSDictionary *updatedJsonDict = [rootJsonDict valueForKey:@"updated"]; - strTemp = [updatedJsonDict valueForKey:@"license"]; if (strTemp != nil) { _statusDocument_UPDATED_LICENSE = strTemp; @@ -823,7 +815,7 @@ -(bool)isInitialized { } -(bool)hasLicenseUpdatePending { - if (_statusDocument_UPDATED_LICENSE == nil) { + if (_statusDocument_UPDATED_LICENSE == nil || [_statusDocument_UPDATED_LICENSE length] == 0) { return false; } @@ -1006,7 +998,6 @@ -(void)fetchAndInjectUpdatedLicense:(DoneCallback)doneCallback_fetchAndInjectUpd [task resume]; } - -(void)doRenew:(DoneCallback)doneCallback_doRenew //void(^)(bool) { if (_statusDocument_LINK_RENEW == nil) { @@ -1033,7 +1024,6 @@ -(void)doRenew:(DoneCallback)doneCallback_doRenew //void(^)(bool) NSURL *url = [NSURL URLWithString:urlString]; - NSURLSessionConfiguration *config = [NSURLSessionConfiguration ephemeralSessionConfiguration]; NSString * locale = [[NSLocale preferredLanguages] objectAtIndex:0]; @@ -1118,18 +1108,67 @@ -(void)doReturn:(DoneCallback)doneCallback_doReturn //void(^)(bool) [task resume]; } +- (NSString *)identifier { + return _statusDocument_ID; +} + +- (NSString *)message { + return _statusDocument_MESSAGE; +} +- (NSString *)status { + return _statusDocument_STATUS; +} -(bool)isActive { return (_statusDocument_STATUS != nil && [_statusDocument_STATUS isEqualToString:@"active"]); } --(bool)hasRenewLink { +- (NSDate *)statusUpdated { + if (_statusDocument_UPDATED_STATUS != nil && [_statusDocument_UPDATED_STATUS length] > 0) { + NSISO8601DateFormatter *dateFormatter = [[NSISO8601DateFormatter alloc] init]; + return [dateFormatter dateFromString:_statusDocument_UPDATED_STATUS]; // can be nil + } + return nil; +} +- (NSDate *)licenseUpdated { + if (_statusDocument_UPDATED_LICENSE != nil && [_statusDocument_UPDATED_LICENSE length] > 0) { + NSISO8601DateFormatter *dateFormatter = [[NSISO8601DateFormatter alloc] init]; + return [dateFormatter dateFromString:_statusDocument_UPDATED_LICENSE]; // can be nil + } + return nil; +} +- (NSDate *)potentialRightsEnd { + if (_statusDocument_POTENTIAL_RIGHTS_END != nil && [_statusDocument_POTENTIAL_RIGHTS_END length] > 0) { + NSISO8601DateFormatter *dateFormatter = [[NSISO8601DateFormatter alloc] init]; + return [dateFormatter dateFromString:_statusDocument_POTENTIAL_RIGHTS_END]; // can be nil + } + return nil; +} + +- (StatusDocumentLink *)licenseLink { + return _statusDocument_LINK_LICENSE; +} + +- (bool)hasRegisterLink { + return (_statusDocument_LINK_REGISTER != nil); +} +- (StatusDocumentLink *)registerLink { + return _statusDocument_LINK_REGISTER; +} + +- (bool)hasRenewLink { return (_statusDocument_LINK_RENEW != nil); } +- (StatusDocumentLink *)renewLink { + return _statusDocument_LINK_RENEW; +} --(bool)hasReturnLink { +- (bool)hasReturnLink { return (_statusDocument_LINK_RETURN != nil); } +- (StatusDocumentLink *)returnLink { + return _statusDocument_LINK_RETURN; +} @end @@ -1147,3 +1186,4 @@ -(bool)hasReturnLink { // }); // }); +// NSLog(@"%s", __PRETTY_FUNCTION__); From 82750a79d1798bf00b8b898627e632d76333693a Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Wed, 7 Nov 2018 21:18:51 +0000 Subject: [PATCH 41/42] LCP license 'service': now with convenient utility methods to obtain information about the underlying native C++ object --- platform/apple/src/LCPLicense.h | 8 ++- platform/apple/src/LCPLicense.mm | 84 +++++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/platform/apple/src/LCPLicense.h b/platform/apple/src/LCPLicense.h index b5a4470..b6a7d11 100644 --- a/platform/apple/src/LCPLicense.h +++ b/platform/apple/src/LCPLicense.h @@ -32,15 +32,21 @@ namespace lcp { } #endif - @interface LCPLicense : NSObject @property (readonly, nonatomic) NSString *identifier; @property (readonly, nonatomic) NSString *linkPublication; @property (readonly, nonatomic) BOOL isDecrypted; +@property (readonly, nonatomic) NSString *username; @property (readonly, nonatomic) NSString *userHint; +- (NSString *)originalJSON; +- (NSString *)canonicalJSON; + +- (NSDate *)rightsStart; +- (NSDate *)rightsEnd; + #ifdef __cplusplus @property (readonly, nonatomic) lcp::ILicense *nativeLicense; - (instancetype)initWithLicense:(lcp::ILicense *)nativeLicense NS_DESIGNATED_INITIALIZER; diff --git a/platform/apple/src/LCPLicense.mm b/platform/apple/src/LCPLicense.mm index 8b218bb..a3bb0f4 100644 --- a/platform/apple/src/LCPLicense.mm +++ b/platform/apple/src/LCPLicense.mm @@ -25,11 +25,11 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #import "LCPLicense.h" - #import "ICrypto.h" #import "ILicense.h" - #import "ILinks.h" +#import "IRights.h" +#import "IUser.h" @interface LCPLicense () @property (nonatomic) lcp::ILicense *nativeLicense; @@ -77,9 +77,89 @@ - (BOOL)isDecrypted return _nativeLicense->Decrypted(); } +- (NSString *)username +{ + if (_nativeLicense->User() != NULL) { // _nativeLicense->User()->Name() can be std::string.empty(), but not nil + return [NSString stringWithUTF8String:_nativeLicense->User()->Name().c_str()]; + } + return @""; // no nil return to be consistent with the above potential missing Name() JSON value (empty std::string) +} + - (NSString *)userHint { return [NSString stringWithUTF8String:_nativeLicense->Crypto()->UserKeyHint().c_str()]; } +- (NSString *)originalJSON +{ + return [NSString stringWithUTF8String:_nativeLicense->OriginalContent().c_str()]; +} + +- (NSString *)canonicalJSON +{ + return [NSString stringWithUTF8String:_nativeLicense->CanonicalContent().c_str()]; +} + +- (NSDate *)rightsStart { + std::string start; + // _nativeLicense->Rights()->HasRightValue(lcp::StartRight) + if (_nativeLicense->Rights() != NULL && _nativeLicense->Rights()->GetRightValue(lcp::StartRight, start)) { + NSString *startDateString = [NSString stringWithUTF8String:start.c_str()]; + + NSISO8601DateFormatter *dateFormatter = [[NSISO8601DateFormatter alloc] init]; + NSDate *startDate = [dateFormatter dateFromString:startDateString]; // may be nil + return startDate; + } + return nil; + +// NSData *data = [[self canonicalJSON] dataUsingEncoding:NSUTF8StringEncoding]; +// +// NSError *error; +// NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; +// if (!jsonDictionary) { +// NSLog(@"Failed to parse license JSON: %@", error); +// return nil; +// } +// +// NSDictionary *rights = [jsonDictionary objectForKey:@"rights"]; +// if (rights == nil) { // no need to check for (id)[NSNull null] here (because source data is LCP license JSON) +// return nil; +// } +// NSString *startDateString = [rights objectForKey:@"start"]; +// if (startDateString == nil || [startDateString length] == 0) { // early exit +// return nil; +// } +} + +- (NSDate *)rightsEnd { + std::string end; + // _nativeLicense->Rights()->HasRightValue(lcp::StartRight) + if (_nativeLicense->Rights() != NULL && _nativeLicense->Rights()->GetRightValue(lcp::EndRight, end)) { + NSString *endDateString = [NSString stringWithUTF8String:end.c_str()]; + + NSISO8601DateFormatter *dateFormatter = [[NSISO8601DateFormatter alloc] init]; + NSDate *endDate = [dateFormatter dateFromString:endDateString]; // may be nil + return endDate; + } + return nil; + +// NSData *data = [[self canonicalJSON] dataUsingEncoding:NSUTF8StringEncoding]; +// +// NSError *error; +// NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; +// if (!jsonDictionary) { +// NSLog(@"Failed to parse license JSON: %@", error); +// return nil; +// } +// +// NSDictionary *rights = [jsonDictionary objectForKey:@"rights"]; +// if (rights == nil) { // no need to check for (id)[NSNull null] here (because source data is LCP license JSON) +// return nil; +// } +// NSString *endDateString = [rights objectForKey:@"end"]; +// if (endDateString == nil || [endDateString length] == 0) { // early exit +// return nil; +// } +} + @end From e4c02fdd396157062b80dcd6b787a2c6a72a0da0 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Sun, 18 Nov 2018 21:30:15 +0000 Subject: [PATCH 42/42] header function name typo --- platform/apple/src/LCPStatusDocumentProcessing.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/apple/src/LCPStatusDocumentProcessing.h b/platform/apple/src/LCPStatusDocumentProcessing.h index 8dca9e1..8b19b53 100644 --- a/platform/apple/src/LCPStatusDocumentProcessing.h +++ b/platform/apple/src/LCPStatusDocumentProcessing.h @@ -100,7 +100,7 @@ typedef void (^DoneCallback)(bool); -(StatusDocumentLink *)returnLink; -(void)doReturn:(DoneCallback)doneCallback_doReturn; //void(^)(bool) --(NSDate *)potentialRightsEndDate; +-(NSDate *)potentialRightsEnd; - (NSDate *)statusUpdated; - (NSDate *)licenseUpdated;