1 
2 /*
3  * Copyright (c) 2019, Redis Labs
4  *
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  *   * Redistributions of source code must retain the above copyright notice,
11  *     this list of conditions and the following disclaimer.
12  *   * Redistributions in binary form must reproduce the above copyright
13  *     notice, this list of conditions and the following disclaimer in the
14  *     documentation and/or other materials provided with the distribution.
15  *   * Neither the name of Redis nor the names of its contributors may be used
16  *     to endorse or promote products derived from this software without
17  *     specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #ifndef __HIREDIS_SSL_H
33 #define __HIREDIS_SSL_H
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 /* This is the underlying struct for SSL in ssl.h, which is not included to
40  * keep build dependencies short here.
41  */
42 struct ssl_st;
43 
44 /* A wrapper around OpenSSL SSL_CTX to allow easy SSL use without directly
45  * calling OpenSSL.
46  */
47 typedef struct redisSSLContext redisSSLContext;
48 
49 /**
50  * Initialization errors that redisCreateSSLContext() may return.
51  */
52 
53 typedef enum {
54     REDIS_SSL_CTX_NONE = 0,                     /* No Error */
55     REDIS_SSL_CTX_CREATE_FAILED,                /* Failed to create OpenSSL SSL_CTX */
56     REDIS_SSL_CTX_CERT_KEY_REQUIRED,            /* Client cert and key must both be specified or skipped */
57     REDIS_SSL_CTX_CA_CERT_LOAD_FAILED,          /* Failed to load CA Certificate or CA Path */
58     REDIS_SSL_CTX_CLIENT_CERT_LOAD_FAILED,      /* Failed to load client certificate */
59     REDIS_SSL_CTX_PRIVATE_KEY_LOAD_FAILED       /* Failed to load private key */
60 } redisSSLContextError;
61 
62 /**
63  * Return the error message corresponding with the specified error code.
64  */
65 
66 const char *redisSSLContextGetError(redisSSLContextError error);
67 
68 /**
69  * Helper function to initialize the OpenSSL library.
70  *
71  * OpenSSL requires one-time initialization before it can be used. Callers should
72  * call this function only once, and only if OpenSSL is not directly initialized
73  * elsewhere.
74  */
75 int redisInitOpenSSL(void);
76 
77 /**
78  * Helper function to initialize an OpenSSL context that can be used
79  * to initiate SSL connections.
80  *
81  * cacert_filename is an optional name of a CA certificate/bundle file to load
82  * and use for validation.
83  *
84  * capath is an optional directory path where trusted CA certificate files are
85  * stored in an OpenSSL-compatible structure.
86  *
87  * cert_filename and private_key_filename are optional names of a client side
88  * certificate and private key files to use for authentication. They need to
89  * be both specified or omitted.
90  *
91  * server_name is an optional and will be used as a server name indication
92  * (SNI) TLS extension.
93  *
94  * If error is non-null, it will be populated in case the context creation fails
95  * (returning a NULL).
96  */
97 
98 redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *capath,
99         const char *cert_filename, const char *private_key_filename,
100         const char *server_name, redisSSLContextError *error);
101 
102 /**
103  * Free a previously created OpenSSL context.
104  */
105 void redisFreeSSLContext(redisSSLContext *redis_ssl_ctx);
106 
107 /**
108  * Initiate SSL on an existing redisContext.
109  *
110  * This is similar to redisInitiateSSL() but does not require the caller
111  * to directly interact with OpenSSL, and instead uses a redisSSLContext
112  * previously created using redisCreateSSLContext().
113  */
114 
115 int redisInitiateSSLWithContext(redisContext *c, redisSSLContext *redis_ssl_ctx);
116 
117 /**
118  * Initiate SSL/TLS negotiation on a provided OpenSSL SSL object.
119  */
120 
121 int redisInitiateSSL(redisContext *c, struct ssl_st *ssl);
122 
123 #ifdef __cplusplus
124 }
125 #endif
126 
127 #endif  /* __HIREDIS_SSL_H */
128