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