From 9f7c094f9f00a6efc0107071f109ef1bc4d7357d Mon Sep 17 00:00:00 2001 From: Gil Date: Fri, 19 Jan 2018 12:20:46 -0800 Subject: Add platform detection logic for SecureRandom (#676) * Add CMake platform detection logic for SecureRandom Now only builds secure_random_arc4random.cc if available. Remove firebase/firestore/base/port.h. Nothing else was in that directory. * Add a SecureRandom implementation that uses OpenSSL This is usable on Linux, Windows, and Android * Properly check return from RAND_bytes --- .gitignore | 3 ++ FirebaseFirestore.podspec | 11 +++++- Firestore/CMakeLists.txt | 3 ++ Firestore/core/src/firebase/firestore/base/port.h | 33 ---------------- .../src/firebase/firestore/util/CMakeLists.txt | 45 ++++++++++++++++++++- .../core/src/firebase/firestore/util/config.h.in | 35 ++++++++++++++++ .../firestore/util/secure_random_arc4random.cc | 2 +- .../firestore/util/secure_random_openssl.cc | 46 ++++++++++++++++++++++ .../test/firebase/firestore/util/CMakeLists.txt | 21 +++++++++- 9 files changed, 161 insertions(+), 38 deletions(-) delete mode 100644 Firestore/core/src/firebase/firestore/base/port.h create mode 100644 Firestore/core/src/firebase/firestore/util/config.h.in create mode 100644 Firestore/core/src/firebase/firestore/util/secure_random_openssl.cc diff --git a/.gitignore b/.gitignore index 79daac4..7645c89 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,9 @@ Pods/ Podfile.lock *.xcworkspace +# Firestore's build configuration, as generated by CocoaPods +Firestore/core/src/firebase/firestore/util/config.h + # CMake .downloads Debug diff --git a/FirebaseFirestore.podspec b/FirebaseFirestore.podspec index b6b2966..af8770b 100644 --- a/FirebaseFirestore.podspec +++ b/FirebaseFirestore.podspec @@ -47,7 +47,8 @@ Google Cloud Firestore is a NoSQL document database built for automatic scaling, # Exclude alternate implementations for other platforms 'Firestore/core/src/firebase/firestore/util/assert_stdio.cc', - 'Firestore/core/src/firebase/firestore/util/log_stdio.cc' + 'Firestore/core/src/firebase/firestore/util/log_stdio.cc', + 'Firestore/core/src/firebase/firestore/util/secure_random_openssl.cc' ] s.public_header_files = 'Firestore/Source/Public/*.h' @@ -66,4 +67,12 @@ Google Cloud Firestore is a NoSQL document database built for automatic scaling, '"${PODS_TARGET_SRCROOT}/Firestore/third_party/abseil-cpp"', 'OTHER_CFLAGS' => '-DFIRFirestore_VERSION=' + s.version.to_s } + + s.prepare_command = <<-CMD + # Generate a version of the config.h header suitable for building with + # CocoaPods. + sed '/^#cmakedefine/ d' \ + Firestore/core/src/firebase/firestore/util/config.h.in > \ + Firestore/core/src/firebase/firestore/util/config.h + CMD end diff --git a/Firestore/CMakeLists.txt b/Firestore/CMakeLists.txt index 499e06c..b8c95c6 100644 --- a/Firestore/CMakeLists.txt +++ b/Firestore/CMakeLists.txt @@ -57,6 +57,9 @@ add_subdirectory(third_party/abseil-cpp) include(CompilerSetup) +# Generated sources will be relative to the binary directory. +include_directories(${FIREBASE_INSTALL_DIR}) + # Fully qualified imports, project wide include_directories(${FIREBASE_SOURCE_DIR}) diff --git a/Firestore/core/src/firebase/firestore/base/port.h b/Firestore/core/src/firebase/firestore/base/port.h deleted file mode 100644 index 5e3959d..0000000 --- a/Firestore/core/src/firebase/firestore/base/port.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2017 Google - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_BASE_PORT_H_ -#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_BASE_PORT_H_ - -#if defined(__APPLE__) -// On Apple platforms we support building via CocoaPods without CMake. When -// building this way we can't test the presence of features so predefine all -// the platform-support feature macros to their expected values. - -// All supported Apple platforms have arc4random(3). -#define HAVE_ARC4RANDOM 1 - -#else - -#error "Unknown platform." -#endif // defined(__APPLE__) - -#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_BASE_PORT_H_ diff --git a/Firestore/core/src/firebase/firestore/util/CMakeLists.txt b/Firestore/core/src/firebase/firestore/util/CMakeLists.txt index 7283942..737173b 100644 --- a/Firestore/core/src/firebase/firestore/util/CMakeLists.txt +++ b/Firestore/core/src/firebase/firestore/util/CMakeLists.txt @@ -16,11 +16,12 @@ # libraries in here are an implementation detail of making this a # mutli-platform build. +include(CheckSymbolExists) +include(CheckIncludeFiles) + cc_library( firebase_firestore_util_base SOURCES - secure_random.h - secure_random_arc4random.cc string_printf.cc string_printf.h DEPENDS @@ -60,15 +61,55 @@ else() endif() +## secure_random + +check_symbol_exists(arc4random stdlib.h HAVE_ARC4RANDOM) +cc_library( + firebase_firestore_util_arc4random + SOURCES + secure_random_arc4random.cc +) + +get_target_property( + CMAKE_REQUIRED_INCLUDES + OpenSSL::Crypto INTERFACE_INCLUDE_DIRECTORIES +) +check_include_files(openssl/rand.h HAVE_OPENSSL_RAND_H) +cc_library( + firebase_firestore_util_openssl + SOURCES + secure_random_openssl.cc + DEPENDS + OpenSSL::Crypto +) + +if(HAVE_ARC4RANDOM) + list(APPEND UTIL_DEPENDS firebase_firestore_util_arc4random) + +elseif(HAVE_OPENSSL_RAND_H) + list(APPEND UTIL_DEPENDS firebase_firestore_util_openssl) + +else() + message(FATAL_ERROR "No implementation for SecureRandom available.") + +endif() + + ## main library +configure_file( + config.h.in + config.h +) cc_library( firebase_firestore_util SOURCES autoid.cc autoid.h + config.h firebase_assert.h log.h + secure_random.h DEPENDS ${UTIL_DEPENDS} firebase_firestore_util_base diff --git a/Firestore/core/src/firebase/firestore/util/config.h.in b/Firestore/core/src/firebase/firestore/util/config.h.in new file mode 100644 index 0000000..e7a0c03 --- /dev/null +++ b/Firestore/core/src/firebase/firestore/util/config.h.in @@ -0,0 +1,35 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_CONFIG_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_CONFIG_H_ + +// This header defines macros for all available platform configuration values. +// When building with CMake, it will substitute the lines marked with +// cmakedefine with values corresponding to the local configuration. +// +// On Apple platforms we support building via CocoaPods without CMake. When +// building this way we can't test the presence of features before building so +// predefine all the platform-support feature macros to their expected values. + +#cmakedefine HAVE_ARC4RANDOM 1 +#if COCOAPODS +# define HAVE_ARC4RANDOM 1 +#endif + +#cmakedefine HAVE_OPENSSL_RAND_H 1 + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_CONFIG_H_ diff --git a/Firestore/core/src/firebase/firestore/util/secure_random_arc4random.cc b/Firestore/core/src/firebase/firestore/util/secure_random_arc4random.cc index a76ade3..83f72b5 100644 --- a/Firestore/core/src/firebase/firestore/util/secure_random_arc4random.cc +++ b/Firestore/core/src/firebase/firestore/util/secure_random_arc4random.cc @@ -16,7 +16,7 @@ #include "Firestore/core/src/firebase/firestore/util/secure_random.h" -#include "Firestore/core/src/firebase/firestore/base/port.h" +#include "Firestore/core/src/firebase/firestore/util/config.h" #if HAVE_ARC4RANDOM diff --git a/Firestore/core/src/firebase/firestore/util/secure_random_openssl.cc b/Firestore/core/src/firebase/firestore/util/secure_random_openssl.cc new file mode 100644 index 0000000..d3f6e63 --- /dev/null +++ b/Firestore/core/src/firebase/firestore/util/secure_random_openssl.cc @@ -0,0 +1,46 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "Firestore/core/src/firebase/firestore/util/secure_random.h" + +#include "Firestore/core/src/firebase/firestore/util/config.h" + +#if HAVE_OPENSSL_RAND_H + +#include +#include + +namespace firebase { +namespace firestore { +namespace util { + +SecureRandom::result_type SecureRandom::operator()() { + result_type result; + int rc = RAND_bytes(reinterpret_cast(&result), sizeof(result)); + if (rc <= 0) { + // OpenSSL's RAND_bytes can fail if there's not enough entropy. BoringSSL + // won't fail this way. + ERR_print_errors_fp(stderr); + abort(); + } + return result; +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // HAVE_OPENSSL_RAND_H diff --git a/Firestore/core/test/firebase/firestore/util/CMakeLists.txt b/Firestore/core/test/firebase/firestore/util/CMakeLists.txt index 7f0539c..468c62e 100644 --- a/Firestore/core/test/firebase/firestore/util/CMakeLists.txt +++ b/Firestore/core/test/firebase/firestore/util/CMakeLists.txt @@ -12,11 +12,30 @@ # See the License for the specific language governing permissions and # limitations under the License. +if(HAVE_ARC4RANDOM) + cc_test( + firebase_firestore_util_arc4random_test + SOURCES + secure_random_test.cc + DEPENDS + firebase_firestore_util_arc4random + ) +endif() + +if(HAVE_OPENSSL_RAND_H) + cc_test( + firebase_firestore_util_openssl_test + SOURCES + secure_random_test.cc + DEPENDS + firebase_firestore_util_openssl + ) +endif() + cc_test( firebase_firestore_util_test SOURCES autoid_test.cc - secure_random_test.cc string_printf_test.cc DEPENDS firebase_firestore_util -- cgit v1.2.3