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