/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * 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. */ #pragma once #include #include #include namespace folly { namespace ssl { // helper which translates: // FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(Foo, FOO, FOO_free); // into // using FooDeleter = folly::static_function_deleter; // using FooUniquePtr = std::unique_ptr; #define FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(alias, object, deleter) \ using alias##Deleter = folly::static_function_deleter; \ using alias##UniquePtr = std::unique_ptr // ASN1 FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(ASN1Time, ASN1_TIME, ASN1_TIME_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( ASN1Ia5Str, ASN1_IA5STRING, ASN1_IA5STRING_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(ASN1Int, ASN1_INTEGER, ASN1_INTEGER_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(ASN1Obj, ASN1_OBJECT, ASN1_OBJECT_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(ASN1Str, ASN1_STRING, ASN1_STRING_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(ASN1Type, ASN1_TYPE, ASN1_TYPE_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( ASN1UTF8Str, ASN1_UTF8STRING, ASN1_UTF8STRING_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( ASN1BitStr, ASN1_BIT_STRING, ASN1_BIT_STRING_free); // X509 FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(X509, X509, X509_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( X509Extension, X509_EXTENSION, X509_EXTENSION_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(X509Store, X509_STORE, X509_STORE_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( X509StoreCtx, X509_STORE_CTX, X509_STORE_CTX_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(X509Sig, X509_SIG, X509_SIG_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(X509Algor, X509_ALGOR, X509_ALGOR_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(X509Pubkey, X509_PUBKEY, X509_PUBKEY_free); using X509VerifyParamDeleter = folly::static_function_deleter; using X509VerifyParam = std::unique_ptr; FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(GeneralName, GENERAL_NAME, GENERAL_NAME_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( GeneralNames, GENERAL_NAMES, GENERAL_NAMES_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( AccessDescription, ACCESS_DESCRIPTION, ACCESS_DESCRIPTION_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( AuthorityInfoAccess, AUTHORITY_INFO_ACCESS, AUTHORITY_INFO_ACCESS_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( DistPointName, DIST_POINT_NAME, DIST_POINT_NAME_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(DistPoint, DIST_POINT, DIST_POINT_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( CrlDistPoints, CRL_DIST_POINTS, CRL_DIST_POINTS_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(X509Crl, X509_CRL, X509_CRL_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(X509Name, X509_NAME, X509_NAME_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(X509Req, X509_REQ, X509_REQ_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(X509Revoked, X509_REVOKED, X509_REVOKED_free); // EVP FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(EvpPkey, EVP_PKEY, EVP_PKEY_free); using EvpPkeySharedPtr = std::shared_ptr; FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( EvpEncodeCtx, EVP_ENCODE_CTX, EVP_ENCODE_CTX_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(EvpPkeyCtx, EVP_PKEY_CTX, EVP_PKEY_CTX_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(EvpMdCtx, EVP_MD_CTX, EVP_MD_CTX_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( EvpCipherCtx, EVP_CIPHER_CTX, EVP_CIPHER_CTX_free); // HMAC FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(HmacCtx, HMAC_CTX, HMAC_CTX_free); // BIO FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(BioMethod, BIO_METHOD, BIO_meth_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(Bio, BIO, BIO_vfree); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(BioChain, BIO, BIO_free_all); inline void BIO_free_fb(BIO* bio) { CHECK_EQ(1, BIO_free(bio)); } using BioDeleterFb = folly::static_function_deleter; using BioUniquePtrFb = std::unique_ptr; // RSA and EC FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(Rsa, RSA, RSA_free); #ifndef OPENSSL_NO_EC FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(EcKey, EC_KEY, EC_KEY_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(EcGroup, EC_GROUP, EC_GROUP_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(EcPoint, EC_POINT, EC_POINT_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(EcdsaSig, ECDSA_SIG, ECDSA_SIG_free); #endif // DSA #ifndef OPENSSL_NO_DSA FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(Dsa, DSA, DSA_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(DsaSig, DSA_SIG, DSA_SIG_free); #endif // BIGNUMs FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(BIGNUM, BIGNUM, BN_clear_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(BNCtx, BN_CTX, BN_CTX_free); // SSL and SSL_CTX FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(SSL, SSL, SSL_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(SSLSession, SSL_SESSION, SSL_SESSION_free); // OCSP #ifndef OPENSSL_NO_OCSP FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(OcspRequest, OCSP_REQUEST, OCSP_REQUEST_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( OcspResponse, OCSP_RESPONSE, OCSP_RESPONSE_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE( OcspBasicResponse, OCSP_BASICRESP, OCSP_BASICRESP_free); FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(OcspCertId, OCSP_CERTID, OCSP_CERTID_free); #endif // PKCS7 FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE(Pkcs7, PKCS7, PKCS7_free); // OpenSSL STACK_OF(T) can both represent owned or borrowed values. // // This isn't represented in the OpenSSL "safestack" type (e.g. STACK_OF(Foo)). // Whether or not a STACK is owning or borrowing is determined purely based on // which destructor is called. // * sk_T_free - This only deallocates the STACK, but does not free the // contained items within. This is the "borrowing" version. // * sk_T_pop_free - This deallocates both the STACK and it invokes a free // function for each element. This is the "owning" version. // // The below macro, // FOLLY_SSL_DETAIL_DEFINE_STACK_PTR_TYPE(Alias, Element) // // can be used to define two unique_ptr types that correspond to the "owned" // or "borrowing" version of each. // // For example, // FOLLY_SSL_DETAIL_DEFINE_STACK_PTR_TYPE(X509Name, X509_NAME) // creates two unique ptr type aliases // * OwningStackOfX509NameUniquePtr // * BorrowingStackOfX509NameUniquePtr // which corresponds to a unique_ptr of `STACK_OF(X509_NAME)` that will invoke // the appropriate destructor: // * OwningStackOf* -> Invokes sk_T_pop_free // * BorrowingStackOf* -> Invokes sk_T_free namespace detail { template < class StackType, class ElementType, void (*ElementDestructor)(ElementType*)> struct OpenSSLOwnedStackDeleter { void operator()(StackType* stack) const { OPENSSL_sk_pop_free( reinterpret_cast(stack), reinterpret_cast(ElementDestructor)); } }; template struct OpenSSLBorrowedStackDestructor { void operator()(StackType* stack) { OPENSSL_sk_free(reinterpret_cast(stack)); } }; } // namespace detail #define FOLLY_SSL_DETAIL_OWNING_STACK_DESTRUCTOR(T) \ ::folly::ssl::detail::OpenSSLOwnedStackDeleter #define FOLLY_SSL_DETAIL_BORROWING_STACK_DESTRUCTOR(T) \ ::folly::ssl::detail::OpenSSLBorrowedStackDestructor #define FOLLY_SSL_DETAIL_DEFINE_OWNING_STACK_PTR_TYPE( \ element_alias, element_type) \ using OwningStackOf##element_alias##UniquePtr = std::unique_ptr< \ STACK_OF(element_type), \ FOLLY_SSL_DETAIL_OWNING_STACK_DESTRUCTOR(element_type)> #define FOLLY_SSL_DETAIL_DEFINE_BORROWING_STACK_PTR_TYPE( \ element_alias, element_type) \ using BorrowingStackOf##element_alias##UniquePtr = std::unique_ptr< \ STACK_OF(element_type), \ FOLLY_SSL_DETAIL_BORROWING_STACK_DESTRUCTOR(element_type)> #define FOLLY_SSL_DETAIL_DEFINE_STACK_PTR_TYPE(element_alias, element_type) \ FOLLY_SSL_DETAIL_DEFINE_BORROWING_STACK_PTR_TYPE( \ element_alias, element_type); \ FOLLY_SSL_DETAIL_DEFINE_OWNING_STACK_PTR_TYPE(element_alias, element_type) FOLLY_SSL_DETAIL_DEFINE_STACK_PTR_TYPE(X509Name, X509_NAME); FOLLY_SSL_DETAIL_DEFINE_STACK_PTR_TYPE(X509, X509); FOLLY_SSL_DETAIL_DEFINE_STACK_PTR_TYPE(X509Extension, X509_EXTENSION); FOLLY_SSL_DETAIL_DEFINE_STACK_PTR_TYPE(ASN1Obj, ASN1_OBJECT); #undef FOLLY_SSL_DETAIL_BORROWING_STACK_DESTRUCTOR #undef FOLLY_SSL_DETAIL_OWNING_STACK_DESTRUCTOR #undef FOLLY_SSL_DETAIL_DEFINE_OWNING_STACK_PTR_TYPE #undef FOLLY_SSL_DETAIL_DEFINE_BORROWING_STACK_PTR_TYPE #undef FOLLY_SSL_DETAIL_DEFINE_STACK_PTR_TYPE #undef FOLLY_SSL_DETAIL_DEFINE_PTR_TYPE } // namespace ssl } // namespace folly