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
36extern "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 */
42struct ssl_st;
43
44/* A wrapper around OpenSSL SSL_CTX to allow easy SSL use without directly
45 * calling OpenSSL.
46 */
47typedef struct redisSSLContext redisSSLContext;
48
49/**
50 * Initialization errors that redisCreateSSLContext() may return.
51 */
52
53typedef 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 REDIS_SSL_CTX_OS_CERTSTORE_OPEN_FAILED, /* Failed to open system certificate store */
61 REDIS_SSL_CTX_OS_CERT_ADD_FAILED /* Failed to add CA certificates obtained from system to the SSL context */
62} redisSSLContextError;
63
64/**
65 * Return the error message corresponding with the specified error code.
66 */
67
68const char *redisSSLContextGetError(redisSSLContextError error);
69
70/**
71 * Helper function to initialize the OpenSSL library.
72 *
73 * OpenSSL requires one-time initialization before it can be used. Callers should
74 * call this function only once, and only if OpenSSL is not directly initialized
75 * elsewhere.
76 */
77int redisInitOpenSSL(void);
78
79/**
80 * Helper function to initialize an OpenSSL context that can be used
81 * to initiate SSL connections.
82 *
83 * cacert_filename is an optional name of a CA certificate/bundle file to load
84 * and use for validation.
85 *
86 * capath is an optional directory path where trusted CA certificate files are
87 * stored in an OpenSSL-compatible structure.
88 *
89 * cert_filename and private_key_filename are optional names of a client side
90 * certificate and private key files to use for authentication. They need to
91 * be both specified or omitted.
92 *
93 * server_name is an optional and will be used as a server name indication
94 * (SNI) TLS extension.
95 *
96 * If error is non-null, it will be populated in case the context creation fails
97 * (returning a NULL).
98 */
99
100redisSSLContext *redisCreateSSLContext(const char *cacert_filename, const char *capath,
101 const char *cert_filename, const char *private_key_filename,
102 const char *server_name, redisSSLContextError *error);
103
104/**
105 * Free a previously created OpenSSL context.
106 */
107void redisFreeSSLContext(redisSSLContext *redis_ssl_ctx);
108
109/**
110 * Initiate SSL on an existing redisContext.
111 *
112 * This is similar to redisInitiateSSL() but does not require the caller
113 * to directly interact with OpenSSL, and instead uses a redisSSLContext
114 * previously created using redisCreateSSLContext().
115 */
116
117int redisInitiateSSLWithContext(redisContext *c, redisSSLContext *redis_ssl_ctx);
118
119/**
120 * Initiate SSL/TLS negotiation on a provided OpenSSL SSL object.
121 */
122
123int redisInitiateSSL(redisContext *c, struct ssl_st *ssl);
124
125#ifdef __cplusplus
126}
127#endif
128
129#endif /* __HIREDIS_SSL_H */
130