From 157dcd9ccac01d8b8d311a97092f5c240f496a30 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Mon, 19 Nov 2018 15:45:38 +0000 Subject: [PATCH 01/16] Android / Gradle updates (current working build): upgraded API 26 to 28, build tools to 28.0.3, Gradle 4.10.2, max processors / thread 6 (native NDK compiler), see https://github.com/readium/readium-sdk/pull/317 --- .../android/gradle/wrapper/gradle-wrapper.properties | 4 ++-- platform/android/lib/build.gradle | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/platform/android/gradle/wrapper/gradle-wrapper.properties b/platform/android/gradle/wrapper/gradle-wrapper.properties index a1347d8..e972ad2 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.4) -distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip +# GRADLE STABLE works with latest (4.10.2) +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/platform/android/lib/build.gradle b/platform/android/lib/build.gradle index 02af41a..a64b8a0 100644 --- a/platform/android/lib/build.gradle +++ b/platform/android/lib/build.gradle @@ -56,12 +56,12 @@ println "${lcpBuildContentFilter}" println "${readiumSdkLibDir}" println "${readiumSdkIncludeDir}" android { - compileSdkVersion 26 - buildToolsVersion "27.0.3" + compileSdkVersion 28 + buildToolsVersion "28.0.3" defaultConfig { minSdkVersion 19 - targetSdkVersion 26 + targetSdkVersion 28 versionCode 1 versionName "1.0" @@ -70,7 +70,8 @@ android { if (lcpBuildContentFilter) { targets "clientlib", "contentfilter", "lcp" - arguments "-DFEATURES_READIUM=1", + arguments "-DCMAKE_JOB_POOLS:STRING=compile=6;link=6", + "-DFEATURES_READIUM=1", "-DANDROID_PLATFORM=android-19", "-DANDROID_TOOLCHAIN=${toolchain}", "-DANDROID_STL=${stl}", @@ -80,7 +81,8 @@ android { } else { targets "clientlib", "lcp-min" - arguments "-DANDROID_PLATFORM=android-19", + arguments "-DCMAKE_JOB_POOLS:STRING=compile=6;link=6", + "-DANDROID_PLATFORM=android-19", "-DANDROID_TOOLCHAIN=${toolchain}", "-DANDROID_STL=${stl}", "-DRSDK_INCLUDE_DIR=${readiumSdkIncludeDir}", From a57e2a0b2ffe1a788889fceb320f317304535664 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Sat, 15 Jun 2019 14:06:58 +0100 Subject: [PATCH 02/16] support for 32 and 64 bits Android libs, with generated AARs for ARM-only, x86-only, or ARM+x86 --- platform/android/build.gradle | 15 +- platform/android/clean.sh | 2 + .../gradle/wrapper/gradle-wrapper.properties | 8 +- platform/android/lib/build.gradle | 137 +++++++++--------- .../android/lib/src/main/AndroidManifest.xml | 2 +- 5 files changed, 86 insertions(+), 78 deletions(-) diff --git a/platform/android/build.gradle b/platform/android/build.gradle index 10e11e7..f7ab5b3 100644 --- a/platform/android/build.gradle +++ b/platform/android/build.gradle @@ -1,6 +1,11 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { + google() + maven { + url "https://maven.google.com" + } + mavenCentral() jcenter() } dependencies { @@ -34,13 +39,19 @@ buildscript { 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.3" + // https://bintray.com/android/android-tools/com.android.tools.build.gradle/view + // https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google + classpath "com.android.tools.build:gradle:3.4.1" } } allprojects { repositories { + google() + maven { + url "https://maven.google.com" + } + mavenCentral() jcenter() } } diff --git a/platform/android/clean.sh b/platform/android/clean.sh index e155c5b..d160992 100644 --- a/platform/android/clean.sh +++ b/platform/android/clean.sh @@ -1,6 +1,8 @@ #!/bin/sh rm -rf build +rm -rf dist +rm -rf lib/libs rm -rf lib/build rm -rf lib/.externalNativeBuild diff --git a/platform/android/gradle/wrapper/gradle-wrapper.properties b/platform/android/gradle/wrapper/gradle-wrapper.properties index e972ad2..256d859 100644 --- a/platform/android/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/gradle/wrapper/gradle-wrapper.properties @@ -3,7 +3,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -#https://services.gradle.org/distributions -# GRADLE EXPERIMENTAL requires 3.3 -# GRADLE STABLE works with latest (4.10.2) -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip +# https://services.gradle.org/distributions +# GRADLE EXPERIMENTAL requires 3.3 (the 4.1 + 0.11.1 combo fails, see https://stackoverflow.com/questions/47057160/ ) +# GRADLE STABLE works with latest 5.4.1 +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/platform/android/lib/build.gradle b/platform/android/lib/build.gradle index a64b8a0..3a0555c 100644 --- a/platform/android/lib/build.gradle +++ b/platform/android/lib/build.gradle @@ -1,6 +1,10 @@ apply plugin: 'com.android.library' repositories { + google() + maven { + url "https://maven.google.com" + } mavenCentral() jcenter() } @@ -89,6 +93,17 @@ android { "-DRSDK_LIB_DIR=${readiumSdkLibDir}", "-DEXTRA_CMAKE=${extraCmake}" } + + if (!ndk_skipARM && !ndk_skipX86) { + abiFilters = ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'] + } else { + if (!ndk_skipARM) { + abiFilters = ['armeabi-v7a', 'arm64-v8a'] + } + if (!ndk_skipX86) { + abiFilters = ['x86', 'x86_64'] + } + } } } } @@ -138,101 +153,81 @@ android { } } + flavorDimensions "version" productFlavors { - if (!ndk_skipARM) { - arm7 { - ndk { - abiFilter 'armeabi-v7a' - } - } - } - if (!ndk_skipX86) { - x86 { + if (!ndk_skipARM && !ndk_skipX86) { + 'armeabi-v7a--arm64-v8a--x86--x86_64' { + dimension "version" 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") + abiFilters = ['armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'] } - into("${dstDirPath}") } - - // Copy shared libs - srcDirPath = "${project.projectDir}/build/intermediates/cmake/${flavor.name}/${buildType.name}/obj/${abiFilter}" - - copy { - from("${srcDirPath}") { - include("*.so") + } else { + if (!ndk_skipARM) { + 'armeabi-v7a--arm64-v8a' { + dimension "version" + ndk { + abiFilters = ['armeabi-v7a', 'arm64-v8a'] + } } - into("${dstDirPath}") } - - // Copy aar - srcDirPath = "${project.projectDir}/build/outputs/aar" - def srcFilename = "lib-${flavor.name}-${buildType.name}.aar" - - copy { - from("${srcDirPath}") { - include(srcFilename) + if (!ndk_skipX86) { + 'x86--x86_64' { + dimension "version" + ndk { + abiFilters = ['x86', 'x86_64'] + } } - into("${dstDirPath}") - rename(srcFilename, "liblcp.aar") } } } } clean.doFirst { - println("Clean dist directory") + println("Clean dist and libs directory") + def dstDirPath = "${project.projectDir}/../dist/" delete dstDirPath + + dstDirPath = "${project.projectDir}/libs/" + delete dstDirPath } task copyLibs { doLast { - println ("Copy shared library to libs") + println ("Copy 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}" + def srcDirPath_AAR = "${project.projectDir}/build/outputs/aar" + def dstDirPath_AAR = "${project.projectDir}/../dist/${buildType.name.toUpperCase()}" copy { - from("${srcDirPath}") { - include("liblcp.so") + from("${srcDirPath_AAR}") { + include("lib-${flavor.name}-${buildType.name}.aar") + } + into("${dstDirPath_AAR}") + } + + // def srcFilename = "lib-${flavor.name}-${buildType.name}.aar" + // copy { + // from("${srcDirPath_AAR}") { + // include(srcFilename) + // } + // into("${dstDirPath_AAR}") + // rename(srcFilename, "liblcp.aar") + // } + + flavor.ndk.abiFilters.each { abiFilter -> + + def srcDirPath_LIBS = "${project.projectDir}/build/intermediates/cmake/${flavor.name}/${buildType.name}/obj/${abiFilter}" + def dstDirPath_LIBS = "${project.projectDir}/libs/${buildType.name.toUpperCase()}/${abiFilter}" + + copy { + from("${srcDirPath_LIBS}") { + include("*.so", "*.a") + } + into("${dstDirPath_LIBS}") } - into("${dstDirPath}") } } } diff --git a/platform/android/lib/src/main/AndroidManifest.xml b/platform/android/lib/src/main/AndroidManifest.xml index 156d6aa..cced05b 100644 --- a/platform/android/lib/src/main/AndroidManifest.xml +++ b/platform/android/lib/src/main/AndroidManifest.xml @@ -22,6 +22,6 @@ + android:targetSdkVersion="28" /> From 0af14579b026fd8a8664ef70e85e43b4ae4c5781 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Sat, 15 Jun 2019 18:52:25 +0100 Subject: [PATCH 03/16] ReadiumSDK lib copied into LCP libs output if necessary --- platform/android/lib/build.gradle | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/platform/android/lib/build.gradle b/platform/android/lib/build.gradle index 3a0555c..53a53c4 100644 --- a/platform/android/lib/build.gradle +++ b/platform/android/lib/build.gradle @@ -228,6 +228,17 @@ task copyLibs { } into("${dstDirPath_LIBS}") } + + if (lcpBuildContentFilter) { + srcDirPath_LIBS = "${readiumSdkLibDir}/${buildType.name.toUpperCase()}/${abiFilter}" + + copy { + from("${srcDirPath_LIBS}") { + include("*.so") + } + into("${dstDirPath_LIBS}") + } + } } } } From f6f77be24a48888ae9002590288d362d801c7f6a Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Sun, 16 Jun 2019 01:37:46 +0100 Subject: [PATCH 04/16] LCP lib automatically builds ReadiumSDK --- platform/android/build.gradle | 76 +++++++------ platform/android/lib/build.gradle | 171 ++++++++++++++++++++++-------- platform/android/settings.gradle | 18 ++++ 3 files changed, 192 insertions(+), 73 deletions(-) diff --git a/platform/android/build.gradle b/platform/android/build.gradle index f7ab5b3..04c9b4a 100644 --- a/platform/android/build.gradle +++ b/platform/android/build.gradle @@ -1,4 +1,48 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. +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 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) + +def readiumSdkIncludeDir = properties.getProperty('readium.sdk_include_dir', null) +rootProject.ext.set('readium_sdk_include_dir', readiumSdkIncludeDir) + +def lcpBuildContentFilter = false +if (readiumSdkLibDir != null && readiumSdkIncludeDir != null) { + lcpBuildContentFilter = true + rootProject.ext.set('readium_lcp_build_content_filter', true) +} else { + rootProject.ext.set('readium_lcp_build_content_filter', false) +} + +// println "[[${project.name}]] (ROOT) Gradle Experimental: ${ndkExperimental}" +println "[[${project.name}]] (ROOT) Skip ARM: ${ndkSkipARM}" +println "[[${project.name}]] (ROOT) Skip x86: ${ndkSkipX86}" +println "[[${project.name}]] (ROOT) Clang: ${ndkClang}" +println "[[${project.name}]] (ROOT) readiumSdkLibDir: ${readiumSdkLibDir}" +println "[[${project.name}]] (ROOT) readiumSdkIncludeDir: ${readiumSdkIncludeDir}" +println "[[${project.name}]] (ROOT) extraCmake: ${extraCmake}" + +if (lcpBuildContentFilter) { + // include ':epub3' + // project(':epub3').projectDir = new File(rootProject.projectDir, './epub3') +} + buildscript { repositories { google() @@ -9,36 +53,6 @@ buildscript { jcenter() } dependencies { - 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 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) - - 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 // https://mvnrepository.com/artifact/com.android.tools.build/gradle?repo=google classpath "com.android.tools.build:gradle:3.4.1" diff --git a/platform/android/lib/build.gradle b/platform/android/lib/build.gradle index 53a53c4..e65aadd 100644 --- a/platform/android/lib/build.gradle +++ b/platform/android/lib/build.gradle @@ -38,28 +38,41 @@ if (rootProject.hasProperty("readium_sdk_include_dir")) { if (rootProject.hasProperty("readium_lcp_build_content_filter")) { lcpBuildContentFilter = rootProject.readium_lcp_build_content_filter } -println("extraCmake ${extraCmake}") + +// println "[[${project.name}]] (LIB) Gradle Experimental: ${ndk_experimental}" +println "[[${project.name}]] (LIB) Skip ARM: ${ndk_skipARM}" +println "[[${project.name}]] (LIB) Skip x86: ${ndk_skipX86}" +println "[[${project.name}]] (LIB) Clang: ${ndk_clang}" +println "[[${project.name}]] (LIB) extraCmake: ${extraCmake}" + def toolchain = ndk_clang ? "clang" : "gcc" def stl = ndk_clang ? "c++_shared" : "gnustl_shared" if (!lcpBuildContentFilter) { try { def epub3Dir = project(':epub3').projectDir - readiumSdkLibDir = "${epub3Dir}/libs" + readiumSdkLibDir = "${epub3Dir}/jniLibs" readiumSdkIncludeDir = "${epub3Dir}/include" lcpBuildContentFilter = true - println("Build with rsdk *") + println "[[${project.name}]] (LIB) lcpBuildContentFilter 2: ${lcpBuildContentFilter}" } catch (UnknownProjectException e) { - // No epub3 project is defined - println("Build without rsdk") + println "[[${project.name}]] (LIB) lcpBuildContentFilter 3: ${lcpBuildContentFilter}" } } else { - println("Build with rsdk") + println "[[${project.name}]] (LIB) lcpBuildContentFilter 1: ${lcpBuildContentFilter}" } -println "${lcpBuildContentFilter}" -println "${readiumSdkLibDir}" -println "${readiumSdkIncludeDir}" + +println "[[${project.name}]] (LIB) readiumSdkLibDir: ${readiumSdkLibDir}" +println "[[${project.name}]] (LIB) readiumSdkIncludeDir: ${readiumSdkIncludeDir}" + +def currentBuildType android { + libraryVariants.all { variant -> + println "[[${project.name}]] (LIB) libraryVariant buildType: ${variant.buildType.name}" + + // currentBuildType = variant.buildType.name + } + compileSdkVersion 28 buildToolsVersion "28.0.3" @@ -181,63 +194,80 @@ android { } } } + + variantFilter { variant -> + println "[[${project.name}]] (LIB) variantFilter buildType: ${variant.buildType.name}" + + // def names = variant.flavors*.name + // if (names.contains("xxx")) { + // setIgnore(true) + // } + } } clean.doFirst { - println("Clean dist and libs directory") + println "[[${project.name}]] (LIB) Remove *.so *.aar" def dstDirPath = "${project.projectDir}/../dist/" delete dstDirPath - dstDirPath = "${project.projectDir}/libs/" + dstDirPath = "${project.projectDir}/jniLibs/" delete dstDirPath } task copyLibs { doLast { - println ("Copy libs ...") - android.productFlavors.all { flavor -> - android.buildTypes.all { buildType -> + println "[[${project.name}]] (LIB) Copy *.so *.aar (${currentBuildType})" - def srcDirPath_AAR = "${project.projectDir}/build/outputs/aar" - def dstDirPath_AAR = "${project.projectDir}/../dist/${buildType.name.toUpperCase()}" - copy { - from("${srcDirPath_AAR}") { - include("lib-${flavor.name}-${buildType.name}.aar") - } - into("${dstDirPath_AAR}") - } - - // def srcFilename = "lib-${flavor.name}-${buildType.name}.aar" - // copy { - // from("${srcDirPath_AAR}") { - // include(srcFilename) - // } - // into("${dstDirPath_AAR}") - // rename(srcFilename, "liblcp.aar") - // } + android.productFlavors.all { flavor -> + println " [[${project.name}]] (LIB) productFlavor (${flavor.name})" - flavor.ndk.abiFilters.each { abiFilter -> + android.buildTypes.all { buildType -> + println " [[${project.name}]] (LIB) buildType (${buildType.name})" - def srcDirPath_LIBS = "${project.projectDir}/build/intermediates/cmake/${flavor.name}/${buildType.name}/obj/${abiFilter}" - def dstDirPath_LIBS = "${project.projectDir}/libs/${buildType.name.toUpperCase()}/${abiFilter}" + if (currentBuildType == buildType.name) { + def srcDirPath_AAR = "${project.projectDir}/build/outputs/aar" + def dstDirPath_AAR = "${project.projectDir}/../dist/${buildType.name.toUpperCase()}" copy { - from("${srcDirPath_LIBS}") { - include("*.so", "*.a") + from("${srcDirPath_AAR}") { + include("lib-${flavor.name}-${buildType.name}.aar") } - into("${dstDirPath_LIBS}") + into("${dstDirPath_AAR}") } - if (lcpBuildContentFilter) { - srcDirPath_LIBS = "${readiumSdkLibDir}/${buildType.name.toUpperCase()}/${abiFilter}" + // def srcFilename = "lib-${flavor.name}-${buildType.name}.aar" + // copy { + // from("${srcDirPath_AAR}") { + // include(srcFilename) + // } + // into("${dstDirPath_AAR}") + // rename(srcFilename, "liblcp.aar") + // } + + flavor.ndk.abiFilters.each { abiFilter -> + println " [[${project.name}]] (LIB) abiFilter (${abiFilter})" + + def srcDirPath_LIBS = "${project.projectDir}/build/intermediates/cmake/${flavor.name}/${buildType.name}/obj/${abiFilter}" + def dstDirPath_LIBS = "${project.projectDir}/jniLibs/${buildType.name.toUpperCase()}/${abiFilter}" copy { from("${srcDirPath_LIBS}") { - include("*.so") + include("*.so", "*.a") } into("${dstDirPath_LIBS}") } + + if (lcpBuildContentFilter) { + srcDirPath_LIBS = "${readiumSdkLibDir}/${buildType.name.toUpperCase()}/${abiFilter}" + + copy { + from("${srcDirPath_LIBS}") { + include("*.so") + } + into("${dstDirPath_LIBS}") + } + } } } } @@ -246,7 +276,64 @@ task copyLibs { } tasks.whenTaskAdded { task -> - if (task.name.startsWith('assemble')) { - task.dependsOn copyLibs + println "[[${project.name}]] (LIB) TaskAdded: ${task.name} (${currentBuildType})" + + if (task.name.startsWith('compile')) { + if (lcpBuildContentFilter) { + // task.dependsOn ":epub3:buildMk" + if (task.name.toLowerCase().contains("debug")) { + task.dependsOn ":rsdk:assembleDebug" + } else { + task.dependsOn ":rsdk:assembleRelease" + } + } + } + if (task.name.startsWith("assemble")) { + task.finalizedBy copyLibs } } +gradle.buildFinished { buildResult -> + println "[[${project.name}]] (LIB) buildFinished (${currentBuildType})" +} + +gradle.taskGraph.whenReady { taskGraph -> + println "[[${project.name}]] (LIB) taskGraph ready" + + // taskGraph.getAllTasks().last().finalizedBy copyLibs + taskGraph.getAllTasks().last().doLast { + println "[[${project.name}]] (LIB) last TASK (${currentBuildType})" + } // .dependsOn copyLibs + + if (taskGraph.hasTask(buildRelease)) { + println "[[${project.name}]] (LIB) taskGraph RELEASE (build)" + + currentBuildType = "release" + } else if (taskGraph.hasTask(buildDebug)) { + println "[[${project.name}]] (LIB) taskGraph DEBUG (build)" + + currentBuildType = "debug" + } else { + if (taskGraph.hasTask(assembleRelease)) { + println "[[${project.name}]] (LIB) taskGraph RELEASE (assemble)" + + currentBuildType = "release" + } + if (taskGraph.hasTask(assembleDebug)) { + println "[[${project.name}]] (LIB) taskGraph DEBUG (assemble)" + + currentBuildType = "debug" + } + } +} + +task buildRelease(type: GradleBuild, dependsOn: build) { +} + +task buildDebug(type: GradleBuild, dependsOn: build) { +} + +// task assembleRelease(type: GradleBuild, dependsOn: assemble) { +// } + +// task assembleDebug(type: GradleBuild, dependsOn: assemble) { +// } diff --git a/platform/android/settings.gradle b/platform/android/settings.gradle index 8c2a2e0..731f76f 100644 --- a/platform/android/settings.gradle +++ b/platform/android/settings.gradle @@ -1 +1,19 @@ include ':lib' + +Properties properties = new Properties() +properties.load(new File('./local.properties').newDataInputStream()) + +def readiumSdkLibDir = properties.getProperty('readium.sdk_lib_dir', null) +def readiumSdkIncludeDir = properties.getProperty('readium.sdk_include_dir', null) + +def lcpBuildContentFilter = readiumSdkLibDir != null && readiumSdkIncludeDir != null + +println "[[LCP]] (SETTINGS) readiumSdkLibDir: ${readiumSdkLibDir}" +println "[[LCP]] (SETTINGS) readiumSdkIncludeDir: ${readiumSdkIncludeDir}" + +if (lcpBuildContentFilter) { + include ':epub3' + project(':epub3').projectDir = new File(readiumSdkIncludeDir, '../') + include ':rsdk' + project(':rsdk').projectDir = new File(readiumSdkIncludeDir, '../../lib/') +} \ No newline at end of file From 0277d71d9c44d006a45fb463bdc45902e6ab30a2 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Sun, 16 Jun 2019 01:39:10 +0100 Subject: [PATCH 05/16] minor clean script addition --- platform/android/clean.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/android/clean.sh b/platform/android/clean.sh index d160992..eb2548c 100644 --- a/platform/android/clean.sh +++ b/platform/android/clean.sh @@ -4,5 +4,6 @@ rm -rf build rm -rf dist rm -rf lib/libs +rm -rf lib/jniLibs rm -rf lib/build rm -rf lib/.externalNativeBuild From 43c7c150809dd2dc78124253ffaae79a83abca4a Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Sun, 16 Jun 2019 11:07:35 +0100 Subject: [PATCH 06/16] removed obsolete statement (fixes AndroidStudio error message) --- platform/android/lib/src/main/AndroidManifest.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/android/lib/src/main/AndroidManifest.xml b/platform/android/lib/src/main/AndroidManifest.xml index cced05b..dae828e 100644 --- a/platform/android/lib/src/main/AndroidManifest.xml +++ b/platform/android/lib/src/main/AndroidManifest.xml @@ -20,8 +20,8 @@ android:versionCode="1" android:versionName="0.1" > - + + + From fb48b71913b216eab387d3094d0cd8ac48e71a31 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Fri, 5 Jul 2019 12:27:33 +0100 Subject: [PATCH 07/16] removed unnecessary makefile flags (tested, only applies to lcp-min.so lib which excludes ReadiumSDK / content module + filter) --- platform/android/lib/build.gradle | 2 -- 1 file changed, 2 deletions(-) diff --git a/platform/android/lib/build.gradle b/platform/android/lib/build.gradle index e65aadd..aa317f4 100644 --- a/platform/android/lib/build.gradle +++ b/platform/android/lib/build.gradle @@ -102,8 +102,6 @@ android { "-DANDROID_PLATFORM=android-19", "-DANDROID_TOOLCHAIN=${toolchain}", "-DANDROID_STL=${stl}", - "-DRSDK_INCLUDE_DIR=${readiumSdkIncludeDir}", - "-DRSDK_LIB_DIR=${readiumSdkLibDir}", "-DEXTRA_CMAKE=${extraCmake}" } From c9d887b60361e95257015925596004891abd2e3b Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Mon, 22 Jul 2019 15:34:04 +0100 Subject: [PATCH 08/16] ARM cross-compiler toolchain (arm-linux-gnueabi) --- platform/cross-platform/build.py | 4 ++++ platform/cross-platform/lcp.gyp | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/platform/cross-platform/build.py b/platform/cross-platform/build.py index 9316a49..3968c9d 100644 --- a/platform/cross-platform/build.py +++ b/platform/cross-platform/build.py @@ -7,6 +7,10 @@ SYSTEM = platform.system().lower() if SYSTEM == "linux": + # Use ARM cross-compiler toolchain (arm-linux-gnueabi) + # os.environ["CC"] = "arm-linux-gnueabi-gcc" + # os.environ["CXX"] = "arm-linux-gnueabi-g++" + # # Use clang on linux # print "Use clang compiler" # os.environ["CC"] = "clang" diff --git a/platform/cross-platform/lcp.gyp b/platform/cross-platform/lcp.gyp index 13aba20..8245a8d 100644 --- a/platform/cross-platform/lcp.gyp +++ b/platform/cross-platform/lcp.gyp @@ -23,8 +23,11 @@ { 'target_name': 'lcp_content_filter', 'type': 'static_library', + 'standalone_static_library': 1, 'cflags_cc': [ - '-std=c++11' + '-std=c++11', + '-frtti', + '-fexceptions', ], 'sources': [ '<@(lcp_content_filter_sources)' @@ -33,6 +36,7 @@ { 'target_name': 'lcp_client_lib', 'type': 'static_library', + 'standalone_static_library': 1, 'dependencies': [ 'cryptopp', 'zip_lib', @@ -53,6 +57,7 @@ { 'target_name': 'cryptopp', 'type': 'static_library', + 'standalone_static_library': 1, 'cflags_cc': [ '-std=c++11', '-fpermissive', @@ -66,6 +71,7 @@ { 'target_name': 'zip_lib', 'type': 'static_library', + 'standalone_static_library': 1, 'dependencies': [ 'zlib', 'bzip2' @@ -83,6 +89,7 @@ { 'target_name': 'zlib', 'type': 'static_library', + 'standalone_static_library': 1, 'sources': [ '<@(zlib_sources)' ] @@ -90,6 +97,7 @@ { 'target_name': 'bzip2', 'type': 'static_library', + 'standalone_static_library': 1, 'sources': [ '<@(bzip2_sources)' ] @@ -97,6 +105,7 @@ { 'target_name': 'time64', 'type': 'static_library', + 'standalone_static_library': 1, 'sources': [ '<@(time64_sources)' ] @@ -160,6 +169,11 @@ 'cflags': [ '-m64', '-march=x86-64', +# Use ARM cross-compiler toolchain (arm-linux-gnueabi) +# '-march=armv7-a', +# '-mthumb', +# '-mfpu=neon', +# '-mfloat-abi=hard', ], 'cflags_cc': [ ], From a2a0d249d4a0918943c5bf114a9c4da9b806fc7d Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Tue, 23 Jul 2019 16:44:26 +0100 Subject: [PATCH 09/16] added missing source files in makefile --- platform/cross-platform/filenames.gypi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/cross-platform/filenames.gypi b/platform/cross-platform/filenames.gypi index 0298447..c02f048 100644 --- a/platform/cross-platform/filenames.gypi +++ b/platform/cross-platform/filenames.gypi @@ -183,6 +183,7 @@ 'lcp_client_lib_sources': [ '<(lcp_client_lib_dir)/Acquisition.cpp', '<(lcp_client_lib_dir)/AesCbcSymmetricAlgorithm.cpp', + '<(lcp_client_lib_dir)/AesGcmSymmetricAlgorithm.cpp', '<(lcp_client_lib_dir)/AlgorithmNames.cpp', '<(lcp_client_lib_dir)/Certificate.cpp', '<(lcp_client_lib_dir)/CertificateExtension.cpp', @@ -193,6 +194,7 @@ '<(lcp_client_lib_dir)/CryptoppCryptoProvider.cpp', '<(lcp_client_lib_dir)/CryptoppUtils.cpp', '<(lcp_client_lib_dir)/DateTime.cpp', + '<(lcp_client_lib_dir)/EcdsaSha256SignatureAlgorithm.cpp', '<(lcp_client_lib_dir)/EncryptionProfileNames.cpp', '<(lcp_client_lib_dir)/EncryptionProfilesManager.cpp', '<(lcp_client_lib_dir)/JsonCanonicalizer.cpp', From f89dcacf127b7e0f526193692d5714f80cb318b7 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Thu, 25 Jul 2019 15:27:47 +0100 Subject: [PATCH 10/16] this fix introduces a KeyCheck verification for the code path that tests existing user keys available in the secret vault (as opposed to the codepath that uses the passphrase to unlock the license), see https://github.com/readium/readium-lcp-client/issues/51 --- src/lcp-client-lib/CryptoppCryptoProvider.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lcp-client-lib/CryptoppCryptoProvider.cpp b/src/lcp-client-lib/CryptoppCryptoProvider.cpp index 5db7485..7a3027c 100644 --- a/src/lcp-client-lib/CryptoppCryptoProvider.cpp +++ b/src/lcp-client-lib/CryptoppCryptoProvider.cpp @@ -295,8 +295,15 @@ namespace lcp //http://www.w3.org/2009/xmlenc11#aes256-gcm //http://www.w3.org/2001/04/xmlenc#aes256-cbc - const std::string algorithm = license->Crypto()->ContentKeyAlgorithm(); + const std::string algorithm_ = license->Crypto()->ContentKeyAlgorithm(); + std::unique_ptr contentKeyAlgorithm_(profile->CreateContentKeyAlgorithm(userKey, algorithm_)); + std::string id = contentKeyAlgorithm_->Decrypt(license->Crypto()->UserKeyCheck()); + if (!EqualsUtf8(id, license->Id())) + { + return Status(StatusCode::ErrorDecryptionUserPassphraseNotValid, "ErrorDecryptionUserPassphraseNotValid"); + } + const std::string algorithm = license->Crypto()->ContentKeyAlgorithm(); std::unique_ptr contentKeyAlgorithm(profile->CreateContentKeyAlgorithm(userKey, algorithm)); std::string decryptedContentKey = contentKeyAlgorithm->Decrypt(license->Crypto()->ContentKey()); From 1c4bb3f86b3fe6fd902cc4572a66c74f0b39e45d Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Thu, 25 Jul 2019 17:22:54 +0100 Subject: [PATCH 11/16] LCP keycheck verification must be performed on valid UTF8 characters, otherwise fatal fail uncaught exception! --- src/lcp-client-lib/CryptoppCryptoProvider.cpp | 22 +++++++++++++++---- src/lcp-client-lib/LcpUtils.cpp | 8 ++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/lcp-client-lib/CryptoppCryptoProvider.cpp b/src/lcp-client-lib/CryptoppCryptoProvider.cpp index 7a3027c..0d915bd 100644 --- a/src/lcp-client-lib/CryptoppCryptoProvider.cpp +++ b/src/lcp-client-lib/CryptoppCryptoProvider.cpp @@ -263,9 +263,16 @@ namespace lcp std::unique_ptr contentKeyAlgorithm(profile->CreateContentKeyAlgorithm(userKey2, algorithm)); std::string id = contentKeyAlgorithm->Decrypt(license->Crypto()->UserKeyCheck()); - if (!EqualsUtf8(id, license->Id())) + try + { + if (!EqualsUtf8(id, license->Id())) + { + return Status(StatusCode::ErrorDecryptionUserPassphraseNotValid, "ErrorDecryptionUserPassphraseNotValid"); + } + } + catch (const std::exception & exc) // utf8::invalid_utf8 { - return Status(StatusCode::ErrorDecryptionUserPassphraseNotValid, "ErrorDecryptionUserPassphraseNotValid"); + return Status(StatusCode::ErrorDecryptionUserPassphraseNotValid, "ErrorDecryptionUserPassphraseNotValid: " + std::string(exc.what())); } return Status(StatusCode::ErrorCommonSuccess); } @@ -298,9 +305,16 @@ namespace lcp const std::string algorithm_ = license->Crypto()->ContentKeyAlgorithm(); std::unique_ptr contentKeyAlgorithm_(profile->CreateContentKeyAlgorithm(userKey, algorithm_)); std::string id = contentKeyAlgorithm_->Decrypt(license->Crypto()->UserKeyCheck()); - if (!EqualsUtf8(id, license->Id())) + try + { + if (!EqualsUtf8(id, license->Id())) + { + return Status(StatusCode::ErrorDecryptionUserPassphraseNotValid, "ErrorDecryptionUserPassphraseNotValid"); + } + } + catch (const std::exception & exc) // utf8::invalid_utf8 { - return Status(StatusCode::ErrorDecryptionUserPassphraseNotValid, "ErrorDecryptionUserPassphraseNotValid"); + return Status(StatusCode::ErrorDecryptionUserPassphraseNotValid, "ErrorDecryptionUserPassphraseNotValid: " + std::string(exc.what())); } const std::string algorithm = license->Crypto()->ContentKeyAlgorithm(); diff --git a/src/lcp-client-lib/LcpUtils.cpp b/src/lcp-client-lib/LcpUtils.cpp index d6273cc..04b97c4 100644 --- a/src/lcp-client-lib/LcpUtils.cpp +++ b/src/lcp-client-lib/LcpUtils.cpp @@ -103,6 +103,9 @@ namespace lcp bool EqualsUtf8(const std::string & left, const std::string & right) { + ValidateUtf8(left); + ValidateUtf8(right); + Utf8ConstIt leftBeginIt(left.begin(), left.begin(), left.end()); Utf8ConstIt leftEndIt(left.end(), left.begin(), left.end()); Utf8ConstIt rightBeginIt(right.begin(), right.begin(), right.end()); @@ -112,6 +115,9 @@ namespace lcp bool LexicographicalCompareUtf8(const std::string & left, const std::string & right) { + ValidateUtf8(left); + ValidateUtf8(right); + Utf8ConstIt leftBeginIt(left.begin(), left.begin(), left.end()); Utf8ConstIt leftEndIt(left.end(), left.begin(), left.end()); Utf8ConstIt rightBeginIt(right.begin(), right.begin(), right.end()); @@ -119,4 +125,4 @@ namespace lcp return std::lexicographical_compare(leftBeginIt, leftEndIt, rightBeginIt, rightEndIt); } -} \ No newline at end of file +} From 534a0144cc935f2dc2260a97cc4e26830be20a84 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Thu, 25 Jul 2019 18:11:32 +0100 Subject: [PATCH 12/16] Linux 32/64 bits build config --- platform/cross-platform/build.py | 12 +++++------- platform/cross-platform/lcp.gyp | 10 +++++----- 2 files changed, 10 insertions(+), 12 deletions(-) mode change 100644 => 100755 platform/cross-platform/build.py mode change 100644 => 100755 platform/cross-platform/lcp.gyp diff --git a/platform/cross-platform/build.py b/platform/cross-platform/build.py old mode 100644 new mode 100755 index 3968c9d..6d7f5e9 --- a/platform/cross-platform/build.py +++ b/platform/cross-platform/build.py @@ -7,14 +7,12 @@ SYSTEM = platform.system().lower() if SYSTEM == "linux": - # Use ARM cross-compiler toolchain (arm-linux-gnueabi) - # os.environ["CC"] = "arm-linux-gnueabi-gcc" - # os.environ["CXX"] = "arm-linux-gnueabi-g++" - # # Use clang on linux # print "Use clang compiler" - # os.environ["CC"] = "clang" - # os.environ["CXX"] = "clang++" + # sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi + # sudo apt-get install libc6-armel-cross libc6-dev-armel-cross binutils-arm-linux-gnueabi libncurses5-dev + # os.environ["CC"] = "arm-linux-gnueabi-gcc" + # os.environ["CXX"] = "arm-linux-gnueabi-g++" # os.environ["GYP_DEFINES"] = "clang=1" GYP_OS = "linux" elif SYSTEM == "windows": @@ -46,4 +44,4 @@ if SYSTEM == "windows": cmd = ["vcvarsall.bat", "&&"] + cmd -utils.execute_command(cmd) \ No newline at end of file +utils.execute_command(cmd) diff --git a/platform/cross-platform/lcp.gyp b/platform/cross-platform/lcp.gyp old mode 100644 new mode 100755 index 8245a8d..721e90e --- a/platform/cross-platform/lcp.gyp +++ b/platform/cross-platform/lcp.gyp @@ -16,6 +16,7 @@ '-g', # Debug mode ], 'defines': [ + 'ENABLE_NET_PROVIDER_ACQUISITION=1', 'BUILDING_EPUB3' ] }, @@ -169,11 +170,10 @@ 'cflags': [ '-m64', '-march=x86-64', -# Use ARM cross-compiler toolchain (arm-linux-gnueabi) -# '-march=armv7-a', -# '-mthumb', -# '-mfpu=neon', -# '-mfloat-abi=hard', +# '-march=armv7-a', +# '-mthumb', +# '-mfpu=neon', +# '-mfloat-abi=hard', ], 'cflags_cc': [ ], From 06e26e712aa584daf200b5d2c2f3699433c9cde9 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Thu, 3 Oct 2019 22:52:54 +0100 Subject: [PATCH 13/16] RapidJSON usage bug! This fixes application crash when UserRights in LCP license is undefined (absent property). The bug was due to the RapidJSON move semantics not copying the allocator in Value objects (only in Document objects) when return a function value. Works fine in function parameters, due to the stacking memory context. Without this fix, the GetType() function returns 16 (or some other weird value) instead of zero for kNullType enum, and isNull() returns false due to internal mismatch in the mask value. https://github.com/Tencent/rapidjson/blob/master/include/rapidjson/document.h#L1954 https://rapidjson.org/md_doc_tutorial.html#TemporaryValues https://github.com/Tencent/rapidjson/issues/387#issuecomment-122067853 --- src/lcp-client-lib/JsonValueReader.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/lcp-client-lib/JsonValueReader.cpp b/src/lcp-client-lib/JsonValueReader.cpp index 7ffc771..9383e38 100644 --- a/src/lcp-client-lib/JsonValueReader.cpp +++ b/src/lcp-client-lib/JsonValueReader.cpp @@ -63,7 +63,13 @@ namespace lcp { return it->value; } - return rapidjson::Value(rapidjson::kNullType).Move(); + + // https://rapidjson.org/md_doc_tutorial.html#TemporaryValues + // https://github.com/Tencent/rapidjson/issues/387#issuecomment-122067853 + // std::move() not needed (same as other returns, like it->value above) + // rapidjson::Value(rapidjson::kNullType).Move(); + // rapidjson::Value().SetNull()); + return rapidjson::Document().SetNull(); // THIS WORKS!! (allocator is preserved) } const rapidjson::Value & JsonValueReader::ReadArrayCheck(const std::string & name, const rapidjson::Value & jsonValue) @@ -83,7 +89,13 @@ namespace lcp { return it->value; } - return rapidjson::Value(rapidjson::kNullType).Move(); + + // https://rapidjson.org/md_doc_tutorial.html#TemporaryValues + // https://github.com/Tencent/rapidjson/issues/387#issuecomment-122067853 + // std::move() not needed (same as other returns, like it->value above) + // rapidjson::Value(rapidjson::kNullType).Move(); + // rapidjson::Value().SetNull()); + return rapidjson::Document().SetNull(); // THIS WORKS!! (allocator is preserved) } const rapidjson::Value & JsonValueReader::ReadObjectCheck(const std::string & name, const rapidjson::Value & jsonValue) From 25d2e375bc86e662e5611714d18a3c992145641a Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Tue, 7 Jan 2020 22:41:43 +0000 Subject: [PATCH 14/16] fix for edge-case whereby last AES-256-CBC block (16 bytes) is entirely padding (W3C with zeros or PKCS), as opposed to partial padding. In other words, zero-padding actually never occurs (even for cypher data that is exactly a multiple of block size), instead a full block is allocated and suffixed to the cypher stream. The general case of partial padding between 1-15 bytes was working fine, this fix adds support for the edge case of zero-padding (full 16-bytes padding block) --- .../AesCbcSymmetricAlgorithm.cpp | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/lcp-client-lib/AesCbcSymmetricAlgorithm.cpp b/src/lcp-client-lib/AesCbcSymmetricAlgorithm.cpp index 9f28986..2917ed9 100644 --- a/src/lcp-client-lib/AesCbcSymmetricAlgorithm.cpp +++ b/src/lcp-client-lib/AesCbcSymmetricAlgorithm.cpp @@ -108,23 +108,29 @@ namespace lcp throw std::out_of_range("Invalid encrypted file, size is out of range"); } + // we read the last two 16-bytes AES blocks (first one is IV for second) size_t readPosition = static_cast(stream->Size()) - (CryptoPP::AES::BLOCKSIZE + CryptoPP::AES::BLOCKSIZE); stream->SetReadPosition(readPosition); std::vector inBuffer(CryptoPP::AES::BLOCKSIZE + CryptoPP::AES::BLOCKSIZE); - std::vector outBuffer(inBuffer.size()); stream->Read(&inBuffer.at(0), inBuffer.size()); + std::vector outBuffer(CryptoPP::AES::BLOCKSIZE); // we only decrypt the last 16-bytes AES block size_t outSize = this->InnerDecrypt( &inBuffer.at(0), inBuffer.size(), &outBuffer.at(0), outBuffer.size(), - BlockPaddingSchemeDef::W3C_PADDING // Note that handling of W3C padding scheme during decryption also handles PKCS#7 (which is BlockPaddingSchemeDef::PKCS_PADDING in CryptoPP, with AES CBC Block Size > 8 (not PKCS#5)) + BlockPaddingSchemeDef::NO_PADDING // if W3C_PADDING and padding length == full-length 16-bytes AES padding block, then outSize is ZERO ); + // BlockPaddingSchemeDef::W3C_PADDING => ZERO for all unused bytes in the 16-bytes AES block, except for the last one which corresponds to the padding length. + // BlockPaddingSchemeDef::PKCS_PADDING (PKCS#7) => stores the padding length in ALL unused bytes in the 16-bytes AES block. + // Even when padding is not needed (because encrypted data is exactly a multiple of 16-bytes AES block size), there is a trailing padding block with the sole purpose of informing the presence of this full-length 16-bytes padding block. + size_t paddingSize = static_cast(outBuffer[outBuffer.size() - 1]); + return static_cast(stream->Size()) - CryptoPP::AES::BLOCKSIZE // minus IV or previous block - - (CryptoPP::AES::BLOCKSIZE - outSize) % CryptoPP::AES::BLOCKSIZE; // minus padding part + - paddingSize; } void AesCbcSymmetricAlgorithm::Decrypt( @@ -166,23 +172,24 @@ namespace lcp blocksCount++; } - // Figure out what padding scheme to use - BlockPaddingSchemeDef::BlockPaddingScheme padding = BlockPaddingSchemeDef::NO_PADDING; - size_t sizeWithoutPaddedBlock = plainTextSize - (plainTextSize % CryptoPP::AES::BLOCKSIZE); - if (rangeInfo.position + rangeInfo.length > sizeWithoutPaddedBlock) - { - padding = BlockPaddingSchemeDef::W3C_PADDING; // Note that handling of W3C padding scheme during decryption also handles PKCS#7 (which is BlockPaddingSchemeDef::PKCS_PADDING in CryptoPP, with AES CBC Block Size > 8 (not PKCS#5)) - } - // Read data from the stream stream->SetReadPosition(readPosition); std::vector inBuffer(blocksCount * CryptoPP::AES::BLOCKSIZE); std::vector outBuffer(inBuffer.size()); - if (readPosition + inBuffer.size() > stream->Size()) + int64_t total = readPosition + inBuffer.size(); + int64_t ssize = stream->Size(); + if (total > ssize) { throw std::out_of_range("encrypted stream is out of range"); } stream->Read(&inBuffer.at(0), inBuffer.size()); + + // Figure out what padding scheme to use + BlockPaddingSchemeDef::BlockPaddingScheme padding = BlockPaddingSchemeDef::NO_PADDING; + if (total > (ssize - CryptoPP::AES::BLOCKSIZE)) + { + padding = BlockPaddingSchemeDef::W3C_PADDING; // Note that handling of W3C padding scheme during decryption also handles PKCS#7 (which is BlockPaddingSchemeDef::PKCS_PADDING in CryptoPP, with AES CBC Block Size > 8 (not PKCS#5)) + } // Decrypt and copy necessary data size_t outSize = this->InnerDecrypt( From 21c1ecf43573728279f7e127193f791a17e5a299 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Wed, 29 Jan 2020 11:59:20 +0000 Subject: [PATCH 15/16] minor: chmod a+x on clean script --- platform/android/clean.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 platform/android/clean.sh diff --git a/platform/android/clean.sh b/platform/android/clean.sh old mode 100644 new mode 100755 From e396cd0142f9aa613a3b9244462f28281907c7d7 Mon Sep 17 00:00:00 2001 From: Daniel Weck Date: Mon, 20 Jul 2020 16:12:43 +0100 Subject: [PATCH 16/16] XCFramework build config and script --- .../LCP Client.xcodeproj/project.pbxproj | 10 ++++- platform/apple/xcframework.sh | 45 +++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100755 platform/apple/xcframework.sh diff --git a/platform/apple/LCP Client.xcodeproj/project.pbxproj b/platform/apple/LCP Client.xcodeproj/project.pbxproj index f6c011e..baea62c 100644 --- a/platform/apple/LCP Client.xcodeproj/project.pbxproj +++ b/platform/apple/LCP Client.xcodeproj/project.pbxproj @@ -723,6 +723,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = 5ACE2E021BF21D7900AC0585; @@ -884,6 +885,7 @@ baseConfigurationReference = 5ACE2E7D1BF21EBE00AC0585 /* LCP Client.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -938,6 +940,7 @@ baseConfigurationReference = 5ACE2E7D1BF21EBE00AC0585 /* LCP Client.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + BUILD_LIBRARY_FOR_DISTRIBUTION = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -986,11 +989,13 @@ isa = XCBuildConfiguration; baseConfigurationReference = 5A2496AE1C620ECA00EABFFC /* LCP Client (iOS).xcconfig */; buildSettings = { - IPHONEOS_DEPLOYMENT_TARGET = 10.2; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/third-parties/cryptopp/lib", ); + ONLY_ACTIVE_ARCH = YES; + OTHER_CFLAGS = "-fembed-bitcode"; OTHER_LDFLAGS = "-ObjC"; SKIP_INSTALL = YES; }; @@ -1000,11 +1005,12 @@ isa = XCBuildConfiguration; baseConfigurationReference = 5A2496AE1C620ECA00EABFFC /* LCP Client (iOS).xcconfig */; buildSettings = { - IPHONEOS_DEPLOYMENT_TARGET = 10.2; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/third-parties/cryptopp/lib", ); + OTHER_CFLAGS = "-fembed-bitcode"; OTHER_LDFLAGS = "-ObjC"; SKIP_INSTALL = YES; }; diff --git a/platform/apple/xcframework.sh b/platform/apple/xcframework.sh new file mode 100755 index 0000000..1746b94 --- /dev/null +++ b/platform/apple/xcframework.sh @@ -0,0 +1,45 @@ +####### +#xcode-select --install +#sudo xcode-select --switch /Library/Developer/CommandLineTools +#sudo xcode-select -s /Applications/Xcode.app/Contents/Developer +####### + +rm -rf "./archives/LCP Client (iOS) DEVICE" +rm -rf "./archives/LCP Client (iOS) SIMULATOR" + +xcodebuild archive \ +-project "LCP Client.xcodeproj" \ +-scheme "LCP Client (iOS)" \ +-destination "generic/platform=iOS" \ +-archivePath "./archives/LCP Client (iOS) DEVICE" \ +SKIP_INSTALL=NO \ +BUILD_LIBRARY_FOR_DISTRIBUTION=YES + +xcodebuild archive \ +-project "LCP Client.xcodeproj" \ +-scheme "LCP Client (iOS)" \ +-destination "generic/platform=iOS Simulator" \ +-archivePath "./archives/LCP Client (iOS) SIMULATOR" \ +SKIP_INSTALL=NO \ +BUILD_LIBRARY_FOR_DISTRIBUTION=YES + +rm -rf "./archives/LCP_iOS.xcframework" + +mkdir "./archives/headers" +ls -als "../../src/lcp-content-filter/public" | grep "\\.h[p]*" +ls -als "../../src/lcp-client-lib/public" | grep "\\.h[p]*" +ls -als "./src" | grep "\\.h[p]*" +cp ../../src/lcp-content-filter/public/*.h "./archives/headers/" +cp ../../src/lcp-client-lib/public/*.h "./archives/headers/" +cp ./src/*.h "./archives/headers/" +rm "./archives/headers/lcp.h" +ls -als "./archives/headers" + +xcodebuild -create-xcframework \ +-library "./archives/LCP Client (iOS) DEVICE.xcarchive/Products/usr/local/lib/libLCP-client-iOS.a" \ +-headers "./archives/headers" \ +-library "./archives/LCP Client (iOS) SIMULATOR.xcarchive/Products/usr/local/lib/libLCP-client-iOS.a" \ +-headers "./archives/headers" \ +-output "./archives/LCP_iOS.xcframework" + +ls -alsR "./archives/LCP_iOS.xcframework"