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