Maintainers.txt: Update email address
[mirror_edk2.git] / CryptoPkg / Library / TlsLib / TlsInit.c
CommitLineData
264702a0
HW
1/** @file\r
2 SSL/TLS Initialization Library Wrapper Implementation over OpenSSL.\r
3\r
4Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
5(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
2009f6b4 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
264702a0
HW
7\r
8**/\r
9\r
10#include "InternalTlsLib.h"\r
11\r
12/**\r
13 Initializes the OpenSSL library.\r
14\r
15 This function registers ciphers and digests used directly and indirectly\r
16 by SSL/TLS, and initializes the readable error messages.\r
17 This function must be called before any other action takes places.\r
18\r
0878771f
JW
19 @retval TRUE The OpenSSL library has been initialized.\r
20 @retval FALSE Failed to initialize the OpenSSL library.\r
21\r
264702a0 22**/\r
0878771f 23BOOLEAN\r
264702a0
HW
24EFIAPI\r
25TlsInitialize (\r
26 VOID\r
27 )\r
28{\r
7c342378 29 INTN Ret;\r
0878771f 30\r
264702a0
HW
31 //\r
32 // Performs initialization of crypto and ssl library, and loads required\r
33 // algorithms.\r
34 //\r
0878771f
JW
35 Ret = OPENSSL_init_ssl (\r
36 OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS,\r
37 NULL\r
38 );\r
39 if (Ret != 1) {\r
40 return FALSE;\r
41 }\r
264702a0
HW
42\r
43 //\r
44 // Initialize the pseudorandom number generator.\r
45 //\r
0878771f 46 return RandomSeed (NULL, 0);\r
264702a0
HW
47}\r
48\r
49/**\r
50 Free an allocated SSL_CTX object.\r
51\r
52 @param[in] TlsCtx Pointer to the SSL_CTX object to be released.\r
53\r
54**/\r
55VOID\r
56EFIAPI\r
57TlsCtxFree (\r
7c342378 58 IN VOID *TlsCtx\r
264702a0
HW
59 )\r
60{\r
61 if (TlsCtx == NULL) {\r
62 return;\r
63 }\r
64\r
65 if (TlsCtx != NULL) {\r
7c342378 66 SSL_CTX_free ((SSL_CTX *)(TlsCtx));\r
264702a0
HW
67 }\r
68}\r
69\r
70/**\r
71 Creates a new SSL_CTX object as framework to establish TLS/SSL enabled\r
72 connections.\r
73\r
74 @param[in] MajorVer Major Version of TLS/SSL Protocol.\r
75 @param[in] MinorVer Minor Version of TLS/SSL Protocol.\r
76\r
77 @return Pointer to an allocated SSL_CTX object.\r
78 If the creation failed, TlsCtxNew() returns NULL.\r
79\r
80**/\r
81VOID *\r
82EFIAPI\r
83TlsCtxNew (\r
7c342378
MK
84 IN UINT8 MajorVer,\r
85 IN UINT8 MinorVer\r
264702a0
HW
86 )\r
87{\r
88 SSL_CTX *TlsCtx;\r
89 UINT16 ProtoVersion;\r
90\r
91 ProtoVersion = (MajorVer << 8) | MinorVer;\r
92\r
93 TlsCtx = SSL_CTX_new (SSLv23_client_method ());\r
94 if (TlsCtx == NULL) {\r
95 return NULL;\r
96 }\r
97\r
98 //\r
99 // Ensure SSLv3 is disabled\r
100 //\r
101 SSL_CTX_set_options (TlsCtx, SSL_OP_NO_SSLv3);\r
102\r
103 //\r
104 // Treat as minimum accepted versions by setting the minimal bound.\r
105 // Client can use higher TLS version if server supports it\r
106 //\r
107 SSL_CTX_set_min_proto_version (TlsCtx, ProtoVersion);\r
108\r
7c342378 109 return (VOID *)TlsCtx;\r
264702a0
HW
110}\r
111\r
112/**\r
113 Free an allocated TLS object.\r
114\r
115 This function removes the TLS object pointed to by Tls and frees up the\r
116 allocated memory. If Tls is NULL, nothing is done.\r
117\r
118 @param[in] Tls Pointer to the TLS object to be freed.\r
119\r
120**/\r
121VOID\r
122EFIAPI\r
123TlsFree (\r
7c342378 124 IN VOID *Tls\r
264702a0
HW
125 )\r
126{\r
127 TLS_CONNECTION *TlsConn;\r
128\r
7c342378 129 TlsConn = (TLS_CONNECTION *)Tls;\r
264702a0
HW
130 if (TlsConn == NULL) {\r
131 return;\r
132 }\r
133\r
134 //\r
6aac2db4 135 // Free the internal TLS and related BIO objects.\r
264702a0
HW
136 //\r
137 if (TlsConn->Ssl != NULL) {\r
138 SSL_free (TlsConn->Ssl);\r
139 }\r
140\r
264702a0
HW
141 OPENSSL_free (Tls);\r
142}\r
143\r
144/**\r
145 Create a new TLS object for a connection.\r
146\r
147 This function creates a new TLS object for a connection. The new object\r
148 inherits the setting of the underlying context TlsCtx: connection method,\r
149 options, verification setting.\r
150\r
151 @param[in] TlsCtx Pointer to the SSL_CTX object.\r
152\r
153 @return Pointer to an allocated SSL object.\r
154 If the creation failed, TlsNew() returns NULL.\r
155\r
156**/\r
157VOID *\r
158EFIAPI\r
159TlsNew (\r
7c342378 160 IN VOID *TlsCtx\r
264702a0
HW
161 )\r
162{\r
163 TLS_CONNECTION *TlsConn;\r
164 SSL_CTX *SslCtx;\r
165 X509_STORE *X509Store;\r
166\r
167 TlsConn = NULL;\r
168\r
169 //\r
170 // Allocate one new TLS_CONNECTION object\r
171 //\r
7c342378 172 TlsConn = (TLS_CONNECTION *)OPENSSL_malloc (sizeof (TLS_CONNECTION));\r
264702a0
HW
173 if (TlsConn == NULL) {\r
174 return NULL;\r
175 }\r
176\r
177 TlsConn->Ssl = NULL;\r
178\r
179 //\r
180 // Create a new SSL Object\r
181 //\r
7c342378 182 TlsConn->Ssl = SSL_new ((SSL_CTX *)TlsCtx);\r
264702a0 183 if (TlsConn->Ssl == NULL) {\r
7c342378 184 TlsFree ((VOID *)TlsConn);\r
264702a0
HW
185 return NULL;\r
186 }\r
187\r
188 //\r
189 // This retains compatibility with previous version of OpenSSL.\r
190 //\r
191 SSL_set_security_level (TlsConn->Ssl, 0);\r
192\r
193 //\r
194 // Initialize the created SSL Object\r
195 //\r
196 SSL_set_info_callback (TlsConn->Ssl, NULL);\r
197\r
198 TlsConn->InBio = NULL;\r
199\r
200 //\r
201 // Set up Reading BIO for TLS connection\r
202 //\r
203 TlsConn->InBio = BIO_new (BIO_s_mem ());\r
204 if (TlsConn->InBio == NULL) {\r
7c342378 205 TlsFree ((VOID *)TlsConn);\r
264702a0
HW
206 return NULL;\r
207 }\r
208\r
209 //\r
210 // Sets the behaviour of memory BIO when it is empty. It will set the\r
211 // read retry flag.\r
212 //\r
213 BIO_set_mem_eof_return (TlsConn->InBio, -1);\r
214\r
215 TlsConn->OutBio = NULL;\r
216\r
217 //\r
218 // Set up Writing BIO for TLS connection\r
219 //\r
220 TlsConn->OutBio = BIO_new (BIO_s_mem ());\r
221 if (TlsConn->OutBio == NULL) {\r
7c342378 222 TlsFree ((VOID *)TlsConn);\r
264702a0
HW
223 return NULL;\r
224 }\r
225\r
226 //\r
227 // Sets the behaviour of memory BIO when it is empty. It will set the\r
228 // write retry flag.\r
229 //\r
230 BIO_set_mem_eof_return (TlsConn->OutBio, -1);\r
231\r
232 ASSERT (TlsConn->Ssl != NULL && TlsConn->InBio != NULL && TlsConn->OutBio != NULL);\r
233\r
234 //\r
235 // Connects the InBio and OutBio for the read and write operations.\r
236 //\r
237 SSL_set_bio (TlsConn->Ssl, TlsConn->InBio, TlsConn->OutBio);\r
238\r
239 //\r
240 // Create new X509 store if needed\r
241 //\r
242 SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl);\r
243 X509Store = SSL_CTX_get_cert_store (SslCtx);\r
244 if (X509Store == NULL) {\r
245 X509Store = X509_STORE_new ();\r
246 if (X509Store == NULL) {\r
7c342378 247 TlsFree ((VOID *)TlsConn);\r
264702a0
HW
248 return NULL;\r
249 }\r
7c342378 250\r
264702a0
HW
251 SSL_CTX_set1_verify_cert_store (SslCtx, X509Store);\r
252 X509_STORE_free (X509Store);\r
253 }\r
254\r
255 //\r
256 // Set X509_STORE flags used in certificate validation\r
257 //\r
258 X509_STORE_set_flags (\r
259 X509Store,\r
260 X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME\r
261 );\r
7c342378 262 return (VOID *)TlsConn;\r
264702a0 263}\r