MdeModulePkg/Core: Fix potential array overflow
[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
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**/\r
26VOID\r
27EFIAPI\r
28TlsInitialize (\r
29 VOID\r
30 )\r
31{\r
32 //\r
33 // Performs initialization of crypto and ssl library, and loads required\r
34 // algorithms.\r
35 //\r
36 OPENSSL_init_ssl (\r
37 OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS,\r
38 NULL\r
39 );\r
40\r
41 //\r
42 // Initialize the pseudorandom number generator.\r
43 //\r
44 RandomSeed (NULL, 0);\r
45}\r
46\r
47/**\r
48 Free an allocated SSL_CTX object.\r
49\r
50 @param[in] TlsCtx Pointer to the SSL_CTX object to be released.\r
51\r
52**/\r
53VOID\r
54EFIAPI\r
55TlsCtxFree (\r
56 IN VOID *TlsCtx\r
57 )\r
58{\r
59 if (TlsCtx == NULL) {\r
60 return;\r
61 }\r
62\r
63 if (TlsCtx != NULL) {\r
64 SSL_CTX_free ((SSL_CTX *) (TlsCtx));\r
65 }\r
66}\r
67\r
68/**\r
69 Creates a new SSL_CTX object as framework to establish TLS/SSL enabled\r
70 connections.\r
71\r
72 @param[in] MajorVer Major Version of TLS/SSL Protocol.\r
73 @param[in] MinorVer Minor Version of TLS/SSL Protocol.\r
74\r
75 @return Pointer to an allocated SSL_CTX object.\r
76 If the creation failed, TlsCtxNew() returns NULL.\r
77\r
78**/\r
79VOID *\r
80EFIAPI\r
81TlsCtxNew (\r
82 IN UINT8 MajorVer,\r
83 IN UINT8 MinorVer\r
84 )\r
85{\r
86 SSL_CTX *TlsCtx;\r
87 UINT16 ProtoVersion;\r
88\r
89 ProtoVersion = (MajorVer << 8) | MinorVer;\r
90\r
91 TlsCtx = SSL_CTX_new (SSLv23_client_method ());\r
92 if (TlsCtx == NULL) {\r
93 return NULL;\r
94 }\r
95\r
96 //\r
97 // Ensure SSLv3 is disabled\r
98 //\r
99 SSL_CTX_set_options (TlsCtx, SSL_OP_NO_SSLv3);\r
100\r
101 //\r
102 // Treat as minimum accepted versions by setting the minimal bound.\r
103 // Client can use higher TLS version if server supports it\r
104 //\r
105 SSL_CTX_set_min_proto_version (TlsCtx, ProtoVersion);\r
106\r
107 return (VOID *) TlsCtx;\r
108}\r
109\r
110/**\r
111 Free an allocated TLS object.\r
112\r
113 This function removes the TLS object pointed to by Tls and frees up the\r
114 allocated memory. If Tls is NULL, nothing is done.\r
115\r
116 @param[in] Tls Pointer to the TLS object to be freed.\r
117\r
118**/\r
119VOID\r
120EFIAPI\r
121TlsFree (\r
122 IN VOID *Tls\r
123 )\r
124{\r
125 TLS_CONNECTION *TlsConn;\r
126\r
127 TlsConn = (TLS_CONNECTION *) Tls;\r
128 if (TlsConn == NULL) {\r
129 return;\r
130 }\r
131\r
132 //\r
6aac2db4 133 // Free the internal TLS and related BIO objects.\r
264702a0
HW
134 //\r
135 if (TlsConn->Ssl != NULL) {\r
136 SSL_free (TlsConn->Ssl);\r
137 }\r
138\r
264702a0
HW
139 OPENSSL_free (Tls);\r
140}\r
141\r
142/**\r
143 Create a new TLS object for a connection.\r
144\r
145 This function creates a new TLS object for a connection. The new object\r
146 inherits the setting of the underlying context TlsCtx: connection method,\r
147 options, verification setting.\r
148\r
149 @param[in] TlsCtx Pointer to the SSL_CTX object.\r
150\r
151 @return Pointer to an allocated SSL object.\r
152 If the creation failed, TlsNew() returns NULL.\r
153\r
154**/\r
155VOID *\r
156EFIAPI\r
157TlsNew (\r
158 IN VOID *TlsCtx\r
159 )\r
160{\r
161 TLS_CONNECTION *TlsConn;\r
162 SSL_CTX *SslCtx;\r
163 X509_STORE *X509Store;\r
164\r
165 TlsConn = NULL;\r
166\r
167 //\r
168 // Allocate one new TLS_CONNECTION object\r
169 //\r
170 TlsConn = (TLS_CONNECTION *) OPENSSL_malloc (sizeof (TLS_CONNECTION));\r
171 if (TlsConn == NULL) {\r
172 return NULL;\r
173 }\r
174\r
175 TlsConn->Ssl = NULL;\r
176\r
177 //\r
178 // Create a new SSL Object\r
179 //\r
180 TlsConn->Ssl = SSL_new ((SSL_CTX *) TlsCtx);\r
181 if (TlsConn->Ssl == NULL) {\r
182 TlsFree ((VOID *) TlsConn);\r
183 return NULL;\r
184 }\r
185\r
186 //\r
187 // This retains compatibility with previous version of OpenSSL.\r
188 //\r
189 SSL_set_security_level (TlsConn->Ssl, 0);\r
190\r
191 //\r
192 // Initialize the created SSL Object\r
193 //\r
194 SSL_set_info_callback (TlsConn->Ssl, NULL);\r
195\r
196 TlsConn->InBio = NULL;\r
197\r
198 //\r
199 // Set up Reading BIO for TLS connection\r
200 //\r
201 TlsConn->InBio = BIO_new (BIO_s_mem ());\r
202 if (TlsConn->InBio == NULL) {\r
203 TlsFree ((VOID *) TlsConn);\r
204 return NULL;\r
205 }\r
206\r
207 //\r
208 // Sets the behaviour of memory BIO when it is empty. It will set the\r
209 // read retry flag.\r
210 //\r
211 BIO_set_mem_eof_return (TlsConn->InBio, -1);\r
212\r
213 TlsConn->OutBio = NULL;\r
214\r
215 //\r
216 // Set up Writing BIO for TLS connection\r
217 //\r
218 TlsConn->OutBio = BIO_new (BIO_s_mem ());\r
219 if (TlsConn->OutBio == NULL) {\r
220 TlsFree ((VOID *) TlsConn);\r
221 return NULL;\r
222 }\r
223\r
224 //\r
225 // Sets the behaviour of memory BIO when it is empty. It will set the\r
226 // write retry flag.\r
227 //\r
228 BIO_set_mem_eof_return (TlsConn->OutBio, -1);\r
229\r
230 ASSERT (TlsConn->Ssl != NULL && TlsConn->InBio != NULL && TlsConn->OutBio != NULL);\r
231\r
232 //\r
233 // Connects the InBio and OutBio for the read and write operations.\r
234 //\r
235 SSL_set_bio (TlsConn->Ssl, TlsConn->InBio, TlsConn->OutBio);\r
236\r
237 //\r
238 // Create new X509 store if needed\r
239 //\r
240 SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl);\r
241 X509Store = SSL_CTX_get_cert_store (SslCtx);\r
242 if (X509Store == NULL) {\r
243 X509Store = X509_STORE_new ();\r
244 if (X509Store == NULL) {\r
245 TlsFree ((VOID *) TlsConn);\r
246 return NULL;\r
247 }\r
248 SSL_CTX_set1_verify_cert_store (SslCtx, X509Store);\r
249 X509_STORE_free (X509Store);\r
250 }\r
251\r
252 //\r
253 // Set X509_STORE flags used in certificate validation\r
254 //\r
255 X509_STORE_set_flags (\r
256 X509Store,\r
257 X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME\r
258 );\r
259 return (VOID *) TlsConn;\r
260}\r
261\r