1 /* 2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 17 #include <cstring> 18 #include "gtest/gtest.h" 19 20 #ifdef GTEST_API_ 21 #define private public 22 #endif 23 24 #include "http_exec.h" 25 #include "http_async_work.h" 26 #include "netstack_log.h" 27 #include "constant.h" 28 #include "secure_char.h" 29 #include "curl/curl.h" 30 #ifdef HTTP_MULTIPATH_CERT_ENABLE 31 #include <openssl/ssl.h> 32 #include <openssl/pem.h> 33 #include <openssl/sha.h> 34 #include <openssl/x509.h> 35 36 struct SslCtxDeleter { operator ()SslCtxDeleter37 void operator()(SSL_CTX* p) const { SSL_CTX_free(p); } 38 }; 39 struct X509SroreCtxDeleter { operator ()X509SroreCtxDeleter40 void operator()(X509_STORE_CTX* p) const { X509_STORE_CTX_cleanup(p); } 41 }; 42 struct BioDeleter { operator ()BioDeleter43 void operator()(BIO* p) const { BIO_free(p); } 44 }; 45 struct X509Deleter { operator ()X509Deleter46 void operator()(X509* p) const { X509_free(p); } 47 }; 48 49 using unique_SSL_CTX = std::unique_ptr<SSL_CTX, SslCtxDeleter>; 50 using unique_X509_STORE_CTX = std::unique_ptr<X509_STORE_CTX, X509SroreCtxDeleter>; 51 using unique_BIO = std::unique_ptr<BIO, BioDeleter>; 52 using unique_X509 = std::unique_ptr<X509, X509Deleter>; 53 #endif 54 55 using namespace OHOS::NetStack; 56 using namespace OHOS::NetStack::Http; 57 58 struct CurlDeleter { operator ()CurlDeleter59 void operator()(CURL* p) const { curl_easy_cleanup(p); } 60 }; 61 using unique_CURL = std::unique_ptr<CURL, CurlDeleter>; 62 63 class HttpExecTest : public testing::Test { 64 public: SetUpTestCase()65 static void SetUpTestCase() {} 66 TearDownTestCase()67 static void TearDownTestCase() {} 68 SetUp()69 virtual void SetUp() {} 70 TearDown()71 virtual void TearDown() {} 72 }; 73 74 namespace { 75 using namespace std; 76 using namespace testing::ext; 77 78 79 HWTEST_F(HttpExecTest, SetOption001, TestSize.Level1) 80 { 81 unique_CURL handle(curl_easy_init()); 82 83 napi_env env = nullptr; 84 auto manager = std::make_shared<EventManager>(); 85 OHOS::NetStack::Http::RequestContext context(env, manager); 86 87 EXPECT_TRUE(HttpExec::SetOption(handle.get(), &context, context.GetCurlHeaderList())); 88 } 89 90 HWTEST_F(HttpExecTest, SetServerSSLCertOption001, TestSize.Level1) 91 { 92 unique_CURL handle(curl_easy_init()); 93 94 napi_env env = nullptr; 95 auto manager = std::make_shared<EventManager>(); 96 OHOS::NetStack::Http::RequestContext context(env, manager); 97 98 EXPECT_TRUE(HttpExec::SetServerSSLCertOption(handle.get(), &context)); 99 } 100 101 #ifdef HTTP_MULTIPATH_CERT_ENABLE 102 HWTEST_F(HttpExecTest, MultiPathSslCtxFunction001, TestSize.Level1) 103 { 104 std::string dummy_root_ca_pem = "-----BEGIN CERTIFICATE-----\n" 105 "MIIC/jCCAeagAwIBAgIJPscmmRP6WujNMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV\n" 106 "BAMTEE9wZW5IYXJtb255IFRlc3QwHhcNMjUwNzEzMTcyMTM4WhcNMzEwMTAzMTcy\n" 107 "MTM4WjAbMRkwFwYDVQQDExBPcGVuSGFybW9ueSBUZXN0MIIBIjANBgkqhkiG9w0B\n" 108 "AQEFAAOCAQ8AMIIBCgKCAQEA1WD9TT08Sx3jJprsLToBOxm0cXEL1p/Lbo+D9L5P\n" 109 "xb5eDAsbzbShhjhMu0dUshwDZzFOPIIKldB7qy1oqXVIH6r/qht549nH+/ouriWW\n" 110 "meWdGKOAkzB5szwRWTSA/okM+afCUN5fV1H5B498jGXBhtNOJbm1+hMJs0siHCPC\n" 111 "A5Hc9mf8J33LJA7ZvsGR4/K6+mFE9fjzvxw0bN97Qwjtl/DNpKNmUY5YTy/qbkfx\n" 112 "1ZXkE3ztgjQnQvyQvvT4TRu3oSJd4jVtmpsiJZuObcCzv/Z9gcM0FWXAUuvX8TCS\n" 113 "io4eMIrSP0I/0J4C5a0zcWZJGzsJ+RkVRxEHcozNOMlyjQIDAQABo0UwQzAMBgNV\n" 114 "HRMEBTADAQH/MAsGA1UdDwQEAwIC9DAmBgNVHREEHzAdhhtodHRwOi8vZXhhbXBs\n" 115 "ZS5vcmcvd2ViaWQjbWUwDQYJKoZIhvcNAQELBQADggEBAGHRWidqgRFopjieMfuc\n" 116 "4Re/vqk25+CDy8LmuH/Ha9zHGd2Wxif5PGpEgjcP4zfk8XRGVGvRR++Uu3FInNga\n" 117 "a+k1ClbgiDf+E0uh64kTYzTjd0UMJ7Pbn1FKXjpvZaJZOIKTeR7O9UhdNeqE4g7Q\n" 118 "tTkF39n9pOGDfyA4kOErfcWA21zRd0qTEe5qnrJ0+HiMY7V5LYjIJ9tJyRTpfCzr\n" 119 "7yzDZzDwSwdpM/i+B2jbjqbQIJHdcajdzxdq9VzLla1yNtA/AOxtmTmY2q8Uj3mw\n" 120 "zD2cfeLdHoEhKHnSP76QdUnUMMn8eaPPMqWa+7XhxfXCCJjiE8STLzOkBAcvR9E2\n" 121 "QVo=\n" 122 "-----END CERTIFICATE-----\n"; 123 unique_CURL handle(curl_easy_init()); 124 unique_SSL_CTX ctx(SSL_CTX_new(TLS_client_method())); 125 napi_env env = nullptr; 126 std::shared_ptr<EventManager> eventManager = std::make_shared<EventManager>(); 127 RequestContext context(env, eventManager); 128 context.options.SetCaData(dummy_root_ca_pem); 129 CURLcode ret = HttpExec::MultiPathSslCtxFunction(handle.get(), ctx.get(), &context); 130 ASSERT_EQ(ret, CURLE_OK); 131 132 unique_BIO bio(BIO_new_mem_buf(dummy_root_ca_pem.data(), dummy_root_ca_pem.size())); 133 ASSERT_NE(bio, nullptr); 134 135 unique_X509 cert(PEM_read_bio_X509(bio.get(), NULL, NULL, NULL)); 136 ASSERT_NE(cert, nullptr); 137 138 // 配置 X509_STORE_CTX,执行验证 139 X509_STORE *store = SSL_CTX_get_cert_store(ctx.get()); 140 unique_X509_STORE_CTX storeCtx(X509_STORE_CTX_new()); 141 X509_STORE_CTX_init(storeCtx.get(), store, cert.get(), nullptr); 142 143 // 默认允许自签名证书验证 144 int verify_result = X509_verify_cert(storeCtx.get()); 145 146 EXPECT_EQ(verify_result, 1); 147 } 148 #endif 149 } // namespace