From d577228bbda482d469f7417681c4b00fff54d100 Mon Sep 17 00:00:00 2001 From: Alexei Lozovsky Date: Sat, 9 May 2020 15:52:42 +0300 Subject: [PATCH 1/5] Make minimum SDK version configurable In some use cases it's necessary to support older systems. Currently minimum SDK versions are set to reasonable defaults, but there is no easy way to override them. Introduce a new set of command-line flags to set different minimum SDK versions, similar to how it's possible to override the default target SDK version: --min-macos-sdk --min-ios-sdk --min-tvos-sdk --min-watchos-sdk Also, output the selected minimum SDK version along with the target one on the configuration readout. It makes it easier to confirm that the configuration is the one you expect. --- build-libssl.sh | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/build-libssl.sh b/build-libssl.sh index d381ada..13dbd38 100755 --- a/build-libssl.sh +++ b/build-libssl.sh @@ -53,8 +53,13 @@ echo_help() echo " -h, --help Print help (this message)" echo " --macos-sdk=SDKVERSION Override macOS SDK version" echo " --ios-sdk=SDKVERSION Override iOS SDK version" - echo " --noparallel Disable running make with parallel jobs (make -j)" echo " --tvos-sdk=SDKVERSION Override tvOS SDK version" + echo " --watchos-sdk=SDKVERSION Override watchOS SDK version" + echo " --min-macos-sdk=SDKVERSION Set minimum macOS SDK version (default: $MACOS_MIN_SDK_VERSION)" + echo " --min-ios-sdk=SDKVERSION Set minimum iOS SDK version (default: $IOS_MIN_SDK_VERSION)" + echo " --min-tvos-sdk=SDKVERSION Set minimum tvOS SDK version (default: $TVOS_MIN_SDK_VERSION)" + echo " --min-watchos-sdk=SDKVERSION Set minimum watchOS SDK version (default: $WATCHOS_MIN_SDK_VERSION)" + echo " --noparallel Disable running make with parallel jobs (make -j)" echo " --disable-bitcode Disable embedding Bitcode" echo " -v, --verbose Enable verbose logging" echo " --verbose-on-error Dump last 500 lines from log file if an error occurs (for Travis builds)" @@ -265,6 +270,22 @@ case $i in WATCHOS_SDKVERSION="${i#*=}" shift ;; + --min-macos-sdk=*) + MACOS_MIN_SDK_VERSION="${i#*=}" + shift + ;; + --min-ios-sdk=*) + IOS_MIN_SDK_VERSION="${i#*=}" + shift + ;; + --min-tvos-sdk=*) + TVOS_MIN_SDK_VERSION="${i#*=}" + shift + ;; + --min-watchos-sdk=*) + WATCHOS_MIN_SDK_VERSION="${i#*=}" + shift + ;; -v|--verbose) LOG_VERBOSE="verbose" ;; @@ -413,10 +434,10 @@ if [ "${BUILD_TYPE}" == "archs" ]; then else echo " Targets: ${TARGETS}" fi -echo " macOS SDK: ${MACOS_SDKVERSION}" -echo " iOS SDK: ${IOS_SDKVERSION}" -echo " tvOS SDK: ${TVOS_SDKVERSION}" -echo " watchOS SDK: ${WATCHOS_SDKVERSION}" +echo " macOS SDK: ${MACOS_SDKVERSION} (min ${MACOS_MIN_SDK_VERSION})" +echo " iOS SDK: ${IOS_SDKVERSION} (min ${IOS_MIN_SDK_VERSION})" +echo " tvOS SDK: ${TVOS_SDKVERSION} (min ${TVOS_MIN_SDK_VERSION})" +echo " watchOS SDK: ${WATCHOS_SDKVERSION} (min ${WATCHOS_MIN_SDK_VERSION})" if [ "${CONFIG_DISABLE_BITCODE}" == "true" ]; then echo " Bitcode embedding disabled" fi From 54315154fbb65b7f7a0dfd5acba46adde9285d3c Mon Sep 17 00:00:00 2001 From: Alexei Lozovsky Date: Sat, 9 May 2020 16:51:57 +0300 Subject: [PATCH 2/5] Set accurate minimum SDK version in dylibs We should set accurate minimum SDK version in produced dylibs. Otherwise the individual versions of object files are ignored and we end up with a file that may have higher minimum SDK version than requested. Since here we don't have access to *_MIN_SDK_VERSION variables set in build-libssl.sh, retrieve the minimum SDK version from the object files. This give accurate information. Parse "otool -l" output for that. It's more or less simple, once you account for peculiarities. --- create-openssl-framework.sh | 54 ++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/create-openssl-framework.sh b/create-openssl-framework.sh index 8506d10..42a2603 100755 --- a/create-openssl-framework.sh +++ b/create-openssl-framework.sh @@ -39,6 +39,45 @@ function check_bitcode() { fi } +# Inspect Mach-O load commands to get minimum SDK version. +# +# Depending on the actual minimum SDK version it may look like this +# (for modern SDKs): +# +# Load command 1 +# cmd LC_BUILD_VERSION +# cmdsize 24 +# platform 8 +# sdk 13.2 <-- target SDK +# minos 12.0 <-- minimum SDK +# ntools 0 +# +# Or like this for older versions, with a platform-dependent tag: +# +# Load command 1 +# cmd LC_VERSION_MIN_WATCHOS +# cmdsize 16 +# version 4.0 <-- minimum SDK +# sdk 6.1 <-- target SDK +function get_min_sdk() { + local file=$1 + set +o pipefail + otool -l "$file" | awk " + /^Load command/ { + last_command = \"\" + } + \$1 == \"cmd\" { + last_command = \$2 + } + (last_command ~ /LC_BUILD_VERSION/ && \$1 == \"minos\") || + (last_command ~ /^LC_VERSION_MIN_/ && \$1 == \"version\") { + print \$2 + exit + } + " + set -o pipefail +} + if [ $FWTYPE == "dynamic" ]; then DEVELOPER=`xcode-select -print-path` FW_EXEC_NAME="${FWNAME}.framework/${FWNAME}" @@ -62,20 +101,21 @@ if [ $FWTYPE == "dynamic" ]; then CROSS_SDK="${PLATFORM}${SDKVERSION}.sdk" SDK="${CROSS_TOP}/SDKs/${CROSS_SDK}" + MIN_SDK_VERSION=$(get_min_sdk "${TARGETDIR}/lib/libcrypto.a") if [[ $PLATFORM == AppleTVSimulator* ]]; then - MIN_SDK="-tvos_simulator_version_min 11.0" + MIN_SDK="-tvos_simulator_version_min $MIN_SDK_VERSION" elif [[ $PLATFORM == AppleTV* ]]; then - MIN_SDK="-tvos_version_min 11.0" + MIN_SDK="-tvos_version_min $MIN_SDK_VERSION" elif [[ $PLATFORM == MacOSX* ]]; then - MIN_SDK="-macosx_version_min 10.11" + MIN_SDK="-macosx_version_min $MIN_SDK_VERSION" elif [[ $PLATFORM == iPhoneSimulator* ]]; then - MIN_SDK="-ios_simulator_version_min 11.0" + MIN_SDK="-ios_simulator_version_min $MIN_SDK_VERSION" elif [[ $PLATFORM == WatchOS* ]]; then - MIN_SDK="-watchos_version_min 4.0" + MIN_SDK="-watchos_version_min $MIN_SDK_VERSION" elif [[ $PLATFORM == WatchSimulator* ]]; then - MIN_SDK="-watchos_simulator_version_min 4.0" + MIN_SDK="-watchos_simulator_version_min $MIN_SDK_VERSION" else - MIN_SDK="-ios_version_min 11.0" + MIN_SDK="-ios_version_min $MIN_SDK_VERSION" fi #cd $TARGETDIR From 5d14c910747bb0b1cbc5fdcb35043681a5dfc93a Mon Sep 17 00:00:00 2001 From: Alexei Lozovsky Date: Sat, 9 May 2020 17:45:50 +0300 Subject: [PATCH 3/5] Set accurate minimum SDK version in Info.plist It is also necessary to set matching minimum SDK version in Info.plist file of the frameworks. Extract the version and replace it in Info.plist by pattern. --- assets/AppleTV/Info.plist | 2 +- assets/MacOSX/Info.plist | 2 +- assets/WatchOS/Info.plist | 2 +- assets/iPhone/Info.plist | 2 +- create-openssl-framework.sh | 6 ++++++ 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/assets/AppleTV/Info.plist b/assets/AppleTV/Info.plist index d18bc32..bb6bd7a 100755 --- a/assets/AppleTV/Info.plist +++ b/assets/AppleTV/Info.plist @@ -19,6 +19,6 @@ CFBundleVersion 1 MinimumOSVersion - 11.0 + $(MIN_SDK_VERSION) diff --git a/assets/MacOSX/Info.plist b/assets/MacOSX/Info.plist index ad76608..bb6bd7a 100755 --- a/assets/MacOSX/Info.plist +++ b/assets/MacOSX/Info.plist @@ -19,6 +19,6 @@ CFBundleVersion 1 MinimumOSVersion - 10.11 + $(MIN_SDK_VERSION) diff --git a/assets/WatchOS/Info.plist b/assets/WatchOS/Info.plist index b5d8c76..bb6bd7a 100755 --- a/assets/WatchOS/Info.plist +++ b/assets/WatchOS/Info.plist @@ -19,6 +19,6 @@ CFBundleVersion 1 MinimumOSVersion - 4.0 + $(MIN_SDK_VERSION) diff --git a/assets/iPhone/Info.plist b/assets/iPhone/Info.plist index d18bc32..bb6bd7a 100755 --- a/assets/iPhone/Info.plist +++ b/assets/iPhone/Info.plist @@ -19,6 +19,6 @@ CFBundleVersion 1 MinimumOSVersion - 11.0 + $(MIN_SDK_VERSION) diff --git a/create-openssl-framework.sh b/create-openssl-framework.sh index 42a2603..0fafd9f 100755 --- a/create-openssl-framework.sh +++ b/create-openssl-framework.sh @@ -157,6 +157,9 @@ if [ $FWTYPE == "dynamic" ]; then lipo -create ${DYLIBS[@]} -output $FWDIR/$FWNAME cp -r include/$FWNAME/* $FWDIR/Headers/ cp -L assets/$SYS/Info.plist $FWDIR/Info.plist + MIN_SDK_VERSION=$(get_min_sdk "$FWDIR/$FWNAME") + sed -e "s/\\\$(MIN_SDK_VERSION)/$MIN_SDK_VERSION/g" \ + -i '' "$FWDIR/Info.plist" echo "Created $FWDIR" check_bitcode $FWDIR else @@ -176,6 +179,9 @@ else libtool -static -o $FWDIR/$FWNAME lib/libcrypto-$SYS.a lib/libssl-$SYS.a cp -r include/$FWNAME/* $FWDIR/Headers/ cp -L assets/$SYS/Info.plist $FWDIR/Info.plist + MIN_SDK_VERSION=$(get_min_sdk "$FWDIR/$FWNAME") + sed -e "s/\\\$(MIN_SDK_VERSION)/$MIN_SDK_VERSION/g" \ + -i '' "$FWDIR/Info.plist" echo "Created $FWDIR" check_bitcode $FWDIR else From fb997dc62fb94e9a13da6e6cbb472cc7face79c9 Mon Sep 17 00:00:00 2001 From: Alexei Lozovsky Date: Sat, 9 May 2020 18:24:48 +0300 Subject: [PATCH 4/5] Set OpenSSL version in CFBundleShortVersionString Some vulnerability analysis tools look at this 'marketing version' string to determine the version of OpenSSL library. Keep the actual version there to make the tools happy. Otherwise they tend to treat OpenSSL 1.0 to be massively vulnerable. Since we don't have access to OPENSSL_VERSION from build-libssl.sh, extract the version from OpenSSL header files. --- assets/AppleTV/Info.plist | 2 +- assets/MacOSX/Info.plist | 2 +- assets/WatchOS/Info.plist | 2 +- assets/iPhone/Info.plist | 2 +- create-openssl-framework.sh | 22 ++++++++++++++++++++++ 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/assets/AppleTV/Info.plist b/assets/AppleTV/Info.plist index bb6bd7a..0cd9882 100755 --- a/assets/AppleTV/Info.plist +++ b/assets/AppleTV/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + $(OPENSSL_VERSION) CFBundleVersion 1 MinimumOSVersion diff --git a/assets/MacOSX/Info.plist b/assets/MacOSX/Info.plist index bb6bd7a..0cd9882 100755 --- a/assets/MacOSX/Info.plist +++ b/assets/MacOSX/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + $(OPENSSL_VERSION) CFBundleVersion 1 MinimumOSVersion diff --git a/assets/WatchOS/Info.plist b/assets/WatchOS/Info.plist index bb6bd7a..0cd9882 100755 --- a/assets/WatchOS/Info.plist +++ b/assets/WatchOS/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + $(OPENSSL_VERSION) CFBundleVersion 1 MinimumOSVersion diff --git a/assets/iPhone/Info.plist b/assets/iPhone/Info.plist index bb6bd7a..0cd9882 100755 --- a/assets/iPhone/Info.plist +++ b/assets/iPhone/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + $(OPENSSL_VERSION) CFBundleVersion 1 MinimumOSVersion diff --git a/create-openssl-framework.sh b/create-openssl-framework.sh index 0fafd9f..35c63ee 100755 --- a/create-openssl-framework.sh +++ b/create-openssl-framework.sh @@ -78,6 +78,24 @@ function get_min_sdk() { set -o pipefail } +# Read OpenSSL version from opensslv.h file. +# +# In modern OpenSSL releases the version line looks like this: +# +# # define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1g 21 Apr 2020" +# +# But for older versions with FIPS module it may look like this: +# +# # ifdef OPENSSL_FIPS +# # define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2u-fips 20 Dec 2019" +# # else +# # define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2u 20 Dec 2019" +# # endif +function get_openssl_version() { + local opensslv=$1 + awk '/define OPENSSL_VERSION_TEXT/ && !/-fips/ {print $5}' "$opensslv" +} + if [ $FWTYPE == "dynamic" ]; then DEVELOPER=`xcode-select -print-path` FW_EXEC_NAME="${FWNAME}.framework/${FWNAME}" @@ -158,7 +176,9 @@ if [ $FWTYPE == "dynamic" ]; then cp -r include/$FWNAME/* $FWDIR/Headers/ cp -L assets/$SYS/Info.plist $FWDIR/Info.plist MIN_SDK_VERSION=$(get_min_sdk "$FWDIR/$FWNAME") + OPENSSL_VERSION=$(get_openssl_version "$FWDIR/Headers/opensslv.h") sed -e "s/\\\$(MIN_SDK_VERSION)/$MIN_SDK_VERSION/g" \ + -e "s/\\\$(OPENSSL_VERSION)/$OPENSSL_VERSION/g" \ -i '' "$FWDIR/Info.plist" echo "Created $FWDIR" check_bitcode $FWDIR @@ -180,7 +200,9 @@ else cp -r include/$FWNAME/* $FWDIR/Headers/ cp -L assets/$SYS/Info.plist $FWDIR/Info.plist MIN_SDK_VERSION=$(get_min_sdk "$FWDIR/$FWNAME") + OPENSSL_VERSION=$(get_openssl_version "$FWDIR/Headers/opensslv.h") sed -e "s/\\\$(MIN_SDK_VERSION)/$MIN_SDK_VERSION/g" \ + -e "s/\\\$(OPENSSL_VERSION)/$OPENSSL_VERSION/g" \ -i '' "$FWDIR/Info.plist" echo "Created $FWDIR" check_bitcode $FWDIR From 3d03ccc56ab8f702bfa0790c9df79306e46427e7 Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Tue, 12 May 2020 12:38:20 +0200 Subject: [PATCH 5/5] Normalize OpenSSL version for App Store --- create-openssl-framework.sh | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/create-openssl-framework.sh b/create-openssl-framework.sh index 35c63ee..e6ce8bd 100755 --- a/create-openssl-framework.sh +++ b/create-openssl-framework.sh @@ -91,9 +91,26 @@ function get_min_sdk() { # # else # # define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2u 20 Dec 2019" # # endif +# +# For App Store validation purposes, replace trailing letter with +# 2-digit offset from 'a' (ASCII 97), plus 1 for 1-based +# +# 1.0.2u +# 'u' = 117 -> 20 + 1 = 21 +# 1.0.221 +# +# 1.1.1g +# 'g' = 103 -> 6 + 1 = 07 (zero-padded) +# 1.1.107 +# function get_openssl_version() { local opensslv=$1 - awk '/define OPENSSL_VERSION_TEXT/ && !/-fips/ {print $5}' "$opensslv" + local std_version=$(awk '/define OPENSSL_VERSION_TEXT/ && !/-fips/ {print $5}' "$opensslv") + local generic_version=${std_version%?} + local subpatch=${std_version: -1} + local subpatch_number=$(($(printf '%d' \'$subpatch) - 97 + 1)) + local normalized_version="${generic_version}$(printf '%02d' $subpatch_number)" + echo $normalized_version } if [ $FWTYPE == "dynamic" ]; then