2 * Copyright 2016 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <folly/ssl/detail/SSLSessionImpl.h>
18 #include <folly/ssl/detail/OpenSSLVersionFinder.h>
25 // Wrapper OpenSSL 1.0.2 (and possibly 1.0.1)
28 SSLSessionImpl::SSLSessionImpl(SSL_SESSION* session, bool takeOwnership)
30 if (session_ == nullptr) {
31 throw std::runtime_error("SSL_SESSION is null");
33 // If we're not given ownership, we need to up the refcount so the SSL_SESSION
34 // object won't be freed while SSLSessionImpl is alive
40 SSLSessionImpl::SSLSessionImpl(const std::string& serializedSession) {
42 reinterpret_cast<const unsigned char*>(serializedSession.data());
43 if ((session_ = d2i_SSL_SESSION(
44 nullptr, &sessionData, serializedSession.length())) == nullptr) {
45 throw std::runtime_error("Cannot deserialize SSLSession string");
49 SSLSessionImpl::~SSLSessionImpl() {
53 std::string SSLSessionImpl::serialize(void) const {
56 // Get the length first, then we know how much space to allocate.
57 auto len = i2d_SSL_SESSION(session_, nullptr);
60 std::unique_ptr<unsigned char[]> uptr(new unsigned char[len]);
62 auto written = i2d_SSL_SESSION(session_, &p);
64 VLOG(2) << "Could not serialize SSL_SESSION!";
66 ret.assign(uptr.get(), uptr.get() + written);
72 std::string SSLSessionImpl::getSessionID() const {
75 const unsigned char* ptr = nullptr;
77 #if defined(OPENSSL_IS_102) || defined(OPENSSL_IS_101)
78 len = session_->session_id_length;
79 ptr = session_->session_id;
80 #elif defined(OPENSSL_IS_110) || defined(OPENSSL_IS_BORINGSSL)
81 ptr = SSL_SESSION_get_id(session_, &len);
83 ret.assign(ptr, ptr + len);
88 const SSL_SESSION* SSLSessionImpl::getRawSSLSession() const {
89 return const_cast<SSL_SESSION*>(session_);
92 SSL_SESSION* SSLSessionImpl::getRawSSLSessionDangerous() {
97 void SSLSessionImpl::upRef() {
99 #if defined(OPENSSL_IS_102) || defined(OPENSSL_IS_101)
100 CRYPTO_add(&session_->references, 1, CRYPTO_LOCK_SSL_SESSION);
101 #elif defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_110)
102 SSL_SESSION_up_ref(session_);
107 void SSLSessionImpl::downRef() {
109 SSL_SESSION_free(session_);
113 } // namespace detail