1 /* Copyright (c) 2015, Google Inc. 2 * 3 * Permission to use, copy, modify, and/or distribute this software for any 4 * purpose with or without fee is hereby granted, provided that the above 5 * copyright notice and this permission notice appear in all copies. 6 * 7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14 15 #ifndef OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H 16 #define OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H 17 18 #include <stdint.h> 19 #include <stdio.h> 20 21 #include <memory> 22 23 #include <openssl/aead.h> 24 #include <openssl/bio.h> 25 #include <openssl/bn.h> 26 #include <openssl/cmac.h> 27 #include <openssl/dh.h> 28 #include <openssl/ec.h> 29 #include <openssl/ec_key.h> 30 #include <openssl/ecdsa.h> 31 #include <openssl/evp.h> 32 #include <openssl/hmac.h> 33 #include <openssl/mem.h> 34 #include <openssl/pkcs8.h> 35 #include <openssl/rsa.h> 36 #include <openssl/stack.h> 37 #include <openssl/x509.h> 38 39 40 template<typename T, void (*func)(T*)> 41 struct OpenSSLDeleter { operatorOpenSSLDeleter42 void operator()(T *obj) { 43 func(obj); 44 } 45 }; 46 47 template<typename StackType, typename T, void (*func)(T*)> 48 struct OpenSSLStackDeleter { operatorOpenSSLStackDeleter49 void operator()(StackType *obj) { 50 sk_pop_free(reinterpret_cast<_STACK*>(obj), 51 reinterpret_cast<void (*)(void *)>(func)); 52 } 53 }; 54 55 template<typename T> 56 struct OpenSSLFree { operatorOpenSSLFree57 void operator()(T *buf) { 58 OPENSSL_free(buf); 59 } 60 }; 61 62 struct FileCloser { operatorFileCloser63 void operator()(FILE *file) { 64 fclose(file); 65 } 66 }; 67 68 template<typename T, void (*func)(T*)> 69 using ScopedOpenSSLType = std::unique_ptr<T, OpenSSLDeleter<T, func>>; 70 71 template<typename StackType, typename T, void (*func)(T*)> 72 using ScopedOpenSSLStack = 73 std::unique_ptr<StackType, OpenSSLStackDeleter<StackType, T, func>>; 74 75 template<typename T, typename CleanupRet, void (*init_func)(T*), 76 CleanupRet (*cleanup_func)(T*)> 77 class ScopedOpenSSLContext { 78 public: ScopedOpenSSLContext()79 ScopedOpenSSLContext() { 80 init_func(&ctx_); 81 } ~ScopedOpenSSLContext()82 ~ScopedOpenSSLContext() { 83 cleanup_func(&ctx_); 84 } 85 get()86 T *get() { return &ctx_; } get()87 const T *get() const { return &ctx_; } 88 Reset()89 void Reset() { 90 cleanup_func(&ctx_); 91 init_func(&ctx_); 92 } 93 94 private: 95 T ctx_; 96 }; 97 98 using ScopedBIO = ScopedOpenSSLType<BIO, BIO_vfree>; 99 using ScopedBIGNUM = ScopedOpenSSLType<BIGNUM, BN_free>; 100 using ScopedBN_CTX = ScopedOpenSSLType<BN_CTX, BN_CTX_free>; 101 using ScopedBN_MONT_CTX = ScopedOpenSSLType<BN_MONT_CTX, BN_MONT_CTX_free>; 102 using ScopedCMAC_CTX = ScopedOpenSSLType<CMAC_CTX, CMAC_CTX_free>; 103 using ScopedDH = ScopedOpenSSLType<DH, DH_free>; 104 using ScopedECDSA_SIG = ScopedOpenSSLType<ECDSA_SIG, ECDSA_SIG_free>; 105 using ScopedEC_GROUP = ScopedOpenSSLType<EC_GROUP, EC_GROUP_free>; 106 using ScopedEC_KEY = ScopedOpenSSLType<EC_KEY, EC_KEY_free>; 107 using ScopedEC_POINT = ScopedOpenSSLType<EC_POINT, EC_POINT_free>; 108 using ScopedEVP_PKEY = ScopedOpenSSLType<EVP_PKEY, EVP_PKEY_free>; 109 using ScopedEVP_PKEY_CTX = ScopedOpenSSLType<EVP_PKEY_CTX, EVP_PKEY_CTX_free>; 110 using ScopedPKCS8_PRIV_KEY_INFO = ScopedOpenSSLType<PKCS8_PRIV_KEY_INFO, 111 PKCS8_PRIV_KEY_INFO_free>; 112 using ScopedPKCS12 = ScopedOpenSSLType<PKCS12, PKCS12_free>; 113 using ScopedRSA = ScopedOpenSSLType<RSA, RSA_free>; 114 using ScopedX509 = ScopedOpenSSLType<X509, X509_free>; 115 using ScopedX509_ALGOR = ScopedOpenSSLType<X509_ALGOR, X509_ALGOR_free>; 116 using ScopedX509_SIG = ScopedOpenSSLType<X509_SIG, X509_SIG_free>; 117 118 using ScopedX509Stack = ScopedOpenSSLStack<STACK_OF(X509), X509, X509_free>; 119 120 using ScopedCBB = ScopedOpenSSLContext<CBB, void, CBB_zero, CBB_cleanup>; 121 using ScopedEVP_AEAD_CTX = ScopedOpenSSLContext<EVP_AEAD_CTX, void, 122 EVP_AEAD_CTX_zero, 123 EVP_AEAD_CTX_cleanup>; 124 using ScopedEVP_CIPHER_CTX = ScopedOpenSSLContext<EVP_CIPHER_CTX, int, 125 EVP_CIPHER_CTX_init, 126 EVP_CIPHER_CTX_cleanup>; 127 using ScopedEVP_MD_CTX = ScopedOpenSSLContext<EVP_MD_CTX, int, EVP_MD_CTX_init, 128 EVP_MD_CTX_cleanup>; 129 using ScopedHMAC_CTX = ScopedOpenSSLContext<HMAC_CTX, void, HMAC_CTX_init, 130 HMAC_CTX_cleanup>; 131 132 using ScopedOpenSSLBytes = std::unique_ptr<uint8_t, OpenSSLFree<uint8_t>>; 133 using ScopedOpenSSLString = std::unique_ptr<char, OpenSSLFree<char>>; 134 135 using ScopedFILE = std::unique_ptr<FILE, FileCloser>; 136 137 #endif // OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H 138