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