1 /*-------------------------------------------------------------------------
2 *
3 * protocol_openssl.c
4 * OpenSSL functionality shared between frontend and backend
5 *
6 * This should only be used if code is compiled with OpenSSL support.
7 *
8 * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
10 *
11 * IDENTIFICATION
12 * src/common/protocol_openssl.c
13 *
14 *-------------------------------------------------------------------------
15 */
16
17 #ifndef FRONTEND
18 #include "postgres.h"
19 #else
20 #include "postgres_fe.h"
21 #endif
22
23 #include "common/openssl.h"
24
25 /*
26 * Replacements for APIs introduced in OpenSSL 1.1.0.
27 */
28 #ifndef SSL_CTX_set_min_proto_version
29
30 /*
31 * OpenSSL versions that support TLS 1.3 shouldn't get here because they
32 * already have these functions. So we don't have to keep updating the below
33 * code for every new TLS version, and eventually it can go away. But let's
34 * just check this to make sure ...
35 */
36 #ifdef TLS1_3_VERSION
37 #error OpenSSL version mismatch
38 #endif
39
40 int
SSL_CTX_set_min_proto_version(SSL_CTX * ctx,int version)41 SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version)
42 {
43 int ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
44
45 if (version > TLS1_VERSION)
46 ssl_options |= SSL_OP_NO_TLSv1;
47
48 /*
49 * Some OpenSSL versions define TLS*_VERSION macros but not the
50 * corresponding SSL_OP_NO_* macro, so in those cases we have to return
51 * unsuccessfully here.
52 */
53 #ifdef TLS1_1_VERSION
54 if (version > TLS1_1_VERSION)
55 {
56 #ifdef SSL_OP_NO_TLSv1_1
57 ssl_options |= SSL_OP_NO_TLSv1_1;
58 #else
59 return 0;
60 #endif
61 }
62 #endif
63 #ifdef TLS1_2_VERSION
64 if (version > TLS1_2_VERSION)
65 {
66 #ifdef SSL_OP_NO_TLSv1_2
67 ssl_options |= SSL_OP_NO_TLSv1_2;
68 #else
69 return 0;
70 #endif
71 }
72 #endif
73
74 SSL_CTX_set_options(ctx, ssl_options);
75
76 return 1; /* success */
77 }
78
79 int
SSL_CTX_set_max_proto_version(SSL_CTX * ctx,int version)80 SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version)
81 {
82 int ssl_options = 0;
83
84 AssertArg(version != 0);
85
86 /*
87 * Some OpenSSL versions define TLS*_VERSION macros but not the
88 * corresponding SSL_OP_NO_* macro, so in those cases we have to return
89 * unsuccessfully here.
90 */
91 #ifdef TLS1_1_VERSION
92 if (version < TLS1_1_VERSION)
93 {
94 #ifdef SSL_OP_NO_TLSv1_1
95 ssl_options |= SSL_OP_NO_TLSv1_1;
96 #else
97 return 0;
98 #endif
99 }
100 #endif
101 #ifdef TLS1_2_VERSION
102 if (version < TLS1_2_VERSION)
103 {
104 #ifdef SSL_OP_NO_TLSv1_2
105 ssl_options |= SSL_OP_NO_TLSv1_2;
106 #else
107 return 0;
108 #endif
109 }
110 #endif
111
112 SSL_CTX_set_options(ctx, ssl_options);
113
114 return 1; /* success */
115 }
116
117 #endif /* !SSL_CTX_set_min_proto_version */
118