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/asn1.h>
25 #include <openssl/bio.h>
26 #include <openssl/bn.h>
27 #include <openssl/bytestring.h>
28 #include <openssl/cmac.h>
29 #include <openssl/curve25519.h>
30 #include <openssl/dh.h>
31 #include <openssl/ecdsa.h>
32 #include <openssl/ec.h>
33 #include <openssl/ec_key.h>
34 #include <openssl/evp.h>
35 #include <openssl/hmac.h>
36 #include <openssl/mem.h>
37 #include <openssl/newhope.h>
38 #include <openssl/pkcs8.h>
39 #include <openssl/rsa.h>
40 #include <openssl/stack.h>
41 #include <openssl/x509.h>
42 
43 
44 template<typename T, void (*func)(T*)>
45 struct OpenSSLDeleter {
operatorOpenSSLDeleter46   void operator()(T *obj) {
47     func(obj);
48   }
49 };
50 
51 template<typename StackType, typename T, void (*func)(T*)>
52 struct OpenSSLStackDeleter {
operatorOpenSSLStackDeleter53   void operator()(StackType *obj) {
54     sk_pop_free(reinterpret_cast<_STACK*>(obj),
55                 reinterpret_cast<void (*)(void *)>(func));
56   }
57 };
58 
59 template<typename T>
60 struct OpenSSLFree {
operatorOpenSSLFree61   void operator()(T *buf) {
62     OPENSSL_free(buf);
63   }
64 };
65 
66 struct FileCloser {
operatorFileCloser67   void operator()(FILE *file) {
68     fclose(file);
69   }
70 };
71 
72 template<typename T, void (*func)(T*)>
73 using ScopedOpenSSLType = std::unique_ptr<T, OpenSSLDeleter<T, func>>;
74 
75 template<typename StackType, typename T, void (*func)(T*)>
76 using ScopedOpenSSLStack =
77     std::unique_ptr<StackType, OpenSSLStackDeleter<StackType, T, func>>;
78 
79 template<typename T, typename CleanupRet, void (*init_func)(T*),
80          CleanupRet (*cleanup_func)(T*)>
81 class ScopedOpenSSLContext {
82  public:
ScopedOpenSSLContext()83   ScopedOpenSSLContext() {
84     init_func(&ctx_);
85   }
~ScopedOpenSSLContext()86   ~ScopedOpenSSLContext() {
87     cleanup_func(&ctx_);
88   }
89 
get()90   T *get() { return &ctx_; }
get()91   const T *get() const { return &ctx_; }
92 
Reset()93   void Reset() {
94     cleanup_func(&ctx_);
95     init_func(&ctx_);
96   }
97 
98  private:
99   T ctx_;
100 };
101 
102 using ScopedASN1_TYPE = ScopedOpenSSLType<ASN1_TYPE, ASN1_TYPE_free>;
103 using ScopedBIO = ScopedOpenSSLType<BIO, BIO_vfree>;
104 using ScopedBIGNUM = ScopedOpenSSLType<BIGNUM, BN_free>;
105 using ScopedBN_CTX = ScopedOpenSSLType<BN_CTX, BN_CTX_free>;
106 using ScopedBN_MONT_CTX = ScopedOpenSSLType<BN_MONT_CTX, BN_MONT_CTX_free>;
107 using ScopedCMAC_CTX = ScopedOpenSSLType<CMAC_CTX, CMAC_CTX_free>;
108 using ScopedDH = ScopedOpenSSLType<DH, DH_free>;
109 using ScopedECDSA_SIG = ScopedOpenSSLType<ECDSA_SIG, ECDSA_SIG_free>;
110 using ScopedEC_GROUP = ScopedOpenSSLType<EC_GROUP, EC_GROUP_free>;
111 using ScopedEC_KEY = ScopedOpenSSLType<EC_KEY, EC_KEY_free>;
112 using ScopedEC_POINT = ScopedOpenSSLType<EC_POINT, EC_POINT_free>;
113 using ScopedEVP_PKEY = ScopedOpenSSLType<EVP_PKEY, EVP_PKEY_free>;
114 using ScopedEVP_PKEY_CTX = ScopedOpenSSLType<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
115 using ScopedNEWHOPE_POLY = ScopedOpenSSLType<NEWHOPE_POLY, NEWHOPE_POLY_free>;
116 using ScopedPKCS8_PRIV_KEY_INFO = ScopedOpenSSLType<PKCS8_PRIV_KEY_INFO,
117                                                     PKCS8_PRIV_KEY_INFO_free>;
118 using ScopedPKCS12 = ScopedOpenSSLType<PKCS12, PKCS12_free>;
119 using ScopedSPAKE2_CTX = ScopedOpenSSLType<SPAKE2_CTX, SPAKE2_CTX_free>;
120 using ScopedRSA = ScopedOpenSSLType<RSA, RSA_free>;
121 using ScopedX509 = ScopedOpenSSLType<X509, X509_free>;
122 using ScopedX509_ALGOR = ScopedOpenSSLType<X509_ALGOR, X509_ALGOR_free>;
123 using ScopedX509_SIG = ScopedOpenSSLType<X509_SIG, X509_SIG_free>;
124 using ScopedX509_STORE_CTX = ScopedOpenSSLType<X509_STORE_CTX, X509_STORE_CTX_free>;
125 
126 using ScopedX509Stack = ScopedOpenSSLStack<STACK_OF(X509), X509, X509_free>;
127 
128 using ScopedCBB = ScopedOpenSSLContext<CBB, void, CBB_zero, CBB_cleanup>;
129 using ScopedEVP_AEAD_CTX = ScopedOpenSSLContext<EVP_AEAD_CTX, void,
130                                                 EVP_AEAD_CTX_zero,
131                                                 EVP_AEAD_CTX_cleanup>;
132 using ScopedEVP_CIPHER_CTX = ScopedOpenSSLContext<EVP_CIPHER_CTX, int,
133                                                   EVP_CIPHER_CTX_init,
134                                                   EVP_CIPHER_CTX_cleanup>;
135 using ScopedEVP_MD_CTX = ScopedOpenSSLContext<EVP_MD_CTX, int, EVP_MD_CTX_init,
136                                               EVP_MD_CTX_cleanup>;
137 using ScopedHMAC_CTX = ScopedOpenSSLContext<HMAC_CTX, void, HMAC_CTX_init,
138                                             HMAC_CTX_cleanup>;
139 
140 using ScopedOpenSSLBytes = std::unique_ptr<uint8_t, OpenSSLFree<uint8_t>>;
141 using ScopedOpenSSLString = std::unique_ptr<char, OpenSSLFree<char>>;
142 
143 using ScopedFILE = std::unique_ptr<FILE, FileCloser>;
144 
145 #endif  // OPENSSL_HEADER_CRYPTO_TEST_SCOPED_TYPES_H
146