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