summaryrefslogtreecommitdiff
path: root/hiredict_ssl.h
blob: 73aa3c3c15995117a15d5ee329fe84ac54706c34 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 * Copyright (c) 2019, Redict Labs
 *
 * SPDX-FileCopyrightText: 2024 Hiredict Contributors
 * SPDX-FileCopyrightText: 2024 Redict Labs
 *
 * SPDX-License-Identifier: BSD-3-Clause
 * SPDX-License-Identifier: LGPL-3.0-or-later
 *
 */

#ifndef __HIREDICT_SSL_H
#define __HIREDICT_SSL_H

#ifdef __cplusplus
extern "C" {
#endif

/* This is the underlying struct for SSL in ssl.h, which is not included to
 * keep build dependencies short here.
 */
struct ssl_st;

/* A wrapper around OpenSSL SSL_CTX to allow easy SSL use without directly
 * calling OpenSSL.
 */
typedef struct redictSSLContext redictSSLContext;

/**
 * Initialization errors that redictCreateSSLContext() may return.
 */

typedef enum {
    REDICT_SSL_CTX_NONE = 0,                     /* No Error */
    REDICT_SSL_CTX_CREATE_FAILED,                /* Failed to create OpenSSL SSL_CTX */
    REDICT_SSL_CTX_CERT_KEY_REQUIRED,            /* Client cert and key must both be specified or skipped */
    REDICT_SSL_CTX_CA_CERT_LOAD_FAILED,          /* Failed to load CA Certificate or CA Path */
    REDICT_SSL_CTX_CLIENT_CERT_LOAD_FAILED,      /* Failed to load client certificate */
    REDICT_SSL_CTX_CLIENT_DEFAULT_CERT_FAILED,   /* Failed to set client default certificate directory */
    REDICT_SSL_CTX_PRIVATE_KEY_LOAD_FAILED,      /* Failed to load private key */
    REDICT_SSL_CTX_OS_CERTSTORE_OPEN_FAILED,     /* Failed to open system certificate store */
    REDICT_SSL_CTX_OS_CERT_ADD_FAILED            /* Failed to add CA certificates obtained from system to the SSL context */
} redictSSLContextError;

/* Constants that mirror OpenSSL's verify modes. By default,
 * REDICT_SSL_VERIFY_PEER is used with redictCreateSSLContext().
 * Some Redict clients disable peer verification if there are no
 * certificates specified.
 */
#define REDICT_SSL_VERIFY_NONE 0x00
#define REDICT_SSL_VERIFY_PEER 0x01
#define REDICT_SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
#define REDICT_SSL_VERIFY_CLIENT_ONCE 0x04
#define REDICT_SSL_VERIFY_POST_HANDSHAKE 0x08

/* Options to create an OpenSSL context. */
typedef struct {
    const char *cacert_filename;
    const char *capath;
    const char *cert_filename;
    const char *private_key_filename;
    const char *server_name;
    int verify_mode;
} redictSSLOptions;

/**
 * Return the error message corresponding with the specified error code.
 */

const char *redictSSLContextGetError(redictSSLContextError error);

/**
 * Helper function to initialize the OpenSSL library.
 *
 * OpenSSL requires one-time initialization before it can be used. Callers should
 * call this function only once, and only if OpenSSL is not directly initialized
 * elsewhere.
 */
int redictInitOpenSSL(void);

/**
 * Helper function to initialize an OpenSSL context that can be used
 * to initiate SSL connections.
 *
 * cacert_filename is an optional name of a CA certificate/bundle file to load
 * and use for validation.
 *
 * capath is an optional directory path where trusted CA certificate files are
 * stored in an OpenSSL-compatible structure.
 *
 * cert_filename and private_key_filename are optional names of a client side
 * certificate and private key files to use for authentication. They need to
 * be both specified or omitted.
 *
 * server_name is an optional and will be used as a server name indication
 * (SNI) TLS extension.
 *
 * If error is non-null, it will be populated in case the context creation fails
 * (returning a NULL).
 */

redictSSLContext *redictCreateSSLContext(const char *cacert_filename, const char *capath,
        const char *cert_filename, const char *private_key_filename,
        const char *server_name, redictSSLContextError *error);

/**
  * Helper function to initialize an OpenSSL context that can be used
  * to initiate SSL connections. This is a more extensible version of redictCreateSSLContext().
  *
  * options contains a structure of SSL options to use.
  *
  * If error is non-null, it will be populated in case the context creation fails
  * (returning a NULL).
*/
redictSSLContext *redictCreateSSLContextWithOptions(redictSSLOptions *options,
        redictSSLContextError *error);

/**
 * Free a previously created OpenSSL context.
 */
void redictFreeSSLContext(redictSSLContext *redict_ssl_ctx);

/**
 * Initiate SSL on an existing redictContext.
 *
 * This is similar to redictInitiateSSL() but does not require the caller
 * to directly interact with OpenSSL, and instead uses a redictSSLContext
 * previously created using redictCreateSSLContext().
 */

int redictInitiateSSLWithContext(redictContext *c, redictSSLContext *redict_ssl_ctx);

/**
 * Initiate SSL/TLS negotiation on a provided OpenSSL SSL object.
 */

int redictInitiateSSL(redictContext *c, struct ssl_st *ssl);

#ifdef __cplusplus
}
#endif

#endif  /* __HIREDICT_SSL_H */