diff --git a/.github/workflows/hw_mode_test.yml b/.github/workflows/hw_mode_test.yml index 05c0f9ef..b9d87808 100644 --- a/.github/workflows/hw_mode_test.yml +++ b/.github/workflows/hw_mode_test.yml @@ -865,11 +865,14 @@ jobs: container-name: ${{ github.job }} build-envs: 'OCCLUM_RELEASE_BUILD=1' - - name: Download and build the pakckages - run: docker exec ${{ env.CONTAINER_NAME }} bash -c "cd /root/occlum/demos/ra_tls; ./prepare_and_build_package.sh" + - name: Download source code + run: docker exec ${{ env.CONTAINER_NAME }} bash -c "cd /root/occlum/demos/ra_tls; ./download_and_prepare.sh" + - name: Build and install gRPC+RATLS + run: docker exec ${{ env.CONTAINER_NAME }} bash -c "cd /root/occlum/demos/ra_tls; ./build_and_install.sh musl" + - name: Build occlum instances - run: docker exec ${{ env.CONTAINER_NAME }} bash -c "cd /root/occlum/demos/ra_tls; ./build_occlum_instance.sh" + run: docker exec ${{ env.CONTAINER_NAME }} bash -c "cd /root/occlum/demos/ra_tls; ./build_occlum_instance.sh musl" - name: Run gRPC server run: docker exec ${{ env.CONTAINER_NAME }} bash -c "cd /root/occlum/demos/ra_tls; ./run.sh server &" diff --git a/demos/ra_tls/README.md b/demos/ra_tls/README.md index 69f2f203..6800e540 100644 --- a/demos/ra_tls/README.md +++ b/demos/ra_tls/README.md @@ -1,23 +1,74 @@ # gRPC Package With RA-TLS +## Simple GRPC protocol for the demo -#### Executing the demo in Occlum +* Server side, holds a [`json file`](./secret_config.json) including secret name and the secret's base64 encoded string. -The following command will download the gRPC source code and apply the ra-tls patches, then build gRPC source code and demo. +* Client side, request the secret by the secret name. + +## Example libraries/executables in the demo + +* libhw_grpc_proto.so +* libgrpc_ratls_client.so +* libgrpc_ratls_server.so +* client +* server + +### APIs defined for sample server and client + +* Server ``` -./prepare_and_build_package.sh +int gr_start_server( + const char *server_addr, // grpc server address+port, such as "localhost:50051" + const char *config_json, // ratls handshake config json file + const char *secret_json // secret config json file +); +``` + +* Client +``` +int gr_client_get_secret( + const char *server_addr, // grpc server address+port, such as "localhost:50051" + const char *config_json, // ratls handshake config json file + const char *name, // secret name to be requested + const char *secret_file // secret file to be saved +); +``` + +All source could be found on [`example`](./grpc/v1.38.1/examples/cpp/ratls/) + + +## Executing the demo in Occlum + +The following command will download prerequisite source and the gRPC source code. +``` +./download_and_prepare.sh +``` + +The following command will patch the gRPC source code and do the build and install. +``` +./build_and_install.sh +``` + +If musl-libc version is expected. +``` +./build_and_install.sh musl ``` The following command will generate the client and server occlum images. It automatically parses the mr_enclave and mr_signer of the client, and write the value into dynamic_config.json. If you want to verify the other measurements of client, please modify the dynamic_config.json before run the script. ``` ./build_occlum_instance.sh ``` +If previous build choice is `musl`. +``` +./build_occlum_instance.sh musl +``` Run the gRPC server & client in occlum. ``` ./run.sh server & -./run.sh client +./run.sh client ( cert, key ) ``` ***Note:*** 1. The demo runs in the same machine by default. If you want to run server and client in different machines. Please modify the examples/cpp/ratls. diff --git a/demos/ra_tls/build_and_install.sh b/demos/ra_tls/build_and_install.sh new file mode 100755 index 00000000..3d761b7c --- /dev/null +++ b/demos/ra_tls/build_and_install.sh @@ -0,0 +1,77 @@ +#!/bin/bash +set -e + +source ./env.sh + +BUILD_TYPE=Release + +if [[ $1 == "musl" ]]; then + echo "*** Build and run musl-libc demo ***" + CC=occlum-gcc + CXX=occlum-g++ + DCAP_LIB_PATH="/opt/occlum/toolchains/dcap_lib/musl" + INSTALL_PREFIX="/usr/local/occlum/x86_64-linux-musl" +else + echo "*** Build and run glibc demo ***" + CC=gcc + CXX=g++ + DCAP_LIB_PATH="/opt/occlum/toolchains/dcap_lib/glibc" + INSTALL_PREFIX="/usr/local" +fi + +# Build and install cJSON +function build_cjson() { + pushd cJSON-${CJSON_VER} + rm -rf build && mkdir build && cd build + cmake -DENABLE_CJSON_UTILS=On -DENABLE_CJSON_TEST=Off -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \ + -DCMAKE_C_COMPILER=${CC} .. + make install + popd +} + +function build_grpc_ratls() { + # Copy occlum dcap lib first + cp ${DCAP_LIB_PATH}/libocclum_dcap.so* ${INSTALL_PREFIX}/lib + cp /opt/occlum/toolchains/dcap_lib/inc/occlum_dcap.h ${INSTALL_PREFIX}/include/ + + # Copy ratls added/updated files to grpc source + cp -rf grpc/${GRPC_VERSION}/* ${GRPC_PATH}/ + + ABSEIL_PATH=${GRPC_PATH}/third_party/abseil-cpp + + # build and install abseil library + # https://abseil.io/docs/cpp/quickstart-cmake.html + pushd ${ABSEIL_PATH} + rm -rf build && mkdir build && cd build + cmake -DCMAKE_CXX_STANDARD=11 -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ + -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} \ + -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_C_COMPILER=${CC} .. + make -j `nproc` + make install + popd + + # Build grpc + ratls + pushd ${GRPC_PATH} + rm -rf build && mkdir build && cd build + cmake -DgRPC_INSTALL=ON -DgRPC_ABSL_PROVIDER=package -DgRPC_BUILD_TESTS=OFF \ + -DgRPC_BUILD_CSHARP_EXT=OFF -DgRPC_BUILD_GRPC_CSHARP_PLUGIN=OFF \ + -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF -DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF \ + -DDEFINE_SGX_RA_TLS_OCCLUM_BACKEND=ON \ + -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_C_COMPILER=${CC} \ + -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. + make -j `nproc` + make install + popd + + # Build grpc ratls client and server demo + pushd ${GRPC_PATH}/examples/cpp/ratls + rm -rf build && mkdir -p build + cd build + cmake -D CMAKE_PREFIX_PATH=${INSTALL_PREFIX} -D CMAKE_BUILD_TYPE=${BUILD_TYPE} \ + -DCMAKE_CXX_COMPILER=${CXX} -DCMAKE_C_COMPILER=${CC} .. + make -j `nproc` + popd +} + +build_cjson +build_grpc_ratls diff --git a/demos/ra_tls/build_occlum_instance.sh b/demos/ra_tls/build_occlum_instance.sh index 0ef45a04..68ccbd67 100755 --- a/demos/ra_tls/build_occlum_instance.sh +++ b/demos/ra_tls/build_occlum_instance.sh @@ -1,9 +1,8 @@ #!/bin/bash -occlum_glibc=/opt/occlum/glibc/lib/ -set -ex +set -e -get_mr() { - sgx_sign dump -enclave ../occlum_instance_$1/build/lib/libocclum-libos.signed.so -dumpfile ../metadata_info_$1.txt +function get_mr() { + sgx_sign dump -enclave ../occlum_$1/build/lib/libocclum-libos.signed.so -dumpfile ../metadata_info_$1.txt if [ "$2" == "mr_enclave" ]; then sed -n -e '/enclave_hash.m/,/metadata->enclave_css.body.isv_prod_id/p' ../metadata_info_$1.txt |head -3|tail -2|xargs|sed 's/0x//g'|sed 's/ //g' elif [ "$2" == "mr_signer" ]; then @@ -11,43 +10,56 @@ get_mr() { fi } -build_instance() { +function build_instance() { # 1. Init Occlum Workspace - rm -rf occlum_instance_$postfix - mkdir occlum_instance_$postfix - pushd occlum_instance_$postfix + rm -rf occlum_$postfix + mkdir occlum_$postfix + pushd occlum_$postfix occlum init - new_json="$(jq '.resource_limits.user_space_size = "320MB" | - .process.default_mmap_size = "256MB"' Occlum.json)" && \ + new_json="$(jq '.resource_limits.user_space_size = "500MB"' Occlum.json)" && \ echo "${new_json}" > Occlum.json - # 2. Copy files into Occlum Workspace and Build - #cp ../dynamic_config.json image/etc/dynamic_config.json - cp ../dynamic_config.json image/dynamic_config.json - #cp ../dynamic_config_$postfix.json image/dynamic_config.json + if [ "$postfix" == "server" ]; then + # Server will verify client's mr_enclave and mr_signer jq ' .verify_mr_enclave = "on" | .verify_mr_signer = "on" | + .verify_isv_prod_id = "off" | + .verify_isv_svn = "off" | .sgx_mrs[0].mr_enclave = ''"'`get_mr client mr_enclave`'" | - .sgx_mrs[0].mr_signer = ''"'`get_mr client mr_signer`'" ' ../dynamic_config.json > image/dynamic_config.json + .sgx_mrs[0].mr_signer = ''"'`get_mr client mr_signer`'" ' ../ra_config_template.json > dynamic_config.json + + if [ "$libnss_require" == "y" ]; then + cp /lib/x86_64-linux-gnu/libnss*.so.2 image/$occlum_glibc + cp /lib/x86_64-linux-gnu/libresolv.so.2 image/$occlum_glibc + fi + + bomfile="../grpc_ratls_server.yaml" + else + # Client verify nothing from server + jq ' .verify_mr_enclave = "off" | + .verify_mr_signer = "off" | + .verify_isv_prod_id = "off" | + .verify_isv_svn = "off" ' ../ra_config_template.json > dynamic_config.json + + bomfile="../grpc_ratls_client.yaml" fi - mkdir -p image/usr/share/grpc - cp -rf /share/grpc/* image/usr/share/grpc/ - cp $occlum_glibc/libdl.so.2 image/$occlum_glibc - cp $occlum_glibc/librt.so.1 image/$occlum_glibc - cp $occlum_glibc/libm.so.6 image/$occlum_glibc - cp /lib/x86_64-linux-gnu/libtinfo.so.5 image/$occlum_glibc - cp /lib/x86_64-linux-gnu/libnss*.so.2 image/$occlum_glibc - cp /lib/x86_64-linux-gnu/libresolv.so.2 image/$occlum_glibc - cp -rf /etc/hostname image/etc/ - cp -rf /etc/ssl image/etc/ - cp -rf /etc/passwd image/etc/ - cp -rf /etc/group image/etc/ - cp -rf /etc/nsswitch.conf image/etc/ - cp -rf /grpc/examples/cpp/ratls/build/* image/bin/ + + rm -rf image + copy_bom -f $bomfile --root image --include-dir /opt/occlum/etc/template + occlum build popd } +if [[ $1 == "musl" ]]; then + echo "*** Build and musl-libc Occlum instance ***" +else + echo "*** Build and run glibc Occlum instance ***" + # glibc version requires libnss + libnss_require="y" + occlum_glibc=/opt/occlum/glibc/lib/ +fi + postfix=client build_instance postfix=server diff --git a/demos/ra_tls/download_and_prepare.sh b/demos/ra_tls/download_and_prepare.sh new file mode 100755 index 00000000..6a31cf0d --- /dev/null +++ b/demos/ra_tls/download_and_prepare.sh @@ -0,0 +1,46 @@ +#!/bin/bash +set -e + +source ./env.sh + +# Download and update cmake +function dl_and_build_cmake() { + # Ubuntu 20.04 has newer enough cmake version + if [ -f "/etc/os-release" ]; then + local os_name=$(cat /etc/os-release) + if [[ $os_name =~ "Ubuntu" && $os_name =~ "20.04" ]]; then + return + fi + fi + + rm -rf cmake-3.20.2* + wget https://github.com/Kitware/CMake/releases/download/v3.20.2/cmake-3.20.2.tar.gz + tar -zxvf cmake-3.20.2.tar.gz + pushd cmake-3.20.2 + ./bootstrap + make install + popd +} + +# GRPC env +function dl_grpc() { + # GRPC source code + rm -rf ${GRPC_PATH} + git clone https://github.com/grpc/grpc -b ${GRPC_VERSION} ${GRPC_PATH} + pushd ${GRPC_PATH} \ + && git checkout ${GRPC_VERSION} \ + && git submodule update --init + popd +} + +# Download cJSON +function dl_cjson() { + rm -rf cJSON* + wget https://github.com/DaveGamble/cJSON/archive/refs/tags/v${CJSON_VER}.tar.gz + tar zxvf v${CJSON_VER}.tar.gz +} + + +dl_and_build_cmake +dl_grpc +dl_cjson diff --git a/demos/ra_tls/env.sh b/demos/ra_tls/env.sh new file mode 100644 index 00000000..74f353bb --- /dev/null +++ b/demos/ra_tls/env.sh @@ -0,0 +1,7 @@ +#!/bin/bash +set -e + +GRPC_VERSION=v1.38.1 +GRPC_PATH=grpc-src + +CJSON_VER=1.7.15 diff --git a/demos/ra_tls/grpc/common/build_cpp.sh b/demos/ra_tls/grpc/common/build_cpp.sh deleted file mode 100755 index 50bf6125..00000000 --- a/demos/ra_tls/grpc/common/build_cpp.sh +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright (c) 2022 Intel Corporation -# -# 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. - -set -ex - -export ABSEIL_PATH=${GRPC_PATH}/third_party/abseil-cpp - -if [ ! -d "${BUILD_TYPE}" ]; then - BUILD_TYPE=Release -fi - -# build and install abseil library -# https://abseil.io/docs/cpp/quickstart-cmake.html -if [ ! -d "${ABSEIL_PATH}/build" ]; then - mkdir -p ${ABSEIL_PATH}/build - cd ${ABSEIL_PATH}/build - cmake -DCMAKE_CXX_STANDARD=11 -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ - -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. - make -j `nproc` - make install - cd - -fi - -# build and install grpc library -mkdir -p ${GRPC_PATH}/build -cd ${GRPC_PATH}/build -cmake -DgRPC_INSTALL=ON -DgRPC_ABSL_PROVIDER=package -DgRPC_BUILD_TESTS=OFF \ - -DgRPC_BUILD_CSHARP_EXT=OFF -DgRPC_BUILD_GRPC_CSHARP_PLUGIN=OFF \ - -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF -DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF \ - -DDEFINE_SGX_RA_TLS_OCCLUM_BACKEND=ON \ - -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${INSTALL_PREFIX} .. -make -j `nproc` -make install -cd - diff --git a/demos/ra_tls/grpc/v1.38.1/CMakeLists.txt b/demos/ra_tls/grpc/v1.38.1/CMakeLists.txt index a87c7315..601c3cb1 100644 --- a/demos/ra_tls/grpc/v1.38.1/CMakeLists.txt +++ b/demos/ra_tls/grpc/v1.38.1/CMakeLists.txt @@ -54,6 +54,7 @@ option(DEFINE_SGX_RA_TLS_OCCLUM_BACKEND "SGX Occlum Backend" OFF) if(DEFINE_SGX_RA_TLS_OCCLUM_BACKEND) message("SGX_RA_TLS_OCCLUM_BACKEND is defined") + include_directories(/opt/intel/sgxsdk/include) add_definitions(-DSGX_RA_TLS_OCCLUM_BACKEND) endif() @@ -2089,7 +2090,8 @@ if(DEFINE_SGX_RA_TLS_OCCLUM_BACKEND) gpr ${_gRPC_SSL_LIBRARIES} address_sorting - libdcap_quote.a + occlum_dcap + cjson ) endif() @@ -2793,7 +2795,6 @@ add_library(grpc++ src/cpp/sgx/sgx_ra_tls_backends.cc src/cpp/sgx/sgx_ra_tls_occlum.cc src/cpp/sgx/sgx_ra_tls_utils.cc - src/cpp/sgx/cjson/cJSON.c ) set_target_properties(grpc++ PROPERTIES diff --git a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/CMakeLists.txt b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/CMakeLists.txt index d04b5f52..200583db 100644 --- a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/CMakeLists.txt +++ b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/CMakeLists.txt @@ -41,7 +41,7 @@ add_custom_command( include_directories("${CMAKE_CURRENT_BINARY_DIR}") # hw_grpc_proto -add_library(hw_grpc_proto +add_library(hw_grpc_proto SHARED ${hw_grpc_srcs} ${hw_grpc_hdrs} ${hw_proto_srcs} @@ -51,12 +51,14 @@ target_link_libraries(hw_grpc_proto ${_GRPC_GRPCPP} ${_PROTOBUF_LIBPROTOBUF}) -# Targets greeter_[async_](client|server) +foreach(_target grpc_ratls_client grpc_ratls_server) + add_library(${_target} SHARED "${_target}.cc") + target_link_libraries(${_target} + hw_grpc_proto) +endforeach() + foreach(_target client server) add_executable(${_target} "${_target}.cc") target_link_libraries(${_target} - hw_grpc_proto - ${_REFLECTION} - ${_GRPC_GRPCPP} - ${_PROTOBUF_LIBPROTOBUF}) + grpc_ratls_${_target}) endforeach() diff --git a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/build.sh b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/build.sh old mode 100755 new mode 100644 index 8791f960..b6ed9c8a --- a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/build.sh +++ b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/build.sh @@ -18,8 +18,6 @@ set -ex export BUILD_TYPE=Release export EXP_PATH=`dirname $0` -${GRPC_PATH}/build_cpp.sh - # build c++ example cd ${EXP_PATH} mkdir -p build diff --git a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/client.cc b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/client.cc index 76a53b8f..e62915f5 100644 --- a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/client.cc +++ b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/client.cc @@ -15,72 +15,27 @@ * limitations under the License. * */ +#include +#include +#include -#include -#include +#include "../grpc_ratls_client.h" -#ifdef BAZEL_BUILD -#include "examples/protos/ratls.grpc.pb.h" -#else -#include "ratls.grpc.pb.h" -#endif - -#include "../getopt.hpp" - -using ratls::Greeter; -using ratls::HelloReply; -using ratls::HelloRequest; - -struct argparser { - const char* config; - std::string server_address; - argparser() { - server_address = getarg("localhost:50051", "-host", "--host"); - config = getarg("dynamic_config.json", "-cfg", "--config"); - }; -}; - -class GreeterClient { - public: - GreeterClient(std::shared_ptr channel) : stub_(Greeter::NewStub(channel)) {} - - std::string SayHello(const std::string& user) { - HelloRequest request; - request.set_name(user); - - HelloReply reply; - - grpc::ClientContext context; - - grpc::Status status = stub_->SayHello(&context, request, &reply); - - if (status.ok()) { - return reply.message(); - } else { - std::cout << status.error_code() << ": " << status.error_message() << std::endl; - return "RPC failed"; - } - } - - private: - std::unique_ptr stub_; -}; - -void run_client() { - argparser args; - - auto cred = grpc::sgx::TlsCredentials(args.config); - auto channel = grpc::CreateChannel(args.server_address, cred); - - GreeterClient greeter(channel); - - std::string user_a = greeter.SayHello("a"); - std::string user_b = greeter.SayHello("b"); - - std::cout << "Greeter received: " << user_a << ", "<< user_b << std::endl; -}; int main(int argc, char** argv) { - run_client(); + // Parse arguments + if (argc < 3) { + printf("[ERROR] At least one argument must be provided\n\n"); + printf("Usage: client [] []\n"); + return -1; + } + + gr_client_get_secret( + "localhost:50051", + "dynamic_config.json", + argv[1], + argv[2] + ); + return 0; } diff --git a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/getopt.hpp b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/getopt.hpp deleted file mode 100644 index 2fe8e3a3..00000000 --- a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/getopt.hpp +++ /dev/null @@ -1,316 +0,0 @@ -// Simple getopt replacement class (C++11). -// - rlyeh, zlib/libpng licensed. -// https://github.com/r-lyeh-archived/getopt/blob/master/getopt.hpp - -// Two APIs provided: -// -// 1) Simple functional api `getarg(...)`. -// - No initialization required: (argc, argv) pair automatically retrieved. -// - First argument is default option value, then all option indentifiers follow. -// -// int main() { -// bool help = getarg( false, "-h", "--help", "-?" ); -// int version = getarg( 0, "-v", "--version", "--show-version" ); -// int depth = getarg( 1, "-d", "--depth", "--max-depth"); -// std::string file = getarg( "", "-f", "--file" ); -// [...] -// } -// -// 2) Simple OOP map-based api `getopt class`. Initialization (argc, argv) pair required. -// -// This getopt class is a std::map replacement where key/value are std::string types. -// Given invokation './app.out --user=me --pass=123 -h' this class delivers not only: -// map[0] = "./app.out", map[1] = "--user=me", map[2]="--pass=123", map[3]='-h' -// but also, map["--user"]="me", map["--pass"]="123" and also, map["-h"]=true -// -// Additional API: -// - .cmdline() for a print app invokation string -// - .str() for pretty map printing -// - .size() number of arguments (equivalent to argc), rather than std::map.size() -// -// int main( int argc, const char **argv ) { -// getopt args( argc, argv ); -// if( args.has("-h") || args.has("--help") || args.has("-?") || args.size() == 1 ) { -// std::cout << args["0"] << " [-?|-h|--help] [-v|--version] [--depth=number]" << std::endl; -// return 0; -// } -// if( args.has("-v") || args.has("--version") ) { -// std::cout << args["0"] << " sample v1.0.0. Compiled on " << __DATE__ << std::endl; -// } -// if( args.has("--depth") ) { -// int depth = atoi( args["--depth"].c_str() ); -// std::cout << "depth set to " << depth << std::endl; -// } -// [...] -// } - -#pragma once -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#include -#include -#pragma comment(lib, "Shell32.lib") -#else -#include -#include -#include -#include -#include -#endif - -#define GETOPT_VERSION "1.0.0" // (2016/04/18) Initial version - -namespace getopt_utils -{ - // string conversion - - template< typename T > - inline T as( const std::string &self ) { - T t; - return (std::istringstream(self) >> t) ? t : - (T)(self.size() && (self != "0") && (self != "false")); - } - - template<> - inline char as( const std::string &self ) { - return self.size() == 1 ? (char)(self[0]) : (char)(as(self)); - } - template<> - inline signed char as( const std::string &self ) { - return self.size() == 1 ? (signed char)(self[0]) : (signed char)(as(self)); - } - template<> - inline unsigned char as( const std::string &self ) { - return self.size() == 1 ? (unsigned char)(self[0]) : (unsigned char)(as(self)); - } - - template<> - inline const char *as( const std::string &self ) { - return self.c_str(); - } - template<> - inline std::string as( const std::string &self ) { - return self; - } - - // token split - - inline size_t split( std::vector &tokens, const std::string &self, const std::string &delimiters ) { - std::string str; - tokens.clear(); - for( auto &ch : self ) { - if( delimiters.find_first_of( ch ) != std::string::npos ) { - if( str.size() ) tokens.push_back( str ), str = ""; - tokens.push_back( std::string() + ch ); - } else str += ch; - } - return str.empty() ? tokens.size() : ( tokens.push_back( str ), tokens.size() ); - }; - - // portable cmdline - - inline std::vector cmdline() { - std::vector args; - std::string arg; - # ifdef _WIN32 - int argv; - auto *list = CommandLineToArgvW( GetCommandLineW(), &argv ); - if( list ) { - for( int i = 0; i < argv; ++i ) { - std::wstring ws( list[i] ); - args.push_back( std::string( ws.begin(), ws.end() ) ); - } - LocalFree(list); - } - # else - pid_t pid = getpid(); - - char fname[32] = {}; - sprintf(fname, "/proc/%d/cmdline", pid); - std::ifstream ifs(fname); - if( ifs.good() ) { - std::stringstream ss; - ifs >> ss.rdbuf(); - arg = ss.str(); - } - for( auto end = arg.size(), i = end - end; i < end; ++i ) { - auto st = i; - while (i < arg.size() && arg[i] != '\0') ++i; - args.push_back( arg.substr(st, i - st) ); - } - # endif - return args; - } -} - -// main map class; explicit initialization - -struct getopt : public std::map< std::string, std::string > -{ - using super = std::map< std::string, std::string >; - - getopt( int argc, const char **argv ) : super() { - // reconstruct vector - std::vector args( argc, std::string() ); - for( int i = 0; i < argc; ++i ) { - args[ i ] = argv[ i ]; - } - // create key=value and key= args as well - for( auto &it : args ) { - std::vector tokens; - auto size = getopt_utils::split( tokens, it, "=" ); - - if( size == 3 && tokens[1] == "=" ) - (*this)[ tokens[0] ] = tokens[2]; - else - if( size == 2 && tokens[1] == "=" ) - (*this)[ tokens[0] ] = true; - else - if( size == 1 && tokens[0] != argv[0] ) - (*this)[ tokens[0] ] = true; - } - // recreate args - while( argc-- ) { - (*this)[ std::to_string(argc) ] = std::string( argv[argc] ); - } - } - - getopt( const std::vector &args ) : super() { - std::vector argv; - for( auto &it : args ) { - argv.push_back( it.c_str() ); - } - *this = getopt( argv.size(), argv.data() ); - } - - size_t size() const { - unsigned i = 0; - while( has(std::to_string(i)) ) ++i; - return i; - } - - bool has( const std::string &op ) const { - return this->find(op) != this->end(); - } - - std::string str() const { - std::stringstream ss; - std::string sep; - for( auto &it : *this ) { - ss << sep << it.first << "=" << it.second; - sep = ','; - } - return ss.str(); - } - - std::string cmdline() const { - std::stringstream cmd; - std::string sep; - // concatenate args - for( auto end = size(), arg = end - end; arg < end; ++arg ) { - cmd << sep << this->find(std::to_string(arg))->second; - sep = ' '; - } - return cmd.str(); - } -}; - -// variadic syntax sugars { - -template< typename T > -inline T getarg( const T &defaults, const char *argv ) { - static struct getopt map( getopt_utils::cmdline() ); - return map.has( argv ) ? getopt_utils::as(map[ argv ]) : defaults; -} - -template< typename T, typename... Args > -inline T getarg( const T &defaults, const char *arg0, Args... argv ) { - T t = getarg( defaults, arg0 ); - return t == defaults ? getarg( defaults, argv... ) : t; -} - -inline const char * getarg( const char *defaults, const char *argv ) { - static struct getopt map( getopt_utils::cmdline() ); - return map.has( argv ) ? getopt_utils::as(map[ argv ]) : defaults; -} - -template< typename... Args > -inline const char * getarg( const char *defaults, const char *arg0, Args... argv ) { - const char *t = getarg( defaults, arg0 ); - return t == defaults ? getarg( defaults, argv... ) : t; -} - -// } - - -#ifdef GETOPT_BUILD_DEMO -#include -#include - -int main( int argc, const char **argv ) { - - auto show_help = [&]() { - std::cout << argv[0] << " [-h|--help|-?] [-f=path|--file=path] [-v|--version] [-d=number|--depth=number|--max-depth=number]" << std::endl; - exit(0); - }; - - // Simple functional api. No initialization required. - - bool help = getarg( false, "-h", "--help", "-?" ); - int version = getarg( 0, "-v", "--version", "--show-version" ); - int depth = getarg( 0, "-d", "--depth", "--max-depth"); - std::string file = getarg( "", "-f", "--file" ); - - if( help || argc <= 1 ) { - show_help(); - } - - if( version ) { - std::cout << argv[0] << " demo v1.0.0. Compiled on " << __DATE__ << std::endl; - } - - if( depth ) { - std::cout << "provided depth: " << depth << std::endl; - } - - if( !file.empty() ) { - std::cout << "provided file: " << file << std::endl; - } - - // OOP map-based api. Explicit (argc, argv) initialization required. - - struct getopt args( argc, argv ); - - if( args.has("-h") || args.has("--help") || args.has("-?") || args.size() == 1 ) { - show_help(); - } - - if( args.has("-v") || args.has("--version") ) { - std::cout << args["0"] << " demo v1.0.0. Compiled on " << __DATE__ << std::endl; - } - - if( args.has("-d") || args.has("--depth") || args.has("--max-depth") ) { - std::string arg = args["-d"]; - if( arg.empty() ) arg = args["--depth"]; - if( arg.empty() ) arg = args["--max-depth"]; - int depth = atoi( arg.c_str() ); - std::cout << "provided depth: " << depth << std::endl; - } - - if( args.has("-f") || args.has("--file") ) { - std::string arg = args["-f"]; - if( arg.empty() ) arg = args["--file"]; - std::string fname = arg; - std::cout << "provided file: " << fname << std::endl; - } - - std::cout << "---" << std::endl; - std::cout << args.cmdline() << std::endl; - //std::cout << args.size() << " provided args: " << args.str() << std::endl; -} -#endif \ No newline at end of file diff --git a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/grpc_ratls_client.cc b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/grpc_ratls_client.cc new file mode 100644 index 00000000..c2620e0c --- /dev/null +++ b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/grpc_ratls_client.cc @@ -0,0 +1,148 @@ +/* + * + * Copyright (c) 2022 Intel Corporation + * + * 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 +#include +#include +#include + +#include +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/ratls.grpc.pb.h" +#else +#include "ratls.grpc.pb.h" +#endif + +#include "../grpc_ratls_client.h" + +using ratls::GrSecret; +using ratls::SecretRequest; +using ratls::SecretReply; + +// Client +class GrSecretClient { + public: + GrSecretClient(std::shared_ptr channel) : stub_(GrSecret::NewStub(channel)) {} + + std::string GetSecret(const std::string& name) { + SecretRequest request; + request.set_name(name); + + SecretReply reply; + + grpc::ClientContext context; + + grpc::Status status = stub_->GetSecret(&context, request, &reply); + + if (status.ok()) { + return reply.secret(); + } else { + std::cout << status.error_code() << ": " << status.error_message() << std::endl; + return "RPC failed"; + } + } + + private: + std::unique_ptr stub_; +}; + +static const unsigned char base64_table[65] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static size_t base64_decode_len(const char *b64input) { + size_t len = strlen(b64input), padding = 0; + + if (b64input[len - 1] == '=' && b64input[len - 2] == '=') { //last two chars are = + padding = 2; + } else if (b64input[len - 1] == '=') { //last char is = + padding = 1; + } + + return (len * 3) / 4 - padding; +} + +/** + * base64_decode - Base64 decode + */ +void base64_decode(const char *b64input, unsigned char *dest, size_t dest_len) { + unsigned char dtable[256], *pos, block[4], tmp; + size_t i, count, olen; + size_t len = strlen(b64input); + + memset(dtable, 0x80, 256); + for (i = 0; i < sizeof(base64_table) - 1; i++) { + dtable[base64_table[i]] = (unsigned char) i; + } + dtable['='] = 0; + + olen = base64_decode_len(b64input); + if (olen > dest_len) { + printf("Base64 encoded length %ld is biggeer than %ld\n", olen, dest_len); + return; + } + + pos = dest; + count = 0; + for (i = 0; i < len; i++) { + tmp = dtable[(unsigned char)b64input[i]]; + if (tmp == 0x80) { + continue; + } + block[count] = tmp; + count++; + if (count == 4) { + *pos++ = (block[0] << 2) | (block[1] >> 4); + *pos++ = (block[1] << 4) | (block[2] >> 2); + *pos++ = (block[2] << 6) | block[3]; + count = 0; + } + } +} + +int gr_client_get_secret( + const char *server_addr, + const char *config_json, + const char *name, + const char *secret_file +) +{ + auto cred = grpc::sgx::TlsCredentials(config_json); + auto channel = grpc::CreateChannel(server_addr, cred); + + GrSecretClient gr_secret(channel); + + std::string secret = gr_secret.GetSecret(name); + //std::cout << "secret received: " << secret << std::endl; + + //Decode From Base64 + size_t len = base64_decode_len(secret.c_str()); + if (len) { + char *secret_orig = (char *)malloc(len); + base64_decode(secret.c_str(), (unsigned char *)secret_orig, len); + std::string secret_string(secret_orig, secret_orig + len - 1); + + //write to file + std::ofstream myfile; + myfile.open(secret_file); + myfile << secret_string; + myfile.close(); + } + + return 0; +} diff --git a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/grpc_ratls_client.h b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/grpc_ratls_client.h new file mode 100644 index 00000000..744a5f14 --- /dev/null +++ b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/grpc_ratls_client.h @@ -0,0 +1,20 @@ +#ifndef _GRPC_RATLS_CLIENT_H_ +#define _GRPC_RATLS_CLIENT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// client get secret +extern int gr_client_get_secret( + const char *server_addr, // grpc server address+port, such as "localhost:50051" + const char *config_json, // ratls handshake config json file + const char *name, // secret name to be requested + const char *secret_file // secret file to be saved +); + +#ifdef __cplusplus +} +#endif + +#endif // _GRPC_RATLS_CLIENT_H_ \ No newline at end of file diff --git a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/grpc_ratls_server.cc b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/grpc_ratls_server.cc new file mode 100644 index 00000000..d8654685 --- /dev/null +++ b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/grpc_ratls_server.cc @@ -0,0 +1,96 @@ +/* + * + * Copyright (c) 2022 Intel Corporation + * + * 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 +#include +#include + +#ifdef BAZEL_BUILD +#include "examples/protos/ratls.grpc.pb.h" +#else +#include "ratls.grpc.pb.h" +#endif + +#include "../grpc_ratls_server.h" + +using ratls::GrSecret; +using ratls::SecretRequest; +using ratls::SecretReply; + + +// Logic and data behind the server's behavior. +class GrSecretServiceImpl final: public GrSecret::Service { + public: + grpc::Status GetSecret( + grpc::ServerContext* context, const SecretRequest* request, SecretReply* reply) override { + //std::cout << "Request: " << request->name() << std::endl; + auto secret = this->get_secret_string(request->name().c_str()); + if (!secret.empty()) { + reply->set_secret(secret); + return grpc::Status::OK; + } else { + return grpc::Status::CANCELLED; + } + } + + GrSecretServiceImpl(const char* file) : secret_file(nullptr) { + this->secret_file = file; + } + + private: + std::string get_secret_string(const char *name) { + std::string secret = ""; + class grpc::sgx::json_engine secret_config(this->secret_file); + auto item = secret_config.get_item(secret_config.get_handle(), name); + if (item) { + secret = secret_config.print_item(item); + } + + return secret; + } + + const char *secret_file; +}; + + +int gr_start_server( + const char *server_addr, + const char *config_json, + const char *secret_json +) +{ + GrSecretServiceImpl service(secret_json); + + grpc::EnableDefaultHealthCheckService(true); + grpc::reflection::InitProtoReflectionServerBuilderPlugin(); + grpc::ServerBuilder builder; + + auto creds = grpc::sgx::TlsServerCredentials(config_json); + GPR_ASSERT(creds.get() != nullptr); + + builder.AddListeningPort(server_addr, creds); + builder.RegisterService(&service); + + std::unique_ptr server(builder.BuildAndStart()); + std::cout << "Server listening on " << server_addr << std::endl; + + server->Wait(); + + return 0; +} + diff --git a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/grpc_ratls_server.h b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/grpc_ratls_server.h new file mode 100644 index 00000000..c0560681 --- /dev/null +++ b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/grpc_ratls_server.h @@ -0,0 +1,19 @@ +#ifndef _GRPC_RATLS_SERVER_H_ +#define _GRPC_RATLS_SERVER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// start server +extern int gr_start_server( + const char *server_addr, // grpc server address+port, such as "localhost:50051" + const char *config_json, // ratls handshake config json file + const char *secret_json // secret config json file +); + +#ifdef __cplusplus +} +#endif + +#endif // _GRPC_RATLS_SERVER_H_ \ No newline at end of file diff --git a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/server.cc b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/server.cc index 90138dce..6b945476 100644 --- a/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/server.cc +++ b/demos/ra_tls/grpc/v1.38.1/examples/cpp/ratls/server.cc @@ -15,66 +15,15 @@ * limitations under the License. * */ +#include "../grpc_ratls_server.h" -#include -#include -#include - -#ifdef BAZEL_BUILD -#include "examples/protos/ratls.grpc.pb.h" -#else -#include "ratls.grpc.pb.h" -#endif - -#include "../getopt.hpp" - -using ratls::Greeter; -using ratls::HelloReply; -using ratls::HelloRequest; - -struct argparser { - const char* config; - std::string server_address; - argparser() { - server_address = getarg("localhost:50051", "-host", "--host"); - config = getarg("dynamic_config.json", "-cfg", "--config"); - }; -}; - -// Logic and data behind the server's behavior. -class GreeterServiceImpl final : public Greeter::Service { - grpc::Status SayHello( - grpc::ServerContext* context, const HelloRequest* request, HelloReply* reply) override { - std::string prefix("Hello "); - reply->set_message(prefix + request->name()); - return grpc::Status::OK; - } -}; - -void RunServer() { - argparser args; - - GreeterServiceImpl service; - - grpc::EnableDefaultHealthCheckService(true); - grpc::reflection::InitProtoReflectionServerBuilderPlugin(); - - grpc::ServerBuilder builder; - - auto creds = grpc::sgx::TlsServerCredentials(args.config); - GPR_ASSERT(creds.get() != nullptr); - - builder.AddListeningPort(args.server_address, creds); - - builder.RegisterService(&service); - - std::unique_ptr server(builder.BuildAndStart()); - std::cout << "Server listening on " << args.server_address << std::endl; - - server->Wait(); -} int main(int argc, char** argv) { - RunServer(); + gr_start_server( + "localhost:50051", + "dynamic_config.json", + "secret_config.json" + ); + return 0; -} +} \ No newline at end of file diff --git a/demos/ra_tls/grpc/v1.38.1/examples/protos/ratls.proto b/demos/ra_tls/grpc/v1.38.1/examples/protos/ratls.proto index 1bb854d7..0bae7047 100644 --- a/demos/ra_tls/grpc/v1.38.1/examples/protos/ratls.proto +++ b/demos/ra_tls/grpc/v1.38.1/examples/protos/ratls.proto @@ -21,18 +21,18 @@ option objc_class_prefix = "HLW"; package ratls; -// The greeting service definition. -service Greeter { +// The GRPC_RATLS secret service definition. +service GrSecret { // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} + rpc GetSecret (SecretRequest) returns (SecretReply) {} } -// The request message containing the user's name. -message HelloRequest { +// The request message containing the request's name. +message SecretRequest { string name = 1; } -// The response message containing the greetings -message HelloReply { - string message = 1; +// The response message containing the secret (base64 encoded string) +message SecretReply { + string secret = 1; } diff --git a/demos/ra_tls/grpc/v1.38.1/include/grpcpp/security/sgx/sgx_ra_tls.h b/demos/ra_tls/grpc/v1.38.1/include/grpcpp/security/sgx/sgx_ra_tls.h index 7e231802..2ea167d2 100644 --- a/demos/ra_tls/grpc/v1.38.1/include/grpcpp/security/sgx/sgx_ra_tls.h +++ b/demos/ra_tls/grpc/v1.38.1/include/grpcpp/security/sgx/sgx_ra_tls.h @@ -24,6 +24,8 @@ #include #include +#include + namespace grpc { namespace sgx { @@ -51,6 +53,30 @@ std::shared_ptr TlsServerCredentials(const char* sgx_cf std::shared_ptr CreateSecureChannel( string target_str, std::shared_ptr channel_creds); +class json_engine { + public: + json_engine(); + + json_engine(const char*); + + ~json_engine(); + + bool open(const char*); + + void close(); + + cJSON* get_handle(); + + cJSON* get_item(cJSON* obj, const char* item); + + char* print_item(cJSON* obj); + + bool compare_item(cJSON* obj, const char* item); + + private: + cJSON* handle; +}; + } // namespace sgx } // namespace grpc diff --git a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/cJSON.c b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/cJSON.c deleted file mode 100644 index 04b5079c..00000000 --- a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/cJSON.c +++ /dev/null @@ -1,567 +0,0 @@ -/* - Copyright (c) 2009 Dave Gamble - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -/* cJSON */ -/* JSON parser in C. */ - -#include -#include -#include -#include -#include -#include -#include -#include "cJSON.h" - -static const char *ep; - -const char *cJSON_GetErrorPtr(void) {return ep;} - -static int cJSON_strcasecmp(const char *s1,const char *s2) -{ - if (!s1) return (s1==s2)?0:1;if (!s2) return 1; - for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0; - return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); -} - -static void *(*cJSON_malloc)(size_t sz) = malloc; -static void (*cJSON_free)(void *ptr) = free; - -static char* cJSON_strdup(const char* str) -{ - size_t len; - char* copy; - - len = strlen(str) + 1; - if (!(copy = (char*)cJSON_malloc(len))) return 0; - memcpy(copy,str,len); - return copy; -} - -void cJSON_InitHooks(cJSON_Hooks* hooks) -{ - if (!hooks) { /* Reset hooks */ - cJSON_malloc = malloc; - cJSON_free = free; - return; - } - - cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; - cJSON_free = (hooks->free_fn)?hooks->free_fn:free; -} - -/* Internal constructor. */ -static cJSON *cJSON_New_Item(void) -{ - cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); - if (node) memset(node,0,sizeof(cJSON)); - return node; -} - -/* Delete a cJSON structure. */ -void cJSON_Delete(cJSON *c) -{ - cJSON *next; - while (c) - { - next=c->next; - if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); - if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); - if (c->string) cJSON_free(c->string); - cJSON_free(c); - c=next; - } -} - -/* Parse the input text to generate a number, and populate the result into item. */ -static const char *parse_number(cJSON *item,const char *num) -{ - double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; - - /* Could use sscanf for this? */ - if (*num=='-') sign=-1,num++; /* Has sign? */ - if (*num=='0') num++; /* is zero */ - if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */ - if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */ - if (*num=='e' || *num=='E') /* Exponent? */ - { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */ - while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */ - } - - n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ - - item->valuedouble=n; - item->valueint=(int)n; - item->type=cJSON_Number; - return num; -} - -/* Render the number nicely from the given item into a string. */ -static char *print_number(cJSON *item) -{ - char *str; - double d=item->valuedouble; - if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) - { - str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ - if (str) sprintf(str,"%d",item->valueint); - } - else - { - str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */ - if (str) - { - if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d); - else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d); - else sprintf(str,"%f",d); - } - } - return str; -} - -/* Parse the input text into an unescaped cstring, and populate item. */ -static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; -static const char *parse_string(cJSON *item,const char *str) -{ - const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2; - if (*str!='\"') {ep=str;return 0;} /* not a string! */ - - while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ - - out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ - if (!out) return 0; - - ptr=str+1;ptr2=out; - while (*ptr!='\"' && *ptr) - { - if (*ptr!='\\') *ptr2++=*ptr++; - else - { - ptr++; - switch (*ptr) - { - case 'b': *ptr2++='\b'; break; - case 'f': *ptr2++='\f'; break; - case 'n': *ptr2++='\n'; break; - case 'r': *ptr2++='\r'; break; - case 't': *ptr2++='\t'; break; - case 'u': /* transcode utf16 to utf8. */ - sscanf(ptr+1,"%4x",&uc);ptr+=4; /* get the unicode char. */ - - if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */ - - if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */ - { - if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */ - sscanf(ptr+3,"%4x",&uc2);ptr+=6; - if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */ - uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); - } - - len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; - - switch (len) { - case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - case 1: *--ptr2 =(uc | firstByteMark[len]); - } - ptr2+=len; - break; - default: *ptr2++=*ptr; break; - } - ptr++; - } - } - *ptr2=0; - if (*ptr=='\"') ptr++; - item->valuestring=out; - item->type=cJSON_String; - return ptr; -} - -/* Render the cstring provided to an escaped version that can be printed. */ -static char *print_string_ptr(const char *str) -{ - const char *ptr;char *ptr2,*out;int len=0;unsigned char token; - - if (!str) return cJSON_strdup(""); - ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} - - out=(char*)cJSON_malloc(len+3); - if (!out) return 0; - - ptr2=out;ptr=str; - *ptr2++='\"'; - while (*ptr) - { - if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; - else - { - *ptr2++='\\'; - switch (token=*ptr++) - { - case '\\': *ptr2++='\\'; break; - case '\"': *ptr2++='\"'; break; - case '\b': *ptr2++='b'; break; - case '\f': *ptr2++='f'; break; - case '\n': *ptr2++='n'; break; - case '\r': *ptr2++='r'; break; - case '\t': *ptr2++='t'; break; - default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */ - } - } - } - *ptr2++='\"';*ptr2++=0; - return out; -} -/* Invote print_string_ptr (which is useful) on an item. */ -static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);} - -/* Predeclare these prototypes. */ -static const char *parse_value(cJSON *item,const char *value); -static char *print_value(cJSON *item,int depth,int fmt); -static const char *parse_array(cJSON *item,const char *value); -static char *print_array(cJSON *item,int depth,int fmt); -static const char *parse_object(cJSON *item,const char *value); -static char *print_object(cJSON *item,int depth,int fmt); - -/* Utility to jump whitespace and cr/lf */ -static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;} - -/* Parse an object - create a new root, and populate. */ -cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated) -{ - const char *end=0; - cJSON *c=cJSON_New_Item(); - ep=0; - if (!c) return 0; /* memory fail */ - - end=parse_value(c,skip(value)); - if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */ - - /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ - if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}} - if (return_parse_end) *return_parse_end=end; - return c; -} -/* Default options for cJSON_Parse */ -cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);} - -/* Render a cJSON item/entity/structure to text. */ -char *cJSON_Print(cJSON *item) {return print_value(item,0,1);} -char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);} - -/* Parser core - when encountering text, process appropriately. */ -static const char *parse_value(cJSON *item,const char *value) -{ - if (!value) return 0; /* Fail on null. */ - if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; } - if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; } - if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; } - if (*value=='\"') { return parse_string(item,value); } - if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); } - if (*value=='[') { return parse_array(item,value); } - if (*value=='{') { return parse_object(item,value); } - - ep=value;return 0; /* failure. */ -} - -/* Render a value to text. */ -static char *print_value(cJSON *item,int depth,int fmt) -{ - char *out=0; - if (!item) return 0; - switch ((item->type)&255) - { - case cJSON_NULL: out=cJSON_strdup("null"); break; - case cJSON_False: out=cJSON_strdup("false");break; - case cJSON_True: out=cJSON_strdup("true"); break; - case cJSON_Number: out=print_number(item);break; - case cJSON_String: out=print_string(item);break; - case cJSON_Array: out=print_array(item,depth,fmt);break; - case cJSON_Object: out=print_object(item,depth,fmt);break; - } - return out; -} - -/* Build an array from input text. */ -static const char *parse_array(cJSON *item,const char *value) -{ - cJSON *child; - if (*value!='[') {ep=value;return 0;} /* not an array! */ - - item->type=cJSON_Array; - value=skip(value+1); - if (*value==']') return value+1; /* empty array. */ - - item->child=child=cJSON_New_Item(); - if (!item->child) return 0; /* memory fail */ - value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */ - if (!value) return 0; - - while (*value==',') - { - cJSON *new_item; - if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ - child->next=new_item;new_item->prev=child;child=new_item; - value=skip(parse_value(child,skip(value+1))); - if (!value) return 0; /* memory fail */ - } - - if (*value==']') return value+1; /* end of array */ - ep=value;return 0; /* malformed. */ -} - -/* Render an array to text */ -static char *print_array(cJSON *item,int depth,int fmt) -{ - char **entries; - char *out=0,*ptr,*ret;int len=5; - cJSON *child=item->child; - int numentries=0,i=0,fail=0; - - /* How many entries in the array? */ - while (child) numentries++,child=child->next; - /* Explicitly handle numentries==0 */ - if (!numentries) - { - out=(char*)cJSON_malloc(3); - if (out) strcpy(out,"[]"); - return out; - } - /* Allocate an array to hold the values for each */ - entries=(char**)cJSON_malloc(numentries*sizeof(char*)); - if (!entries) return 0; - memset(entries,0,numentries*sizeof(char*)); - /* Retrieve all the results: */ - child=item->child; - while (child && !fail) - { - ret=print_value(child,depth+1,fmt); - entries[i++]=ret; - if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1; - child=child->next; - } - - /* If we didn't fail, try to malloc the output string */ - if (!fail) out=(char*)cJSON_malloc(len); - /* If that fails, we fail. */ - if (!out) fail=1; - - /* Handle failure. */ - if (fail) - { - for (i=0;itype=cJSON_Object; - value=skip(value+1); - if (*value=='}') return value+1; /* empty array. */ - - item->child=child=cJSON_New_Item(); - if (!item->child) return 0; - value=skip(parse_string(child,skip(value))); - if (!value) return 0; - child->string=child->valuestring;child->valuestring=0; - if (*value!=':') {ep=value;return 0;} /* fail! */ - value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ - if (!value) return 0; - - while (*value==',') - { - cJSON *new_item; - if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ - child->next=new_item;new_item->prev=child;child=new_item; - value=skip(parse_string(child,skip(value+1))); - if (!value) return 0; - child->string=child->valuestring;child->valuestring=0; - if (*value!=':') {ep=value;return 0;} /* fail! */ - value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ - if (!value) return 0; - } - - if (*value=='}') return value+1; /* end of array */ - ep=value;return 0; /* malformed. */ -} - -/* Render an object to text. */ -static char *print_object(cJSON *item,int depth,int fmt) -{ - char **entries=0,**names=0; - char *out=0,*ptr,*ret,*str;int len=7,i=0,j; - cJSON *child=item->child; - int numentries=0,fail=0; - /* Count the number of entries. */ - while (child) numentries++,child=child->next; - /* Explicitly handle empty object case */ - if (!numentries) - { - out=(char*)cJSON_malloc(fmt?depth+3:3); - if (!out) return 0; - ptr=out;*ptr++='{'; - if (fmt) {*ptr++='\n';for (i=0;ichild;depth++;if (fmt) len+=depth; - while (child) - { - names[i]=str=print_string_ptr(child->string); - entries[i++]=ret=print_value(child,depth,fmt); - if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; - child=child->next; - } - - /* Try to allocate the output string */ - if (!fail) out=(char*)cJSON_malloc(len); - if (!out) fail=1; - - /* Handle failure */ - if (fail) - { - for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;} -cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} -cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} - -/* Utility for array list handling. */ -static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} -/* Utility for handling references. */ -static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;} - -/* Add item to array/object. */ -void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} -void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);} -void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));} -void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));} - -cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0; - if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;} -void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));} -cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;} -void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} - -/* Replace array/object items with new ones. */ -void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; - newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem; - if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);} -void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} - -/* Create basic types: */ -cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} -cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} -cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} -cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} -cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;} -cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} -cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} -cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} - -/* Create Arrays: */ -cJSON *cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} -cJSON *cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} -cJSON *cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} -cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} - -/* Duplication */ -cJSON *cJSON_Duplicate(cJSON *item,int recurse) -{ - cJSON *newitem,*cptr,*nptr=0,*newchild; - /* Bail on bad ptr */ - if (!item) return 0; - /* Create new item */ - newitem=cJSON_New_Item(); - if (!newitem) return 0; - /* Copy over all vars */ - newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble; - if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}} - if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}} - /* If non-recursive, then we're done! */ - if (!recurse) return newitem; - /* Walk the ->next chain for the child. */ - cptr=item->child; - while (cptr) - { - newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */ - if (!newchild) {cJSON_Delete(newitem);return 0;} - if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */ - else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */ - cptr=cptr->next; - } - return newitem; -} diff --git a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/cJSON.h b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/cJSON.h deleted file mode 100644 index 9cedb93d..00000000 --- a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/cJSON.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - Copyright (c) 2009 Dave Gamble - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#ifndef cJSON__h -#define cJSON__h - -#ifdef __cplusplus -extern "C" -{ -#endif -#include -/* cJSON Types: */ -#define cJSON_False 0 -#define cJSON_True 1 -#define cJSON_NULL 2 -#define cJSON_Number 3 -#define cJSON_String 4 -#define cJSON_Array 5 -#define cJSON_Object 6 - -#define cJSON_IsReference 256 - -/* The cJSON structure: */ -typedef struct cJSON { - struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ - struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ - - int type; /* The type of the item, as above. */ - - char *valuestring; /* The item's string, if type==cJSON_String */ - int valueint; /* The item's number, if type==cJSON_Number */ - double valuedouble; /* The item's number, if type==cJSON_Number */ - - char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ -} cJSON; - -typedef struct cJSON_Hooks { - void *(*malloc_fn)(size_t sz); - void (*free_fn)(void *ptr); -} cJSON_Hooks; - -/* Supply malloc, realloc and free functions to cJSON */ -extern void cJSON_InitHooks(cJSON_Hooks* hooks); - - -/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ -extern cJSON *cJSON_Parse(const char *value); -/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ -extern char *cJSON_Print(cJSON *item); -/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ -extern char *cJSON_PrintUnformatted(cJSON *item); -/* Delete a cJSON entity and all subentities. */ -extern void cJSON_Delete(cJSON *c); - -/* Returns the number of items in an array (or object). */ -extern int cJSON_GetArraySize(cJSON *array); -/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ -extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); -/* Get item "string" from object. Case insensitive. */ -extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); - -/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ -extern const char *cJSON_GetErrorPtr(void); - -/* These calls create a cJSON item of the appropriate type. */ -extern cJSON *cJSON_CreateNull(void); -extern cJSON *cJSON_CreateTrue(void); -extern cJSON *cJSON_CreateFalse(void); -extern cJSON *cJSON_CreateBool(int b); -extern cJSON *cJSON_CreateNumber(double num); -extern cJSON *cJSON_CreateString(const char *string); -extern cJSON *cJSON_CreateArray(void); -extern cJSON *cJSON_CreateObject(void); - -/* These utilities create an Array of count items. */ -extern cJSON *cJSON_CreateIntArray(int *numbers,int count); -extern cJSON *cJSON_CreateFloatArray(float *numbers,int count); -extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count); -extern cJSON *cJSON_CreateStringArray(const char **strings,int count); - -/* Append item to the specified array/object. */ -extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); -extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); -/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ -extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); -extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); - -/* Remove/Detatch items from Arrays/Objects. */ -extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which); -extern void cJSON_DeleteItemFromArray(cJSON *array,int which); -extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string); -extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string); - -/* Update array items. */ -extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); -extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); - -/* Duplicate a cJSON item */ -extern cJSON *cJSON_Duplicate(cJSON *item,int recurse); -/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will -need to be released. With recurse!=0, it will duplicate any children connected to the item. -The item->next and ->prev pointers are always zero on return from Duplicate. */ - -/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ -extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated); - -/* Macros for creating things quickly. */ -#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) -#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) -#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) -#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) -#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) -#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) - -/* When assigning an integer value, it needs to be propagated to valuedouble too. */ -#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) -#ifdef __cplusplus -} -#endif - -#endif diff --git a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/cjson/cJSON.c b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/cjson/cJSON.c deleted file mode 100644 index 04b5079c..00000000 --- a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/cjson/cJSON.c +++ /dev/null @@ -1,567 +0,0 @@ -/* - Copyright (c) 2009 Dave Gamble - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -/* cJSON */ -/* JSON parser in C. */ - -#include -#include -#include -#include -#include -#include -#include -#include "cJSON.h" - -static const char *ep; - -const char *cJSON_GetErrorPtr(void) {return ep;} - -static int cJSON_strcasecmp(const char *s1,const char *s2) -{ - if (!s1) return (s1==s2)?0:1;if (!s2) return 1; - for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0; - return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); -} - -static void *(*cJSON_malloc)(size_t sz) = malloc; -static void (*cJSON_free)(void *ptr) = free; - -static char* cJSON_strdup(const char* str) -{ - size_t len; - char* copy; - - len = strlen(str) + 1; - if (!(copy = (char*)cJSON_malloc(len))) return 0; - memcpy(copy,str,len); - return copy; -} - -void cJSON_InitHooks(cJSON_Hooks* hooks) -{ - if (!hooks) { /* Reset hooks */ - cJSON_malloc = malloc; - cJSON_free = free; - return; - } - - cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; - cJSON_free = (hooks->free_fn)?hooks->free_fn:free; -} - -/* Internal constructor. */ -static cJSON *cJSON_New_Item(void) -{ - cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); - if (node) memset(node,0,sizeof(cJSON)); - return node; -} - -/* Delete a cJSON structure. */ -void cJSON_Delete(cJSON *c) -{ - cJSON *next; - while (c) - { - next=c->next; - if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); - if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); - if (c->string) cJSON_free(c->string); - cJSON_free(c); - c=next; - } -} - -/* Parse the input text to generate a number, and populate the result into item. */ -static const char *parse_number(cJSON *item,const char *num) -{ - double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; - - /* Could use sscanf for this? */ - if (*num=='-') sign=-1,num++; /* Has sign? */ - if (*num=='0') num++; /* is zero */ - if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */ - if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */ - if (*num=='e' || *num=='E') /* Exponent? */ - { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */ - while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */ - } - - n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ - - item->valuedouble=n; - item->valueint=(int)n; - item->type=cJSON_Number; - return num; -} - -/* Render the number nicely from the given item into a string. */ -static char *print_number(cJSON *item) -{ - char *str; - double d=item->valuedouble; - if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) - { - str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ - if (str) sprintf(str,"%d",item->valueint); - } - else - { - str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */ - if (str) - { - if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d); - else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d); - else sprintf(str,"%f",d); - } - } - return str; -} - -/* Parse the input text into an unescaped cstring, and populate item. */ -static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; -static const char *parse_string(cJSON *item,const char *str) -{ - const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2; - if (*str!='\"') {ep=str;return 0;} /* not a string! */ - - while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ - - out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ - if (!out) return 0; - - ptr=str+1;ptr2=out; - while (*ptr!='\"' && *ptr) - { - if (*ptr!='\\') *ptr2++=*ptr++; - else - { - ptr++; - switch (*ptr) - { - case 'b': *ptr2++='\b'; break; - case 'f': *ptr2++='\f'; break; - case 'n': *ptr2++='\n'; break; - case 'r': *ptr2++='\r'; break; - case 't': *ptr2++='\t'; break; - case 'u': /* transcode utf16 to utf8. */ - sscanf(ptr+1,"%4x",&uc);ptr+=4; /* get the unicode char. */ - - if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */ - - if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */ - { - if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */ - sscanf(ptr+3,"%4x",&uc2);ptr+=6; - if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */ - uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); - } - - len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; - - switch (len) { - case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - case 1: *--ptr2 =(uc | firstByteMark[len]); - } - ptr2+=len; - break; - default: *ptr2++=*ptr; break; - } - ptr++; - } - } - *ptr2=0; - if (*ptr=='\"') ptr++; - item->valuestring=out; - item->type=cJSON_String; - return ptr; -} - -/* Render the cstring provided to an escaped version that can be printed. */ -static char *print_string_ptr(const char *str) -{ - const char *ptr;char *ptr2,*out;int len=0;unsigned char token; - - if (!str) return cJSON_strdup(""); - ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} - - out=(char*)cJSON_malloc(len+3); - if (!out) return 0; - - ptr2=out;ptr=str; - *ptr2++='\"'; - while (*ptr) - { - if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; - else - { - *ptr2++='\\'; - switch (token=*ptr++) - { - case '\\': *ptr2++='\\'; break; - case '\"': *ptr2++='\"'; break; - case '\b': *ptr2++='b'; break; - case '\f': *ptr2++='f'; break; - case '\n': *ptr2++='n'; break; - case '\r': *ptr2++='r'; break; - case '\t': *ptr2++='t'; break; - default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */ - } - } - } - *ptr2++='\"';*ptr2++=0; - return out; -} -/* Invote print_string_ptr (which is useful) on an item. */ -static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);} - -/* Predeclare these prototypes. */ -static const char *parse_value(cJSON *item,const char *value); -static char *print_value(cJSON *item,int depth,int fmt); -static const char *parse_array(cJSON *item,const char *value); -static char *print_array(cJSON *item,int depth,int fmt); -static const char *parse_object(cJSON *item,const char *value); -static char *print_object(cJSON *item,int depth,int fmt); - -/* Utility to jump whitespace and cr/lf */ -static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;} - -/* Parse an object - create a new root, and populate. */ -cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated) -{ - const char *end=0; - cJSON *c=cJSON_New_Item(); - ep=0; - if (!c) return 0; /* memory fail */ - - end=parse_value(c,skip(value)); - if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */ - - /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ - if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}} - if (return_parse_end) *return_parse_end=end; - return c; -} -/* Default options for cJSON_Parse */ -cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);} - -/* Render a cJSON item/entity/structure to text. */ -char *cJSON_Print(cJSON *item) {return print_value(item,0,1);} -char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);} - -/* Parser core - when encountering text, process appropriately. */ -static const char *parse_value(cJSON *item,const char *value) -{ - if (!value) return 0; /* Fail on null. */ - if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; } - if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; } - if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; } - if (*value=='\"') { return parse_string(item,value); } - if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); } - if (*value=='[') { return parse_array(item,value); } - if (*value=='{') { return parse_object(item,value); } - - ep=value;return 0; /* failure. */ -} - -/* Render a value to text. */ -static char *print_value(cJSON *item,int depth,int fmt) -{ - char *out=0; - if (!item) return 0; - switch ((item->type)&255) - { - case cJSON_NULL: out=cJSON_strdup("null"); break; - case cJSON_False: out=cJSON_strdup("false");break; - case cJSON_True: out=cJSON_strdup("true"); break; - case cJSON_Number: out=print_number(item);break; - case cJSON_String: out=print_string(item);break; - case cJSON_Array: out=print_array(item,depth,fmt);break; - case cJSON_Object: out=print_object(item,depth,fmt);break; - } - return out; -} - -/* Build an array from input text. */ -static const char *parse_array(cJSON *item,const char *value) -{ - cJSON *child; - if (*value!='[') {ep=value;return 0;} /* not an array! */ - - item->type=cJSON_Array; - value=skip(value+1); - if (*value==']') return value+1; /* empty array. */ - - item->child=child=cJSON_New_Item(); - if (!item->child) return 0; /* memory fail */ - value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */ - if (!value) return 0; - - while (*value==',') - { - cJSON *new_item; - if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ - child->next=new_item;new_item->prev=child;child=new_item; - value=skip(parse_value(child,skip(value+1))); - if (!value) return 0; /* memory fail */ - } - - if (*value==']') return value+1; /* end of array */ - ep=value;return 0; /* malformed. */ -} - -/* Render an array to text */ -static char *print_array(cJSON *item,int depth,int fmt) -{ - char **entries; - char *out=0,*ptr,*ret;int len=5; - cJSON *child=item->child; - int numentries=0,i=0,fail=0; - - /* How many entries in the array? */ - while (child) numentries++,child=child->next; - /* Explicitly handle numentries==0 */ - if (!numentries) - { - out=(char*)cJSON_malloc(3); - if (out) strcpy(out,"[]"); - return out; - } - /* Allocate an array to hold the values for each */ - entries=(char**)cJSON_malloc(numentries*sizeof(char*)); - if (!entries) return 0; - memset(entries,0,numentries*sizeof(char*)); - /* Retrieve all the results: */ - child=item->child; - while (child && !fail) - { - ret=print_value(child,depth+1,fmt); - entries[i++]=ret; - if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1; - child=child->next; - } - - /* If we didn't fail, try to malloc the output string */ - if (!fail) out=(char*)cJSON_malloc(len); - /* If that fails, we fail. */ - if (!out) fail=1; - - /* Handle failure. */ - if (fail) - { - for (i=0;itype=cJSON_Object; - value=skip(value+1); - if (*value=='}') return value+1; /* empty array. */ - - item->child=child=cJSON_New_Item(); - if (!item->child) return 0; - value=skip(parse_string(child,skip(value))); - if (!value) return 0; - child->string=child->valuestring;child->valuestring=0; - if (*value!=':') {ep=value;return 0;} /* fail! */ - value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ - if (!value) return 0; - - while (*value==',') - { - cJSON *new_item; - if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ - child->next=new_item;new_item->prev=child;child=new_item; - value=skip(parse_string(child,skip(value+1))); - if (!value) return 0; - child->string=child->valuestring;child->valuestring=0; - if (*value!=':') {ep=value;return 0;} /* fail! */ - value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ - if (!value) return 0; - } - - if (*value=='}') return value+1; /* end of array */ - ep=value;return 0; /* malformed. */ -} - -/* Render an object to text. */ -static char *print_object(cJSON *item,int depth,int fmt) -{ - char **entries=0,**names=0; - char *out=0,*ptr,*ret,*str;int len=7,i=0,j; - cJSON *child=item->child; - int numentries=0,fail=0; - /* Count the number of entries. */ - while (child) numentries++,child=child->next; - /* Explicitly handle empty object case */ - if (!numentries) - { - out=(char*)cJSON_malloc(fmt?depth+3:3); - if (!out) return 0; - ptr=out;*ptr++='{'; - if (fmt) {*ptr++='\n';for (i=0;ichild;depth++;if (fmt) len+=depth; - while (child) - { - names[i]=str=print_string_ptr(child->string); - entries[i++]=ret=print_value(child,depth,fmt); - if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; - child=child->next; - } - - /* Try to allocate the output string */ - if (!fail) out=(char*)cJSON_malloc(len); - if (!out) fail=1; - - /* Handle failure */ - if (fail) - { - for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;} -cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} -cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} - -/* Utility for array list handling. */ -static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} -/* Utility for handling references. */ -static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;} - -/* Add item to array/object. */ -void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} -void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);} -void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));} -void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));} - -cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0; - if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;} -void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));} -cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;} -void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} - -/* Replace array/object items with new ones. */ -void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; - newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem; - if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);} -void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} - -/* Create basic types: */ -cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} -cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} -cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} -cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} -cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;} -cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} -cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} -cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} - -/* Create Arrays: */ -cJSON *cJSON_CreateIntArray(int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} -cJSON *cJSON_CreateFloatArray(float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} -cJSON *cJSON_CreateDoubleArray(double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} -cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} - -/* Duplication */ -cJSON *cJSON_Duplicate(cJSON *item,int recurse) -{ - cJSON *newitem,*cptr,*nptr=0,*newchild; - /* Bail on bad ptr */ - if (!item) return 0; - /* Create new item */ - newitem=cJSON_New_Item(); - if (!newitem) return 0; - /* Copy over all vars */ - newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble; - if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}} - if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}} - /* If non-recursive, then we're done! */ - if (!recurse) return newitem; - /* Walk the ->next chain for the child. */ - cptr=item->child; - while (cptr) - { - newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */ - if (!newchild) {cJSON_Delete(newitem);return 0;} - if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */ - else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */ - cptr=cptr->next; - } - return newitem; -} diff --git a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/cjson/cJSON.h b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/cjson/cJSON.h deleted file mode 100644 index 9cedb93d..00000000 --- a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/cjson/cJSON.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - Copyright (c) 2009 Dave Gamble - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#ifndef cJSON__h -#define cJSON__h - -#ifdef __cplusplus -extern "C" -{ -#endif -#include -/* cJSON Types: */ -#define cJSON_False 0 -#define cJSON_True 1 -#define cJSON_NULL 2 -#define cJSON_Number 3 -#define cJSON_String 4 -#define cJSON_Array 5 -#define cJSON_Object 6 - -#define cJSON_IsReference 256 - -/* The cJSON structure: */ -typedef struct cJSON { - struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ - struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ - - int type; /* The type of the item, as above. */ - - char *valuestring; /* The item's string, if type==cJSON_String */ - int valueint; /* The item's number, if type==cJSON_Number */ - double valuedouble; /* The item's number, if type==cJSON_Number */ - - char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ -} cJSON; - -typedef struct cJSON_Hooks { - void *(*malloc_fn)(size_t sz); - void (*free_fn)(void *ptr); -} cJSON_Hooks; - -/* Supply malloc, realloc and free functions to cJSON */ -extern void cJSON_InitHooks(cJSON_Hooks* hooks); - - -/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ -extern cJSON *cJSON_Parse(const char *value); -/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ -extern char *cJSON_Print(cJSON *item); -/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ -extern char *cJSON_PrintUnformatted(cJSON *item); -/* Delete a cJSON entity and all subentities. */ -extern void cJSON_Delete(cJSON *c); - -/* Returns the number of items in an array (or object). */ -extern int cJSON_GetArraySize(cJSON *array); -/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ -extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); -/* Get item "string" from object. Case insensitive. */ -extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); - -/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ -extern const char *cJSON_GetErrorPtr(void); - -/* These calls create a cJSON item of the appropriate type. */ -extern cJSON *cJSON_CreateNull(void); -extern cJSON *cJSON_CreateTrue(void); -extern cJSON *cJSON_CreateFalse(void); -extern cJSON *cJSON_CreateBool(int b); -extern cJSON *cJSON_CreateNumber(double num); -extern cJSON *cJSON_CreateString(const char *string); -extern cJSON *cJSON_CreateArray(void); -extern cJSON *cJSON_CreateObject(void); - -/* These utilities create an Array of count items. */ -extern cJSON *cJSON_CreateIntArray(int *numbers,int count); -extern cJSON *cJSON_CreateFloatArray(float *numbers,int count); -extern cJSON *cJSON_CreateDoubleArray(double *numbers,int count); -extern cJSON *cJSON_CreateStringArray(const char **strings,int count); - -/* Append item to the specified array/object. */ -extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); -extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); -/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ -extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); -extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); - -/* Remove/Detatch items from Arrays/Objects. */ -extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which); -extern void cJSON_DeleteItemFromArray(cJSON *array,int which); -extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string); -extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string); - -/* Update array items. */ -extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); -extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); - -/* Duplicate a cJSON item */ -extern cJSON *cJSON_Duplicate(cJSON *item,int recurse); -/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will -need to be released. With recurse!=0, it will duplicate any children connected to the item. -The item->next and ->prev pointers are always zero on return from Duplicate. */ - -/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ -extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated); - -/* Macros for creating things quickly. */ -#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) -#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) -#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) -#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) -#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) -#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) - -/* When assigning an integer value, it needs to be propagated to valuedouble too. */ -#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) -#ifdef __cplusplus -} -#endif - -#endif diff --git a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_backend.cc b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_backend.cc index 1735281b..2daf2dbc 100644 --- a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_backend.cc +++ b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_backend.cc @@ -1,7 +1,7 @@ #include "sgx_ra_tls_utils.h" #include "sgx_ra_tls_backend.h" #include "sgx_quote_3.h" -#include "dcap_quote.h" +#include "occlum_dcap.h" namespace grpc { namespace sgx { diff --git a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_occlum.cc b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_occlum.cc index 65cc26c5..897e50cc 100644 --- a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_occlum.cc +++ b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_occlum.cc @@ -32,7 +32,7 @@ namespace sgx { #include #include "sgx_quote_3.h" -#include "dcap_quote.h" +#include "occlum_dcap.h" const char * RA_TLS_LONG_NAME = "RA-TLS Extension"; const char * RA_TLS_SHORT_NAME = "RA-TLS"; diff --git a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_utils.h b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_utils.h index d7088370..35bfde93 100644 --- a/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_utils.h +++ b/demos/ra_tls/grpc/v1.38.1/src/cpp/sgx/sgx_ra_tls_utils.h @@ -27,10 +27,11 @@ #define grpc_printf printf #define grpc_fprintf fprintf +#include + namespace grpc { namespace sgx { -#include "cjson/cJSON.h" class library_engine { public: @@ -53,30 +54,6 @@ class library_engine { char* error; }; -class json_engine { - public: - json_engine(); - - json_engine(const char*); - - ~json_engine(); - - bool open(const char*); - - void close(); - - cJSON* get_handle(); - - cJSON* get_item(cJSON* obj, const char* item); - - char* print_item(cJSON* obj); - - bool compare_item(cJSON* obj, const char* item); - - private: - cJSON* handle; -}; - void check_free(void* ptr); bool hex_to_byte(const char* src, char* dst, size_t dst_size); diff --git a/demos/ra_tls/grpc_ratls_client.yaml b/demos/ra_tls/grpc_ratls_client.yaml new file mode 100644 index 00000000..d2a45d16 --- /dev/null +++ b/demos/ra_tls/grpc_ratls_client.yaml @@ -0,0 +1,15 @@ +includes: + - base.yaml +targets: + - target: /bin/ + copy: + - files: + - ../grpc-src/examples/cpp/ratls/build/client + - target: / + copy: + - files: + - dynamic_config.json + - target: /usr/share/grpc/ + copy: + - files: + - ../grpc-src/etc/roots.pem diff --git a/demos/ra_tls/grpc_ratls_server.yaml b/demos/ra_tls/grpc_ratls_server.yaml new file mode 100644 index 00000000..79716e72 --- /dev/null +++ b/demos/ra_tls/grpc_ratls_server.yaml @@ -0,0 +1,16 @@ +includes: + - base.yaml +targets: + - target: /bin/ + copy: + - files: + - ../grpc-src/examples/cpp/ratls/build/server + - target: / + copy: + - files: + - dynamic_config.json + - ../secret_config.json + - target: /usr/share/grpc/ + copy: + - files: + - ../grpc-src/etc/roots.pem diff --git a/demos/ra_tls/prepare_and_build_package.sh b/demos/ra_tls/prepare_and_build_package.sh deleted file mode 100755 index 1b3cba23..00000000 --- a/demos/ra_tls/prepare_and_build_package.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -INSTALL_PREFIX=/usr/local -apt-get update \ - && apt-get install -y --no-install-recommends apt-utils \ - && apt-get install -y \ - ca-certificates \ - build-essential \ - autoconf \ - libtool \ - python3-pip \ - python3-dev \ - git \ - wget \ - unzip - -mkdir -p ${INSTALL_PREFIX} \ - && wget -q -O cmake-linux.sh https://github.com/Kitware/CMake/releases/download/v3.19.6/cmake-3.19.6-Linux-x86_64.sh \ - && sh cmake-linux.sh -- --skip-license --prefix=${INSTALL_PREFIX} \ - && rm cmake-linux.sh - -# Install cJSON -CJSON_PATH=/cJSON -git clone https://github.com/DaveGamble/cJSON.git ${CJSON_PATH} -pushd ${CJSON_PATH} \ - && make static \ - && cp -r *.a ${INSTALL_PREFIX}/lib \ - && mkdir -p ${INSTALL_PREFIX}/include/cjson \ - && cp -r *.h ${INSTALL_PREFIX}/include/cjson -popd - -# GRPC env -GRPC_VERSION=v1.38.x -export GRPC_PATH=/grpc - -# GRPC source code -git clone https://github.com/grpc/grpc -b ${GRPC_VERSION} ${GRPC_PATH} -pushd ${GRPC_PATH} \ - && pip3 install --upgrade pip setuptools==44.1.1 \ - && pip3 install -r requirements.txt \ - && git checkout v1.38.1 \ - && git submodule update --init -popd - -cp -rf grpc/common/* ${GRPC_PATH}/ -cp -rf grpc/v1.38.1/* ${GRPC_PATH}/ - -git clone https://github.com/occlum/occlum -pushd occlum -make submodule -cd demos/remote_attestation/dcap/dcap_lib -cargo build --all-targets -cp target/debug/libdcap_quote.a /usr/local/lib/ -cp ../c_app/dcap_quote.h /usr/local/include/ -popd - -pushd ${GRPC_PATH}/examples/cpp/ratls -./build.sh -popd - diff --git a/demos/ra_tls/dynamic_config.json b/demos/ra_tls/ra_config_template.json similarity index 59% rename from demos/ra_tls/dynamic_config.json rename to demos/ra_tls/ra_config_template.json index f63e10db..0560c5d9 100644 --- a/demos/ra_tls/dynamic_config.json +++ b/demos/ra_tls/ra_config_template.json @@ -1,8 +1,8 @@ { - "verify_mr_enclave" : "off", - "verify_mr_signer" : "off", - "verify_isv_prod_id" : "off", - "verify_isv_svn" : "off", + "verify_mr_enclave" : "on", + "verify_mr_signer" : "on", + "verify_isv_prod_id" : "on", + "verify_isv_svn" : "on", "sgx_mrs": [ { "mr_enclave" : "", diff --git a/demos/ra_tls/run.sh b/demos/ra_tls/run.sh index 68c5cf72..5f370019 100755 --- a/demos/ra_tls/run.sh +++ b/demos/ra_tls/run.sh @@ -1,7 +1,9 @@ #!/bin/bash -set -ex +set -e postfix=$1 +request=$2 +file=${3:-/host/secret} if [ "$postfix" != "server" ] && [ "$postfix" != "client" ]; then echo "input error args, it should be:" @@ -10,6 +12,6 @@ if [ "$postfix" != "server" ] && [ "$postfix" != "client" ]; then exit 1 fi -pushd occlum_instance_$postfix -occlum run /bin/$postfix +pushd occlum_$postfix +occlum run /bin/$postfix ${request} ${file} popd diff --git a/demos/ra_tls/secret_config.json b/demos/ra_tls/secret_config.json new file mode 100644 index 00000000..333da552 --- /dev/null +++ b/demos/ra_tls/secret_config.json @@ -0,0 +1,4 @@ +{ + "cert" : "dGVzdCBzYW1wbGUgY2VydGlmaWNhdGVzCg==", + "key" : "dGVzdCBzYW1wbGUga2V5Cg==" +}