• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /**
3  * Copyright 2021 Huawei Technologies Co., Ltd
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include "ps/core/communicator/ssl_http.h"
19 
20 #include <sys/time.h>
21 #include <openssl/pem.h>
22 #include <openssl/sha.h>
23 
24 #include <cstdio>
25 #include <cstring>
26 #include <cstdlib>
27 #include <vector>
28 #include <iomanip>
29 #include <sstream>
30 
31 namespace mindspore {
32 namespace ps {
33 namespace core {
SSLHTTP()34 SSLHTTP::SSLHTTP() : ssl_ctx_(nullptr) { InitSSL(); }
35 
~SSLHTTP()36 SSLHTTP::~SSLHTTP() { CleanSSL(); }
37 
InitSSL()38 void SSLHTTP::InitSSL() {
39   if (!SSL_library_init()) {
40     MS_LOG(EXCEPTION) << "SSL_library_init failed.";
41   }
42   if (!ERR_load_crypto_strings()) {
43     MS_LOG(EXCEPTION) << "ERR_load_crypto_strings failed.";
44   }
45   if (!SSL_load_error_strings()) {
46     MS_LOG(EXCEPTION) << "SSL_load_error_strings failed.";
47   }
48   if (!OpenSSL_add_all_algorithms()) {
49     MS_LOG(EXCEPTION) << "OpenSSL_add_all_algorithms failed.";
50   }
51   ssl_ctx_ = SSL_CTX_new(SSLv23_server_method());
52   if (!ssl_ctx_) {
53     MS_LOG(EXCEPTION) << "SSL_CTX_new failed";
54   }
55   X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx_);
56   MS_EXCEPTION_IF_NULL(store);
57   if (X509_STORE_set_default_paths(store) != 1) {
58     MS_LOG(EXCEPTION) << "X509_STORE_set_default_paths failed";
59   }
60 
61   std::unique_ptr<Configuration> config_ =
62     std::make_unique<FileConfiguration>(PSContext::instance()->config_file_path());
63   MS_EXCEPTION_IF_NULL(config_);
64   if (!config_->Initialize()) {
65     MS_LOG(EXCEPTION) << "The config file is empty.";
66   }
67 
68   // 1.Parse the server's certificate and the ciphertext of key.
69   std::string server_cert = kCertificateChain;
70   std::string path = CommUtil::ParseConfig(*(config_), kServerCertPath);
71   if (!CommUtil::IsFileExists(path)) {
72     MS_LOG(EXCEPTION) << "The key:" << kServerCertPath << "'s value is not exist.";
73   }
74   server_cert = path;
75 
76   // 2. Parse the server password.
77   EVP_PKEY *pkey = nullptr;
78   X509 *cert = nullptr;
79   STACK_OF(X509) *ca_stack = nullptr;
80   BIO *bio = BIO_new_file(server_cert.c_str(), "rb");
81   if (bio == nullptr) {
82     MS_LOG(EXCEPTION) << "Read server cert file failed.";
83   }
84   PKCS12 *p12 = d2i_PKCS12_bio(bio, nullptr);
85   if (p12 == nullptr) {
86     MS_LOG(EXCEPTION) << "Create PKCS12 cert failed, please check whether the certificate is correct.";
87   }
88   BIO_free_all(bio);
89   if (!PKCS12_parse(p12, PSContext::instance()->server_password(), &pkey, &cert, &ca_stack)) {
90     MS_LOG(EXCEPTION) << "PKCS12_parse failed.";
91   }
92   PKCS12_free(p12);
93   if (cert == nullptr) {
94     MS_LOG(EXCEPTION) << "the cert is nullptr";
95   }
96   if (pkey == nullptr) {
97     MS_LOG(EXCEPTION) << "the key is nullptr";
98   }
99   if (!CommUtil::verifyCertTimeStamp(cert)) {
100     MS_LOG(EXCEPTION) << "Verify Cert Time failed.";
101   }
102   std::string default_cipher_list = CommUtil::ParseConfig(*config_, kCipherList);
103   InitSSLCtx(cert, pkey, default_cipher_list);
104   EVP_PKEY_free(pkey);
105   X509_free(cert);
106 }
107 
InitSSLCtx(const X509 * cert,const EVP_PKEY * pkey,const std::string & default_cipher_list)108 void SSLHTTP::InitSSLCtx(const X509 *cert, const EVP_PKEY *pkey, const std::string &default_cipher_list) {
109   if (!SSL_CTX_set_cipher_list(ssl_ctx_, default_cipher_list.c_str())) {
110     MS_LOG(EXCEPTION) << "SSL use set cipher list failed!";
111   }
112   if (!SSL_CTX_use_certificate(ssl_ctx_, const_cast<X509 *>(cert))) {
113     MS_LOG(EXCEPTION) << "SSL use certificate chain file failed!";
114   }
115   if (!SSL_CTX_use_PrivateKey(ssl_ctx_, const_cast<EVP_PKEY *>(pkey))) {
116     MS_LOG(EXCEPTION) << "SSL use private key file failed!";
117   }
118   if (!SSL_CTX_check_private_key(ssl_ctx_)) {
119     MS_LOG(EXCEPTION) << "SSL check private key file failed!";
120   }
121   if (!SSL_CTX_set_options(ssl_ctx_, SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
122                                        SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1)) {
123     MS_LOG(EXCEPTION) << "SSL_CTX_set_options failed.";
124   }
125   SSL_CTX_set_security_level(ssl_ctx_, kSecurityLevel);
126 }
127 
CleanSSL()128 void SSLHTTP::CleanSSL() {
129   if (ssl_ctx_ != nullptr) {
130     SSL_CTX_free(ssl_ctx_);
131   }
132   ERR_free_strings();
133   EVP_cleanup();
134   ERR_remove_thread_state(nullptr);
135   CRYPTO_cleanup_all_ex_data();
136 }
137 
GetSSLCtx() const138 SSL_CTX *SSLHTTP::GetSSLCtx() const { return ssl_ctx_; }
139 }  // namespace core
140 }  // namespace ps
141 }  // namespace mindspore
142