]>
Commit | Line | Data |
---|---|---|
9396cdfe JW |
1 | /** @file |
2 | SSL/TLS Configuration Library Wrapper Implementation over OpenSSL. | |
3 | ||
9fba84ac | 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 | typedef struct { | |
19 | // | |
20 | // IANA/IETF defined Cipher Suite ID | |
21 | // | |
22 | UINT16 IanaCipher; | |
23 | // | |
24 | // OpenSSL-used Cipher Suite String | |
25 | // | |
26 | CONST CHAR8 *OpensslCipher; | |
27 | } TLS_CIPHER_PAIR; | |
28 | ||
29 | // | |
30 | // The mapping table between IANA/IETF Cipher Suite definitions and | |
31 | // OpenSSL-used Cipher Suite name. | |
32 | // | |
33 | STATIC CONST TLS_CIPHER_PAIR TlsCipherMappingTable[] = { | |
34 | { 0x0001, "NULL-MD5" }, /// TLS_RSA_WITH_NULL_MD5 | |
35 | { 0x0002, "NULL-SHA" }, /// TLS_RSA_WITH_NULL_SHA | |
36 | { 0x0004, "RC4-MD5" }, /// TLS_RSA_WITH_RC4_128_MD5 | |
37 | { 0x0005, "RC4-SHA" }, /// TLS_RSA_WITH_RC4_128_SHA | |
38 | { 0x000A, "DES-CBC3-SHA" }, /// TLS_RSA_WITH_3DES_EDE_CBC_SHA, mandatory TLS 1.1 | |
39 | { 0x0016, "DHE-RSA-DES-CBC3-SHA" }, /// TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA | |
40 | { 0x002F, "AES128-SHA" }, /// TLS_RSA_WITH_AES_128_CBC_SHA, mandatory TLS 1.2 | |
41 | { 0x0030, "DH-DSS-AES128-SHA" }, /// TLS_DH_DSS_WITH_AES_128_CBC_SHA | |
42 | { 0x0031, "DH-RSA-AES128-SHA" }, /// TLS_DH_RSA_WITH_AES_128_CBC_SHA | |
43 | { 0x0033, "DHE-RSA-AES128-SHA" }, /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA | |
44 | { 0x0035, "AES256-SHA" }, /// TLS_RSA_WITH_AES_256_CBC_SHA | |
45 | { 0x0036, "DH-DSS-AES256-SHA" }, /// TLS_DH_DSS_WITH_AES_256_CBC_SHA | |
46 | { 0x0037, "DH-RSA-AES256-SHA" }, /// TLS_DH_RSA_WITH_AES_256_CBC_SHA | |
47 | { 0x0039, "DHE-RSA-AES256-SHA" }, /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA | |
48 | { 0x003B, "NULL-SHA256" }, /// TLS_RSA_WITH_NULL_SHA256 | |
49 | { 0x003C, "AES128-SHA256" }, /// TLS_RSA_WITH_AES_128_CBC_SHA256 | |
50 | { 0x003D, "AES256-SHA256" }, /// TLS_RSA_WITH_AES_256_CBC_SHA256 | |
51 | { 0x003E, "DH-DSS-AES128-SHA256" }, /// TLS_DH_DSS_WITH_AES_128_CBC_SHA256 | |
52 | { 0x003F, "DH-RSA-AES128-SHA256" }, /// TLS_DH_RSA_WITH_AES_128_CBC_SHA256 | |
53 | { 0x0067, "DHE-RSA-AES128-SHA256" }, /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 | |
54 | { 0x0068, "DH-DSS-AES256-SHA256" }, /// TLS_DH_DSS_WITH_AES_256_CBC_SHA256 | |
55 | { 0x0069, "DH-RSA-AES256-SHA256" }, /// TLS_DH_RSA_WITH_AES_256_CBC_SHA256 | |
56 | { 0x006B, "DHE-RSA-AES256-SHA256" } /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 | |
57 | }; | |
58 | ||
59 | /** | |
60 | Gets the OpenSSL cipher suite string for the supplied IANA TLS cipher suite. | |
61 | ||
62 | @param[in] CipherId The supplied IANA TLS cipher suite ID. | |
63 | ||
64 | @return The corresponding OpenSSL cipher suite string if found, | |
65 | NULL otherwise. | |
66 | ||
67 | **/ | |
68 | STATIC | |
69 | CONST CHAR8 * | |
70 | TlsGetCipherString ( | |
71 | IN UINT16 CipherId | |
72 | ) | |
73 | { | |
74 | CONST TLS_CIPHER_PAIR *CipherEntry; | |
75 | UINTN TableSize; | |
76 | UINTN Index; | |
77 | ||
78 | CipherEntry = TlsCipherMappingTable; | |
79 | TableSize = sizeof (TlsCipherMappingTable) / sizeof (TLS_CIPHER_PAIR); | |
80 | ||
81 | // | |
82 | // Search Cipher Mapping Table for IANA-OpenSSL Cipher Translation | |
83 | // | |
84 | for (Index = 0; Index < TableSize; Index++, CipherEntry++) { | |
85 | // | |
86 | // Translate IANA cipher suite name to OpenSSL name. | |
87 | // | |
88 | if (CipherEntry->IanaCipher == CipherId) { | |
89 | return CipherEntry->OpensslCipher; | |
90 | } | |
91 | } | |
92 | ||
93 | // | |
94 | // No Cipher Mapping found, return NULL. | |
95 | // | |
96 | return NULL; | |
97 | } | |
98 | ||
99 | /** | |
100 | Set a new TLS/SSL method for a particular TLS object. | |
101 | ||
102 | This function sets a new TLS/SSL method for a particular TLS object. | |
103 | ||
104 | @param[in] Tls Pointer to a TLS object. | |
105 | @param[in] MajorVer Major Version of TLS/SSL Protocol. | |
106 | @param[in] MinorVer Minor Version of TLS/SSL Protocol. | |
107 | ||
108 | @retval EFI_SUCCESS The TLS/SSL method was set successfully. | |
109 | @retval EFI_INVALID_PARAMETER The parameter is invalid. | |
110 | @retval EFI_UNSUPPORTED Unsupported TLS/SSL method. | |
111 | ||
112 | **/ | |
113 | EFI_STATUS | |
114 | EFIAPI | |
115 | TlsSetVersion ( | |
116 | IN VOID *Tls, | |
117 | IN UINT8 MajorVer, | |
118 | IN UINT8 MinorVer | |
119 | ) | |
120 | { | |
121 | TLS_CONNECTION *TlsConn; | |
122 | UINT16 ProtoVersion; | |
123 | ||
124 | TlsConn = (TLS_CONNECTION *)Tls; | |
125 | if (TlsConn == NULL || TlsConn->Ssl == NULL) { | |
126 | return EFI_INVALID_PARAMETER; | |
127 | } | |
128 | ||
129 | ProtoVersion = (MajorVer << 8) | MinorVer; | |
130 | ||
131 | switch (ProtoVersion) { | |
132 | case TLS1_VERSION: | |
133 | // | |
134 | // TLS 1.0 | |
135 | // | |
136 | SSL_set_ssl_method (TlsConn->Ssl, TLSv1_method ()); | |
137 | break; | |
138 | case TLS1_1_VERSION: | |
139 | // | |
140 | // TLS 1.1 | |
141 | // | |
142 | SSL_set_ssl_method (TlsConn->Ssl, TLSv1_1_method ()); | |
143 | break; | |
144 | case TLS1_2_VERSION: | |
145 | // | |
146 | // TLS 1.2 | |
147 | // | |
148 | SSL_set_ssl_method (TlsConn->Ssl, TLSv1_2_method ()); | |
149 | break; | |
150 | default: | |
151 | // | |
152 | // Unsupported Protocol Version | |
153 | // | |
154 | return EFI_UNSUPPORTED; | |
155 | } | |
156 | ||
157 | return EFI_SUCCESS;; | |
158 | } | |
159 | ||
160 | /** | |
161 | Set TLS object to work in client or server mode. | |
162 | ||
163 | This function prepares a TLS object to work in client or server mode. | |
164 | ||
165 | @param[in] Tls Pointer to a TLS object. | |
166 | @param[in] IsServer Work in server mode. | |
167 | ||
168 | @retval EFI_SUCCESS The TLS/SSL work mode was set successfully. | |
169 | @retval EFI_INVALID_PARAMETER The parameter is invalid. | |
170 | @retval EFI_UNSUPPORTED Unsupported TLS/SSL work mode. | |
171 | ||
172 | **/ | |
173 | EFI_STATUS | |
174 | EFIAPI | |
175 | TlsSetConnectionEnd ( | |
176 | IN VOID *Tls, | |
177 | IN BOOLEAN IsServer | |
178 | ) | |
179 | { | |
180 | TLS_CONNECTION *TlsConn; | |
181 | ||
182 | TlsConn = (TLS_CONNECTION *) Tls; | |
183 | if (TlsConn == NULL || TlsConn->Ssl == NULL) { | |
184 | return EFI_INVALID_PARAMETER; | |
185 | } | |
186 | ||
187 | if (!IsServer) { | |
188 | // | |
189 | // Set TLS to work in Client mode. | |
190 | // | |
191 | SSL_set_connect_state (TlsConn->Ssl); | |
192 | } else { | |
193 | // | |
194 | // Set TLS to work in Server mode. | |
195 | // It is unsupported for UEFI version currently. | |
196 | // | |
197 | //SSL_set_accept_state (TlsConn->Ssl); | |
198 | return EFI_UNSUPPORTED; | |
199 | } | |
200 | ||
201 | return EFI_SUCCESS; | |
202 | } | |
203 | ||
204 | /** | |
205 | Set the ciphers list to be used by the TLS object. | |
206 | ||
207 | This function sets the ciphers for use by a specified TLS object. | |
208 | ||
209 | @param[in] Tls Pointer to a TLS object. | |
210 | @param[in] CipherId Pointer to a UINT16 cipher Id. | |
211 | @param[in] CipherNum The number of cipher in the list. | |
212 | ||
213 | @retval EFI_SUCCESS The ciphers list was set successfully. | |
214 | @retval EFI_INVALID_PARAMETER The parameter is invalid. | |
215 | @retval EFI_UNSUPPORTED Unsupported TLS cipher in the list. | |
216 | ||
217 | **/ | |
218 | EFI_STATUS | |
219 | EFIAPI | |
220 | TlsSetCipherList ( | |
221 | IN VOID *Tls, | |
222 | IN UINT16 *CipherId, | |
223 | IN UINTN CipherNum | |
224 | ) | |
225 | { | |
226 | TLS_CONNECTION *TlsConn; | |
227 | UINTN Index; | |
228 | CONST CHAR8 *MappingName; | |
229 | CHAR8 CipherString[500]; | |
230 | ||
231 | TlsConn = (TLS_CONNECTION *) Tls; | |
232 | if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) { | |
233 | return EFI_INVALID_PARAMETER; | |
234 | } | |
235 | ||
236 | MappingName = NULL; | |
237 | ||
238 | memset (CipherString, 0, sizeof (CipherString)); | |
239 | ||
240 | for (Index = 0; Index < CipherNum; Index++) { | |
241 | // | |
242 | // Handling OpenSSL / RFC Cipher name mapping. | |
243 | // | |
244 | MappingName = TlsGetCipherString (*(CipherId + Index)); | |
245 | if (MappingName == NULL) { | |
246 | return EFI_UNSUPPORTED; | |
247 | } | |
248 | ||
249 | if (Index != 0) { | |
250 | // | |
251 | // The ciphers were separated by a colon. | |
252 | // | |
253 | AsciiStrCatS (CipherString, sizeof (CipherString), ":"); | |
254 | } | |
255 | ||
256 | AsciiStrCatS (CipherString, sizeof (CipherString), MappingName); | |
257 | } | |
258 | ||
259 | AsciiStrCatS (CipherString, sizeof (CipherString), ":@STRENGTH"); | |
260 | ||
261 | // | |
262 | // Sets the ciphers for use by the Tls object. | |
263 | // | |
264 | if (SSL_set_cipher_list (TlsConn->Ssl, CipherString) <= 0) { | |
265 | return EFI_UNSUPPORTED; | |
266 | } | |
267 | ||
268 | return EFI_SUCCESS; | |
269 | } | |
270 | ||
271 | /** | |
272 | Set the compression method for TLS/SSL operations. | |
273 | ||
274 | This function handles TLS/SSL integrated compression methods. | |
275 | ||
276 | @param[in] CompMethod The compression method ID. | |
277 | ||
278 | @retval EFI_SUCCESS The compression method for the communication was | |
279 | set successfully. | |
280 | @retval EFI_UNSUPPORTED Unsupported compression method. | |
281 | ||
282 | **/ | |
283 | EFI_STATUS | |
284 | EFIAPI | |
285 | TlsSetCompressionMethod ( | |
286 | IN UINT8 CompMethod | |
287 | ) | |
288 | { | |
289 | COMP_METHOD *Cm; | |
290 | INTN Ret; | |
291 | ||
292 | Cm = NULL; | |
293 | Ret = 0; | |
294 | ||
295 | if (CompMethod == 0) { | |
296 | // | |
297 | // TLS defines one standard compression method, CompressionMethod.null (0), | |
298 | // which specifies that data exchanged via the record protocol will not be compressed. | |
299 | // So, return EFI_SUCCESS directly (RFC 3749). | |
300 | // | |
301 | return EFI_SUCCESS; | |
302 | } else if (CompMethod == 1) { | |
303 | Cm = COMP_zlib(); | |
304 | } else { | |
305 | return EFI_UNSUPPORTED; | |
306 | } | |
307 | ||
308 | // | |
309 | // Adds the compression method to the list of available | |
310 | // compression methods. | |
311 | // | |
312 | Ret = SSL_COMP_add_compression_method (CompMethod, Cm); | |
313 | if (Ret != 0) { | |
314 | return EFI_UNSUPPORTED; | |
315 | } | |
316 | ||
317 | return EFI_SUCCESS; | |
318 | } | |
319 | ||
320 | /** | |
321 | Set peer certificate verification mode for the TLS connection. | |
322 | ||
323 | This function sets the verification mode flags for the TLS connection. | |
324 | ||
325 | @param[in] Tls Pointer to the TLS object. | |
326 | @param[in] VerifyMode A set of logically or'ed verification mode flags. | |
327 | ||
328 | **/ | |
329 | VOID | |
330 | EFIAPI | |
331 | TlsSetVerify ( | |
332 | IN VOID *Tls, | |
333 | IN UINT32 VerifyMode | |
334 | ) | |
335 | { | |
336 | TLS_CONNECTION *TlsConn; | |
337 | ||
338 | TlsConn = (TLS_CONNECTION *) Tls; | |
339 | if (TlsConn == NULL || TlsConn->Ssl == NULL) { | |
340 | return; | |
341 | } | |
342 | ||
343 | // | |
344 | // Set peer certificate verification parameters with NULL callback. | |
345 | // | |
346 | SSL_set_verify (TlsConn->Ssl, VerifyMode, NULL); | |
347 | } | |
348 | ||
349 | /** | |
350 | Sets a TLS/SSL session ID to be used during TLS/SSL connect. | |
351 | ||
352 | This function sets a session ID to be used when the TLS/SSL connection is | |
353 | to be established. | |
354 | ||
355 | @param[in] Tls Pointer to the TLS object. | |
356 | @param[in] SessionId Session ID data used for session resumption. | |
357 | @param[in] SessionIdLen Length of Session ID in bytes. | |
358 | ||
359 | @retval EFI_SUCCESS Session ID was set successfully. | |
360 | @retval EFI_INVALID_PARAMETER The parameter is invalid. | |
361 | @retval EFI_UNSUPPORTED No available session for ID setting. | |
362 | ||
363 | **/ | |
364 | EFI_STATUS | |
365 | EFIAPI | |
366 | TlsSetSessionId ( | |
367 | IN VOID *Tls, | |
368 | IN UINT8 *SessionId, | |
369 | IN UINT16 SessionIdLen | |
370 | ) | |
371 | { | |
372 | TLS_CONNECTION *TlsConn; | |
373 | SSL_SESSION *Session; | |
374 | ||
375 | TlsConn = (TLS_CONNECTION *) Tls; | |
376 | Session = NULL; | |
377 | ||
378 | if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL) { | |
379 | return EFI_INVALID_PARAMETER; | |
380 | } | |
381 | ||
382 | Session = SSL_get_session (TlsConn->Ssl); | |
383 | if (Session == NULL) { | |
384 | return EFI_UNSUPPORTED; | |
385 | } | |
386 | ||
387 | Session->session_id_length = SessionIdLen; | |
388 | CopyMem (Session->session_id, SessionId, Session->session_id_length); | |
389 | ||
390 | return EFI_SUCCESS; | |
391 | } | |
392 | ||
393 | /** | |
394 | Adds the CA to the cert store when requesting Server or Client authentication. | |
395 | ||
396 | This function adds the CA certificate to the list of CAs when requesting | |
397 | Server or Client authentication for the chosen TLS connection. | |
398 | ||
399 | @param[in] Tls Pointer to the TLS object. | |
400 | @param[in] Data Pointer to the data buffer of a DER-encoded binary | |
401 | X.509 certificate or PEM-encoded X.509 certificate. | |
402 | @param[in] DataSize The size of data buffer in bytes. | |
403 | ||
404 | @retval EFI_SUCCESS The operation succeeded. | |
405 | @retval EFI_INVALID_PARAMETER The parameter is invalid. | |
406 | @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated. | |
407 | @retval EFI_ABORTED Invalid X.509 certificate. | |
408 | ||
409 | **/ | |
410 | EFI_STATUS | |
411 | EFIAPI | |
412 | TlsSetCaCertificate ( | |
413 | IN VOID *Tls, | |
414 | IN VOID *Data, | |
415 | IN UINTN DataSize | |
416 | ) | |
417 | { | |
418 | BIO *BioCert; | |
419 | X509 *Cert; | |
420 | X509_STORE *X509Store; | |
421 | EFI_STATUS Status; | |
422 | TLS_CONNECTION *TlsConn; | |
423 | SSL_CTX *SslCtx; | |
424 | INTN Ret; | |
9fba84ac | 425 | UINTN ErrorCode; |
9396cdfe JW |
426 | |
427 | BioCert = NULL; | |
428 | Cert = NULL; | |
429 | X509Store = NULL; | |
430 | Status = EFI_SUCCESS; | |
431 | TlsConn = (TLS_CONNECTION *) Tls; | |
432 | Ret = 0; | |
433 | ||
434 | if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) { | |
435 | return EFI_INVALID_PARAMETER; | |
436 | } | |
437 | ||
438 | // | |
439 | // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate. | |
440 | // Determine whether certificate is from DER encoding, if so, translate it to X509 structure. | |
441 | // | |
442 | Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize); | |
443 | if (Cert == NULL) { | |
444 | // | |
445 | // Certificate is from PEM encoding. | |
446 | // | |
447 | BioCert = BIO_new (BIO_s_mem ()); | |
448 | if (BioCert == NULL) { | |
449 | Status = EFI_OUT_OF_RESOURCES; | |
450 | goto ON_EXIT; | |
451 | } | |
452 | ||
453 | if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) { | |
454 | Status = EFI_ABORTED; | |
455 | goto ON_EXIT; | |
456 | } | |
457 | ||
458 | Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL); | |
459 | if (Cert == NULL) { | |
460 | Status = EFI_ABORTED; | |
461 | goto ON_EXIT; | |
462 | } | |
463 | } | |
464 | ||
465 | SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl); | |
466 | X509Store = SSL_CTX_get_cert_store (SslCtx); | |
467 | if (X509Store == NULL) { | |
468 | Status = EFI_ABORTED; | |
469 | goto ON_EXIT; | |
470 | } | |
471 | ||
472 | // | |
473 | // Add certificate to X509 store | |
474 | // | |
475 | Ret = X509_STORE_add_cert (X509Store, Cert); | |
476 | if (Ret != 1) { | |
477 | ErrorCode = ERR_peek_last_error (); | |
478 | // | |
479 | // Ignore "already in table" errors | |
480 | // | |
481 | if (!(ERR_GET_FUNC (ErrorCode) == X509_F_X509_STORE_ADD_CERT && | |
482 | ERR_GET_REASON (ErrorCode) == X509_R_CERT_ALREADY_IN_HASH_TABLE)) { | |
483 | Status = EFI_ABORTED; | |
484 | goto ON_EXIT; | |
485 | } | |
486 | } | |
487 | ||
488 | ON_EXIT: | |
489 | if (BioCert != NULL) { | |
490 | BIO_free (BioCert); | |
491 | } | |
492 | ||
493 | if (Cert != NULL) { | |
494 | X509_free (Cert); | |
495 | } | |
496 | ||
497 | return Status; | |
498 | } | |
499 | ||
500 | /** | |
501 | Loads the local public certificate into the specified TLS object. | |
502 | ||
503 | This function loads the X.509 certificate into the specified TLS object | |
504 | for TLS negotiation. | |
505 | ||
506 | @param[in] Tls Pointer to the TLS object. | |
507 | @param[in] Data Pointer to the data buffer of a DER-encoded binary | |
508 | X.509 certificate or PEM-encoded X.509 certificate. | |
509 | @param[in] DataSize The size of data buffer in bytes. | |
510 | ||
511 | @retval EFI_SUCCESS The operation succeeded. | |
512 | @retval EFI_INVALID_PARAMETER The parameter is invalid. | |
513 | @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated. | |
514 | @retval EFI_ABORTED Invalid X.509 certificate. | |
515 | ||
516 | **/ | |
517 | EFI_STATUS | |
518 | EFIAPI | |
519 | TlsSetHostPublicCert ( | |
520 | IN VOID *Tls, | |
521 | IN VOID *Data, | |
522 | IN UINTN DataSize | |
523 | ) | |
524 | { | |
525 | BIO *BioCert; | |
526 | X509 *Cert; | |
527 | EFI_STATUS Status; | |
528 | TLS_CONNECTION *TlsConn; | |
529 | ||
530 | BioCert = NULL; | |
531 | Cert = NULL; | |
532 | Status = EFI_SUCCESS; | |
533 | TlsConn = (TLS_CONNECTION *) Tls; | |
534 | ||
535 | if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) { | |
536 | return EFI_INVALID_PARAMETER; | |
537 | } | |
538 | ||
539 | // | |
540 | // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate. | |
541 | // Determine whether certificate is from DER encoding, if so, translate it to X509 structure. | |
542 | // | |
543 | Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize); | |
544 | if (Cert == NULL) { | |
545 | // | |
546 | // Certificate is from PEM encoding. | |
547 | // | |
548 | BioCert = BIO_new (BIO_s_mem ()); | |
549 | if (BioCert == NULL) { | |
550 | Status = EFI_OUT_OF_RESOURCES; | |
551 | goto ON_EXIT; | |
552 | } | |
553 | ||
554 | if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) { | |
555 | Status = EFI_ABORTED; | |
556 | goto ON_EXIT; | |
557 | } | |
558 | ||
559 | Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL); | |
560 | if (Cert == NULL) { | |
561 | Status = EFI_ABORTED; | |
562 | goto ON_EXIT; | |
563 | } | |
564 | } | |
565 | ||
566 | if (SSL_use_certificate (TlsConn->Ssl, Cert) != 1) { | |
567 | Status = EFI_ABORTED; | |
568 | goto ON_EXIT; | |
569 | } | |
570 | ||
571 | ON_EXIT: | |
572 | if (BioCert != NULL) { | |
573 | BIO_free (BioCert); | |
574 | } | |
575 | ||
576 | if (Cert != NULL) { | |
577 | X509_free (Cert); | |
578 | } | |
579 | ||
580 | return Status; | |
581 | } | |
582 | ||
583 | /** | |
584 | Adds the local private key to the specified TLS object. | |
585 | ||
586 | This function adds the local private key (PEM-encoded RSA or PKCS#8 private | |
587 | key) into the specified TLS object for TLS negotiation. | |
588 | ||
589 | @param[in] Tls Pointer to the TLS object. | |
590 | @param[in] Data Pointer to the data buffer of a PEM-encoded RSA | |
591 | or PKCS#8 private key. | |
592 | @param[in] DataSize The size of data buffer in bytes. | |
593 | ||
594 | @retval EFI_SUCCESS The operation succeeded. | |
595 | @retval EFI_UNSUPPORTED This function is not supported. | |
596 | @retval EFI_ABORTED Invalid private key data. | |
597 | ||
598 | **/ | |
599 | EFI_STATUS | |
600 | EFIAPI | |
601 | TlsSetHostPrivateKey ( | |
602 | IN VOID *Tls, | |
603 | IN VOID *Data, | |
604 | IN UINTN DataSize | |
605 | ) | |
606 | { | |
607 | return EFI_UNSUPPORTED; | |
608 | } | |
609 | ||
610 | /** | |
611 | Adds the CA-supplied certificate revocation list for certificate validation. | |
612 | ||
613 | This function adds the CA-supplied certificate revocation list data for | |
614 | certificate validity checking. | |
615 | ||
616 | @param[in] Data Pointer to the data buffer of a DER-encoded CRL data. | |
617 | @param[in] DataSize The size of data buffer in bytes. | |
618 | ||
619 | @retval EFI_SUCCESS The operation succeeded. | |
620 | @retval EFI_UNSUPPORTED This function is not supported. | |
621 | @retval EFI_ABORTED Invalid CRL data. | |
622 | ||
623 | **/ | |
624 | EFI_STATUS | |
625 | EFIAPI | |
626 | TlsSetCertRevocationList ( | |
627 | IN VOID *Data, | |
628 | IN UINTN DataSize | |
629 | ) | |
630 | { | |
631 | return EFI_UNSUPPORTED; | |
632 | } | |
633 | ||
634 | /** | |
635 | Gets the protocol version used by the specified TLS connection. | |
636 | ||
637 | This function returns the protocol version used by the specified TLS | |
638 | connection. | |
639 | ||
640 | @param[in] Tls Pointer to the TLS object. | |
641 | ||
642 | @return The protocol version of the specified TLS connection. | |
643 | ||
644 | **/ | |
645 | UINT16 | |
646 | EFIAPI | |
647 | TlsGetVersion ( | |
648 | IN VOID *Tls | |
649 | ) | |
650 | { | |
651 | TLS_CONNECTION *TlsConn; | |
652 | ||
653 | TlsConn = (TLS_CONNECTION *) Tls; | |
654 | ||
655 | ASSERT (TlsConn != NULL); | |
656 | ||
657 | return (UINT16)(SSL_version (TlsConn->Ssl)); | |
658 | } | |
659 | ||
660 | /** | |
661 | Gets the connection end of the specified TLS connection. | |
662 | ||
663 | This function returns the connection end (as client or as server) used by | |
664 | the specified TLS connection. | |
665 | ||
666 | @param[in] Tls Pointer to the TLS object. | |
667 | ||
668 | @return The connection end used by the specified TLS connection. | |
669 | ||
670 | **/ | |
671 | UINT8 | |
672 | EFIAPI | |
673 | TlsGetConnectionEnd ( | |
674 | IN VOID *Tls | |
675 | ) | |
676 | { | |
677 | TLS_CONNECTION *TlsConn; | |
678 | ||
679 | TlsConn = (TLS_CONNECTION *) Tls; | |
680 | ||
681 | ASSERT (TlsConn != NULL); | |
682 | ||
683 | return (UINT8)SSL_is_server (TlsConn->Ssl); | |
684 | } | |
685 | ||
686 | /** | |
687 | Gets the cipher suite used by the specified TLS connection. | |
688 | ||
689 | This function returns current cipher suite used by the specified | |
690 | TLS connection. | |
691 | ||
692 | @param[in] Tls Pointer to the TLS object. | |
693 | @param[in,out] CipherId The cipher suite used by the TLS object. | |
694 | ||
695 | @retval EFI_SUCCESS The cipher suite was returned successfully. | |
696 | @retval EFI_INVALID_PARAMETER The parameter is invalid. | |
697 | @retval EFI_UNSUPPORTED Unsupported cipher suite. | |
698 | ||
699 | **/ | |
700 | EFI_STATUS | |
701 | EFIAPI | |
702 | TlsGetCurrentCipher ( | |
703 | IN VOID *Tls, | |
704 | IN OUT UINT16 *CipherId | |
705 | ) | |
706 | { | |
707 | TLS_CONNECTION *TlsConn; | |
708 | CONST SSL_CIPHER *Cipher; | |
709 | ||
710 | TlsConn = (TLS_CONNECTION *) Tls; | |
711 | Cipher = NULL; | |
712 | ||
713 | if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) { | |
714 | return EFI_INVALID_PARAMETER; | |
715 | } | |
716 | ||
717 | Cipher = SSL_get_current_cipher (TlsConn->Ssl); | |
718 | if (Cipher == NULL) { | |
719 | return EFI_UNSUPPORTED; | |
720 | } | |
721 | ||
722 | *CipherId = (SSL_CIPHER_get_id (Cipher)) & 0xFFFF; | |
723 | ||
724 | return EFI_SUCCESS; | |
725 | } | |
726 | ||
727 | /** | |
728 | Gets the compression methods used by the specified TLS connection. | |
729 | ||
730 | This function returns current integrated compression methods used by | |
731 | the specified TLS connection. | |
732 | ||
733 | @param[in] Tls Pointer to the TLS object. | |
734 | @param[in,out] CompressionId The current compression method used by | |
735 | the TLS object. | |
736 | ||
737 | @retval EFI_SUCCESS The compression method was returned successfully. | |
738 | @retval EFI_INVALID_PARAMETER The parameter is invalid. | |
739 | @retval EFI_ABORTED Invalid Compression method. | |
740 | @retval EFI_UNSUPPORTED This function is not supported. | |
741 | ||
742 | **/ | |
743 | EFI_STATUS | |
744 | EFIAPI | |
745 | TlsGetCurrentCompressionId ( | |
746 | IN VOID *Tls, | |
747 | IN OUT UINT8 *CompressionId | |
748 | ) | |
749 | { | |
750 | return EFI_UNSUPPORTED; | |
751 | } | |
752 | ||
753 | /** | |
754 | Gets the verification mode currently set in the TLS connection. | |
755 | ||
756 | This function returns the peer verification mode currently set in the | |
757 | specified TLS connection. | |
758 | ||
759 | @param[in] Tls Pointer to the TLS object. | |
760 | ||
761 | @return The verification mode set in the specified TLS connection. | |
762 | ||
763 | **/ | |
764 | UINT32 | |
765 | EFIAPI | |
766 | TlsGetVerify ( | |
767 | IN VOID *Tls | |
768 | ) | |
769 | { | |
770 | TLS_CONNECTION *TlsConn; | |
771 | ||
772 | TlsConn = (TLS_CONNECTION *) Tls; | |
773 | ||
774 | ASSERT (TlsConn != NULL); | |
775 | ||
776 | return SSL_get_verify_mode (TlsConn->Ssl); | |
777 | } | |
778 | ||
779 | /** | |
780 | Gets the session ID used by the specified TLS connection. | |
781 | ||
782 | This function returns the TLS/SSL session ID currently used by the | |
783 | specified TLS connection. | |
784 | ||
785 | @param[in] Tls Pointer to the TLS object. | |
786 | @param[in,out] SessionId Buffer to contain the returned session ID. | |
787 | @param[in,out] SessionIdLen The length of Session ID in bytes. | |
788 | ||
789 | @retval EFI_SUCCESS The Session ID was returned successfully. | |
790 | @retval EFI_INVALID_PARAMETER The parameter is invalid. | |
791 | @retval EFI_UNSUPPORTED Invalid TLS/SSL session. | |
792 | ||
793 | **/ | |
794 | EFI_STATUS | |
795 | EFIAPI | |
796 | TlsGetSessionId ( | |
797 | IN VOID *Tls, | |
798 | IN OUT UINT8 *SessionId, | |
799 | IN OUT UINT16 *SessionIdLen | |
800 | ) | |
801 | { | |
802 | TLS_CONNECTION *TlsConn; | |
803 | SSL_SESSION *Session; | |
804 | CONST UINT8 *SslSessionId; | |
805 | ||
806 | TlsConn = (TLS_CONNECTION *) Tls; | |
807 | Session = NULL; | |
808 | ||
809 | if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL || SessionIdLen == NULL) { | |
810 | return EFI_INVALID_PARAMETER; | |
811 | } | |
812 | ||
813 | Session = SSL_get_session (TlsConn->Ssl); | |
814 | if (Session == NULL) { | |
815 | return EFI_UNSUPPORTED; | |
816 | } | |
817 | ||
818 | SslSessionId = SSL_SESSION_get_id (Session, (unsigned int *)SessionIdLen); | |
819 | CopyMem (SessionId, SslSessionId, *SessionIdLen); | |
820 | ||
821 | return EFI_SUCCESS; | |
822 | } | |
823 | ||
824 | /** | |
825 | Gets the client random data used in the specified TLS connection. | |
826 | ||
827 | This function returns the TLS/SSL client random data currently used in | |
828 | the specified TLS connection. | |
829 | ||
830 | @param[in] Tls Pointer to the TLS object. | |
831 | @param[in,out] ClientRandom Buffer to contain the returned client | |
832 | random data (32 bytes). | |
833 | ||
834 | **/ | |
835 | VOID | |
836 | EFIAPI | |
837 | TlsGetClientRandom ( | |
838 | IN VOID *Tls, | |
839 | IN OUT UINT8 *ClientRandom | |
840 | ) | |
841 | { | |
842 | TLS_CONNECTION *TlsConn; | |
843 | ||
844 | TlsConn = (TLS_CONNECTION *) Tls; | |
845 | ||
846 | if (TlsConn == NULL || TlsConn->Ssl == NULL || ClientRandom == NULL) { | |
847 | return; | |
848 | } | |
849 | ||
850 | CopyMem (ClientRandom, TlsConn->Ssl->s3->client_random, SSL3_RANDOM_SIZE); | |
851 | } | |
852 | ||
853 | /** | |
854 | Gets the server random data used in the specified TLS connection. | |
855 | ||
856 | This function returns the TLS/SSL server random data currently used in | |
857 | the specified TLS connection. | |
858 | ||
859 | @param[in] Tls Pointer to the TLS object. | |
860 | @param[in,out] ServerRandom Buffer to contain the returned server | |
861 | random data (32 bytes). | |
862 | ||
863 | **/ | |
864 | VOID | |
865 | EFIAPI | |
866 | TlsGetServerRandom ( | |
867 | IN VOID *Tls, | |
868 | IN OUT UINT8 *ServerRandom | |
869 | ) | |
870 | { | |
871 | TLS_CONNECTION *TlsConn; | |
872 | ||
873 | TlsConn = (TLS_CONNECTION *) Tls; | |
874 | ||
875 | if (TlsConn == NULL || TlsConn->Ssl == NULL || ServerRandom == NULL) { | |
876 | return; | |
877 | } | |
878 | ||
879 | CopyMem (ServerRandom, TlsConn->Ssl->s3->server_random, SSL3_RANDOM_SIZE); | |
880 | } | |
881 | ||
882 | /** | |
883 | Gets the master key data used in the specified TLS connection. | |
884 | ||
885 | This function returns the TLS/SSL master key material currently used in | |
886 | the specified TLS connection. | |
887 | ||
888 | @param[in] Tls Pointer to the TLS object. | |
889 | @param[in,out] KeyMaterial Buffer to contain the returned key material. | |
890 | ||
891 | @retval EFI_SUCCESS Key material was returned successfully. | |
892 | @retval EFI_INVALID_PARAMETER The parameter is invalid. | |
893 | @retval EFI_UNSUPPORTED Invalid TLS/SSL session. | |
894 | ||
895 | **/ | |
896 | EFI_STATUS | |
897 | EFIAPI | |
898 | TlsGetKeyMaterial ( | |
899 | IN VOID *Tls, | |
900 | IN OUT UINT8 *KeyMaterial | |
901 | ) | |
902 | { | |
903 | TLS_CONNECTION *TlsConn; | |
904 | SSL_SESSION *Session; | |
905 | ||
906 | TlsConn = (TLS_CONNECTION *) Tls; | |
907 | Session = NULL; | |
908 | ||
909 | if (TlsConn == NULL || TlsConn->Ssl == NULL || KeyMaterial == NULL) { | |
910 | return EFI_INVALID_PARAMETER; | |
911 | } | |
912 | ||
913 | Session = SSL_get_session (TlsConn->Ssl); | |
914 | ||
915 | if (Session == NULL) { | |
916 | return EFI_UNSUPPORTED; | |
917 | } | |
918 | ||
919 | CopyMem (KeyMaterial, Session->master_key, Session->master_key_length); | |
920 | ||
921 | return EFI_SUCCESS; | |
922 | } | |
923 | ||
924 | /** | |
925 | Gets the CA Certificate from the cert store. | |
926 | ||
927 | This function returns the CA certificate for the chosen | |
928 | TLS connection. | |
929 | ||
930 | @param[in] Tls Pointer to the TLS object. | |
931 | @param[out] Data Pointer to the data buffer to receive the CA | |
932 | certificate data sent to the client. | |
933 | @param[in,out] DataSize The size of data buffer in bytes. | |
934 | ||
935 | @retval EFI_SUCCESS The operation succeeded. | |
936 | @retval EFI_UNSUPPORTED This function is not supported. | |
937 | @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data. | |
938 | ||
939 | **/ | |
940 | EFI_STATUS | |
941 | EFIAPI | |
942 | TlsGetCaCertificate ( | |
943 | IN VOID *Tls, | |
944 | OUT VOID *Data, | |
945 | IN OUT UINTN *DataSize | |
946 | ) | |
947 | { | |
948 | return EFI_UNSUPPORTED; | |
949 | } | |
950 | ||
951 | /** | |
952 | Gets the local public Certificate set in the specified TLS object. | |
953 | ||
954 | This function returns the local public certificate which was currently set | |
955 | in the specified TLS object. | |
956 | ||
957 | @param[in] Tls Pointer to the TLS object. | |
958 | @param[out] Data Pointer to the data buffer to receive the local | |
959 | public certificate. | |
960 | @param[in,out] DataSize The size of data buffer in bytes. | |
961 | ||
962 | @retval EFI_SUCCESS The operation succeeded. | |
963 | @retval EFI_INVALID_PARAMETER The parameter is invalid. | |
964 | @retval EFI_NOT_FOUND The certificate is not found. | |
965 | @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data. | |
966 | ||
967 | **/ | |
968 | EFI_STATUS | |
969 | EFIAPI | |
970 | TlsGetHostPublicCert ( | |
971 | IN VOID *Tls, | |
972 | OUT VOID *Data, | |
973 | IN OUT UINTN *DataSize | |
974 | ) | |
975 | { | |
976 | X509 *Cert; | |
977 | TLS_CONNECTION *TlsConn; | |
978 | ||
979 | Cert = NULL; | |
980 | TlsConn = (TLS_CONNECTION *) Tls; | |
981 | ||
982 | if (TlsConn == NULL || TlsConn->Ssl == NULL || DataSize == NULL) { | |
983 | return EFI_INVALID_PARAMETER; | |
984 | } | |
985 | ||
986 | Cert = SSL_get_certificate(TlsConn->Ssl); | |
987 | if (Cert == NULL) { | |
988 | return EFI_NOT_FOUND; | |
989 | } | |
990 | ||
991 | // | |
992 | // Only DER encoding is supported currently. | |
993 | // | |
994 | if (*DataSize < (UINTN) i2d_X509 (Cert, NULL)) { | |
995 | *DataSize = (UINTN) i2d_X509 (Cert, NULL); | |
996 | return EFI_BUFFER_TOO_SMALL; | |
997 | } | |
998 | ||
999 | *DataSize = (UINTN) i2d_X509 (Cert, (unsigned char **) &Data); | |
1000 | ||
1001 | return EFI_SUCCESS; | |
1002 | } | |
1003 | ||
1004 | /** | |
1005 | Gets the local private key set in the specified TLS object. | |
1006 | ||
1007 | This function returns the local private key data which was currently set | |
1008 | in the specified TLS object. | |
1009 | ||
1010 | @param[in] Tls Pointer to the TLS object. | |
1011 | @param[out] Data Pointer to the data buffer to receive the local | |
1012 | private key data. | |
1013 | @param[in,out] DataSize The size of data buffer in bytes. | |
1014 | ||
1015 | @retval EFI_SUCCESS The operation succeeded. | |
1016 | @retval EFI_UNSUPPORTED This function is not supported. | |
1017 | @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data. | |
1018 | ||
1019 | **/ | |
1020 | EFI_STATUS | |
1021 | EFIAPI | |
1022 | TlsGetHostPrivateKey ( | |
1023 | IN VOID *Tls, | |
1024 | OUT VOID *Data, | |
1025 | IN OUT UINTN *DataSize | |
1026 | ) | |
1027 | { | |
1028 | return EFI_UNSUPPORTED; | |
1029 | } | |
1030 | ||
1031 | /** | |
1032 | Gets the CA-supplied certificate revocation list data set in the specified | |
1033 | TLS object. | |
1034 | ||
1035 | This function returns the CA-supplied certificate revocation list data which | |
1036 | was currently set in the specified TLS object. | |
1037 | ||
1038 | @param[out] Data Pointer to the data buffer to receive the CRL data. | |
1039 | @param[in,out] DataSize The size of data buffer in bytes. | |
1040 | ||
1041 | @retval EFI_SUCCESS The operation succeeded. | |
1042 | @retval EFI_UNSUPPORTED This function is not supported. | |
1043 | @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data. | |
1044 | ||
1045 | **/ | |
1046 | EFI_STATUS | |
1047 | EFIAPI | |
1048 | TlsGetCertRevocationList ( | |
1049 | OUT VOID *Data, | |
1050 | IN OUT UINTN *DataSize | |
1051 | ) | |
1052 | { | |
1053 | return EFI_UNSUPPORTED; | |
1054 | } |