]> git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/TlsLib/TlsConfig.c
CryptoPkg/TlsLib: TlsSetVerifyHost: parse IP address literals as such (CVE-2019-14553)
[mirror_edk2.git] / CryptoPkg / Library / TlsLib / TlsConfig.c
1 /** @file
2 SSL/TLS Configuration Library Wrapper Implementation over OpenSSL.
3
4 Copyright (c) 2016 - 2018, 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 typedef struct {
13 //
14 // IANA/IETF defined Cipher Suite ID
15 //
16 UINT16 IanaCipher;
17 //
18 // OpenSSL-used Cipher Suite String
19 //
20 CONST CHAR8 *OpensslCipher;
21 //
22 // Length of OpensslCipher
23 //
24 UINTN OpensslCipherLength;
25 } TLS_CIPHER_MAPPING;
26
27 //
28 // Create a TLS_CIPHER_MAPPING initializer from IanaCipher and OpensslCipher so
29 // that OpensslCipherLength is filled in automatically. IanaCipher must be an
30 // integer constant expression, and OpensslCipher must be a string literal.
31 //
32 #define MAP(IanaCipher, OpensslCipher) \
33 { (IanaCipher), (OpensslCipher), sizeof (OpensslCipher) - 1 }
34
35 //
36 // The mapping table between IANA/IETF Cipher Suite definitions and
37 // OpenSSL-used Cipher Suite name.
38 //
39 // Keep the table uniquely sorted by the IanaCipher field, in increasing order.
40 //
41 STATIC CONST TLS_CIPHER_MAPPING TlsCipherMappingTable[] = {
42 MAP ( 0x0001, "NULL-MD5" ), /// TLS_RSA_WITH_NULL_MD5
43 MAP ( 0x0002, "NULL-SHA" ), /// TLS_RSA_WITH_NULL_SHA
44 MAP ( 0x0004, "RC4-MD5" ), /// TLS_RSA_WITH_RC4_128_MD5
45 MAP ( 0x0005, "RC4-SHA" ), /// TLS_RSA_WITH_RC4_128_SHA
46 MAP ( 0x000A, "DES-CBC3-SHA" ), /// TLS_RSA_WITH_3DES_EDE_CBC_SHA, mandatory TLS 1.1
47 MAP ( 0x0016, "DHE-RSA-DES-CBC3-SHA" ), /// TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
48 MAP ( 0x002F, "AES128-SHA" ), /// TLS_RSA_WITH_AES_128_CBC_SHA, mandatory TLS 1.2
49 MAP ( 0x0030, "DH-DSS-AES128-SHA" ), /// TLS_DH_DSS_WITH_AES_128_CBC_SHA
50 MAP ( 0x0031, "DH-RSA-AES128-SHA" ), /// TLS_DH_RSA_WITH_AES_128_CBC_SHA
51 MAP ( 0x0033, "DHE-RSA-AES128-SHA" ), /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA
52 MAP ( 0x0035, "AES256-SHA" ), /// TLS_RSA_WITH_AES_256_CBC_SHA
53 MAP ( 0x0036, "DH-DSS-AES256-SHA" ), /// TLS_DH_DSS_WITH_AES_256_CBC_SHA
54 MAP ( 0x0037, "DH-RSA-AES256-SHA" ), /// TLS_DH_RSA_WITH_AES_256_CBC_SHA
55 MAP ( 0x0039, "DHE-RSA-AES256-SHA" ), /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA
56 MAP ( 0x003B, "NULL-SHA256" ), /// TLS_RSA_WITH_NULL_SHA256
57 MAP ( 0x003C, "AES128-SHA256" ), /// TLS_RSA_WITH_AES_128_CBC_SHA256
58 MAP ( 0x003D, "AES256-SHA256" ), /// TLS_RSA_WITH_AES_256_CBC_SHA256
59 MAP ( 0x003E, "DH-DSS-AES128-SHA256" ), /// TLS_DH_DSS_WITH_AES_128_CBC_SHA256
60 MAP ( 0x003F, "DH-RSA-AES128-SHA256" ), /// TLS_DH_RSA_WITH_AES_128_CBC_SHA256
61 MAP ( 0x0067, "DHE-RSA-AES128-SHA256" ), /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
62 MAP ( 0x0068, "DH-DSS-AES256-SHA256" ), /// TLS_DH_DSS_WITH_AES_256_CBC_SHA256
63 MAP ( 0x0069, "DH-RSA-AES256-SHA256" ), /// TLS_DH_RSA_WITH_AES_256_CBC_SHA256
64 MAP ( 0x006B, "DHE-RSA-AES256-SHA256" ), /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
65 };
66
67 /**
68 Gets the OpenSSL cipher suite mapping for the supplied IANA TLS cipher suite.
69
70 @param[in] CipherId The supplied IANA TLS cipher suite ID.
71
72 @return The corresponding OpenSSL cipher suite mapping if found,
73 NULL otherwise.
74
75 **/
76 STATIC
77 CONST TLS_CIPHER_MAPPING *
78 TlsGetCipherMapping (
79 IN UINT16 CipherId
80 )
81 {
82 INTN Left;
83 INTN Right;
84 INTN Middle;
85
86 //
87 // Binary Search Cipher Mapping Table for IANA-OpenSSL Cipher Translation
88 //
89 Left = 0;
90 Right = ARRAY_SIZE (TlsCipherMappingTable) - 1;
91
92 while (Right >= Left) {
93 Middle = (Left + Right) / 2;
94
95 if (CipherId == TlsCipherMappingTable[Middle].IanaCipher) {
96 //
97 // Translate IANA cipher suite ID to OpenSSL name.
98 //
99 return &TlsCipherMappingTable[Middle];
100 }
101
102 if (CipherId < TlsCipherMappingTable[Middle].IanaCipher) {
103 Right = Middle - 1;
104 } else {
105 Left = Middle + 1;
106 }
107 }
108
109 //
110 // No Cipher Mapping found, return NULL.
111 //
112 return NULL;
113 }
114
115 /**
116 Set a new TLS/SSL method for a particular TLS object.
117
118 This function sets a new TLS/SSL method for a particular TLS object.
119
120 @param[in] Tls Pointer to a TLS object.
121 @param[in] MajorVer Major Version of TLS/SSL Protocol.
122 @param[in] MinorVer Minor Version of TLS/SSL Protocol.
123
124 @retval EFI_SUCCESS The TLS/SSL method was set successfully.
125 @retval EFI_INVALID_PARAMETER The parameter is invalid.
126 @retval EFI_UNSUPPORTED Unsupported TLS/SSL method.
127
128 **/
129 EFI_STATUS
130 EFIAPI
131 TlsSetVersion (
132 IN VOID *Tls,
133 IN UINT8 MajorVer,
134 IN UINT8 MinorVer
135 )
136 {
137 TLS_CONNECTION *TlsConn;
138 UINT16 ProtoVersion;
139
140 TlsConn = (TLS_CONNECTION *)Tls;
141 if (TlsConn == NULL || TlsConn->Ssl == NULL) {
142 return EFI_INVALID_PARAMETER;
143 }
144
145 ProtoVersion = (MajorVer << 8) | MinorVer;
146
147 //
148 // Bound TLS method to the particular specified version.
149 //
150 switch (ProtoVersion) {
151 case TLS1_VERSION:
152 //
153 // TLS 1.0
154 //
155 SSL_set_min_proto_version (TlsConn->Ssl, TLS1_VERSION);
156 SSL_set_max_proto_version (TlsConn->Ssl, TLS1_VERSION);
157 break;
158 case TLS1_1_VERSION:
159 //
160 // TLS 1.1
161 //
162 SSL_set_min_proto_version (TlsConn->Ssl, TLS1_1_VERSION);
163 SSL_set_max_proto_version (TlsConn->Ssl, TLS1_1_VERSION);
164 break;
165 case TLS1_2_VERSION:
166 //
167 // TLS 1.2
168 //
169 SSL_set_min_proto_version (TlsConn->Ssl, TLS1_2_VERSION);
170 SSL_set_max_proto_version (TlsConn->Ssl, TLS1_2_VERSION);
171 break;
172 default:
173 //
174 // Unsupported Protocol Version
175 //
176 return EFI_UNSUPPORTED;
177 }
178
179 return EFI_SUCCESS;;
180 }
181
182 /**
183 Set TLS object to work in client or server mode.
184
185 This function prepares a TLS object to work in client or server mode.
186
187 @param[in] Tls Pointer to a TLS object.
188 @param[in] IsServer Work in server mode.
189
190 @retval EFI_SUCCESS The TLS/SSL work mode was set successfully.
191 @retval EFI_INVALID_PARAMETER The parameter is invalid.
192 @retval EFI_UNSUPPORTED Unsupported TLS/SSL work mode.
193
194 **/
195 EFI_STATUS
196 EFIAPI
197 TlsSetConnectionEnd (
198 IN VOID *Tls,
199 IN BOOLEAN IsServer
200 )
201 {
202 TLS_CONNECTION *TlsConn;
203
204 TlsConn = (TLS_CONNECTION *) Tls;
205 if (TlsConn == NULL || TlsConn->Ssl == NULL) {
206 return EFI_INVALID_PARAMETER;
207 }
208
209 if (!IsServer) {
210 //
211 // Set TLS to work in Client mode.
212 //
213 SSL_set_connect_state (TlsConn->Ssl);
214 } else {
215 //
216 // Set TLS to work in Server mode.
217 // It is unsupported for UEFI version currently.
218 //
219 //SSL_set_accept_state (TlsConn->Ssl);
220 return EFI_UNSUPPORTED;
221 }
222
223 return EFI_SUCCESS;
224 }
225
226 /**
227 Set the ciphers list to be used by the TLS object.
228
229 This function sets the ciphers for use by a specified TLS object.
230
231 @param[in] Tls Pointer to a TLS object.
232 @param[in] CipherId Array of UINT16 cipher identifiers. Each UINT16
233 cipher identifier comes from the TLS Cipher Suite
234 Registry of the IANA, interpreting Byte1 and Byte2
235 in network (big endian) byte order.
236 @param[in] CipherNum The number of cipher in the list.
237
238 @retval EFI_SUCCESS The ciphers list was set successfully.
239 @retval EFI_INVALID_PARAMETER The parameter is invalid.
240 @retval EFI_UNSUPPORTED No supported TLS cipher was found in CipherId.
241 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
242
243 **/
244 EFI_STATUS
245 EFIAPI
246 TlsSetCipherList (
247 IN VOID *Tls,
248 IN UINT16 *CipherId,
249 IN UINTN CipherNum
250 )
251 {
252 TLS_CONNECTION *TlsConn;
253 EFI_STATUS Status;
254 CONST TLS_CIPHER_MAPPING **MappedCipher;
255 UINTN MappedCipherBytes;
256 UINTN MappedCipherCount;
257 UINTN CipherStringSize;
258 UINTN Index;
259 CONST TLS_CIPHER_MAPPING *Mapping;
260 CHAR8 *CipherString;
261 CHAR8 *CipherStringPosition;
262
263 TlsConn = (TLS_CONNECTION *) Tls;
264 if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {
265 return EFI_INVALID_PARAMETER;
266 }
267
268 //
269 // Allocate the MappedCipher array for recording the mappings that we find
270 // for the input IANA identifiers in CipherId.
271 //
272 Status = SafeUintnMult (CipherNum, sizeof (*MappedCipher),
273 &MappedCipherBytes);
274 if (EFI_ERROR (Status)) {
275 return EFI_OUT_OF_RESOURCES;
276 }
277 MappedCipher = AllocatePool (MappedCipherBytes);
278 if (MappedCipher == NULL) {
279 return EFI_OUT_OF_RESOURCES;
280 }
281
282 //
283 // Map the cipher IDs, and count the number of bytes for the full
284 // CipherString.
285 //
286 MappedCipherCount = 0;
287 CipherStringSize = 0;
288 for (Index = 0; Index < CipherNum; Index++) {
289 //
290 // Look up the IANA-to-OpenSSL mapping.
291 //
292 Mapping = TlsGetCipherMapping (CipherId[Index]);
293 if (Mapping == NULL) {
294 DEBUG ((DEBUG_VERBOSE, "%a:%a: skipping CipherId=0x%04x\n",
295 gEfiCallerBaseName, __FUNCTION__, CipherId[Index]));
296 //
297 // Skipping the cipher is valid because CipherId is an ordered
298 // preference list of ciphers, thus we can filter it as long as we
299 // don't change the relative order of elements on it.
300 //
301 continue;
302 }
303 //
304 // Accumulate Mapping->OpensslCipherLength into CipherStringSize. If this
305 // is not the first successful mapping, account for a colon (":") prefix
306 // too.
307 //
308 if (MappedCipherCount > 0) {
309 Status = SafeUintnAdd (CipherStringSize, 1, &CipherStringSize);
310 if (EFI_ERROR (Status)) {
311 Status = EFI_OUT_OF_RESOURCES;
312 goto FreeMappedCipher;
313 }
314 }
315 Status = SafeUintnAdd (CipherStringSize, Mapping->OpensslCipherLength,
316 &CipherStringSize);
317 if (EFI_ERROR (Status)) {
318 Status = EFI_OUT_OF_RESOURCES;
319 goto FreeMappedCipher;
320 }
321 //
322 // Record the mapping.
323 //
324 MappedCipher[MappedCipherCount++] = Mapping;
325 }
326
327 //
328 // Verify that at least one IANA cipher ID could be mapped; account for the
329 // terminating NUL character in CipherStringSize; allocate CipherString.
330 //
331 if (MappedCipherCount == 0) {
332 DEBUG ((DEBUG_ERROR, "%a:%a: no CipherId could be mapped\n",
333 gEfiCallerBaseName, __FUNCTION__));
334 Status = EFI_UNSUPPORTED;
335 goto FreeMappedCipher;
336 }
337 Status = SafeUintnAdd (CipherStringSize, 1, &CipherStringSize);
338 if (EFI_ERROR (Status)) {
339 Status = EFI_OUT_OF_RESOURCES;
340 goto FreeMappedCipher;
341 }
342 CipherString = AllocatePool (CipherStringSize);
343 if (CipherString == NULL) {
344 Status = EFI_OUT_OF_RESOURCES;
345 goto FreeMappedCipher;
346 }
347
348 //
349 // Go over the collected mappings and populate CipherString.
350 //
351 CipherStringPosition = CipherString;
352 for (Index = 0; Index < MappedCipherCount; Index++) {
353 Mapping = MappedCipher[Index];
354 //
355 // Append the colon (":") prefix except for the first mapping, then append
356 // Mapping->OpensslCipher.
357 //
358 if (Index > 0) {
359 *(CipherStringPosition++) = ':';
360 }
361 CopyMem (CipherStringPosition, Mapping->OpensslCipher,
362 Mapping->OpensslCipherLength);
363 CipherStringPosition += Mapping->OpensslCipherLength;
364 }
365
366 //
367 // NUL-terminate CipherString.
368 //
369 *(CipherStringPosition++) = '\0';
370 ASSERT (CipherStringPosition == CipherString + CipherStringSize);
371
372 //
373 // Log CipherString for debugging. CipherString can be very long if the
374 // caller provided a large CipherId array, so log CipherString in segments of
375 // 79 non-newline characters. (MAX_DEBUG_MESSAGE_LENGTH is usually 0x100 in
376 // DebugLib instances.)
377 //
378 DEBUG_CODE (
379 UINTN FullLength;
380 UINTN SegmentLength;
381
382 FullLength = CipherStringSize - 1;
383 DEBUG ((DEBUG_VERBOSE, "%a:%a: CipherString={\n", gEfiCallerBaseName,
384 __FUNCTION__));
385 for (CipherStringPosition = CipherString;
386 CipherStringPosition < CipherString + FullLength;
387 CipherStringPosition += SegmentLength) {
388 SegmentLength = FullLength - (CipherStringPosition - CipherString);
389 if (SegmentLength > 79) {
390 SegmentLength = 79;
391 }
392 DEBUG ((DEBUG_VERBOSE, "%.*a\n", SegmentLength, CipherStringPosition));
393 }
394 DEBUG ((DEBUG_VERBOSE, "}\n"));
395 //
396 // Restore the pre-debug value of CipherStringPosition by skipping over the
397 // trailing NUL.
398 //
399 CipherStringPosition++;
400 ASSERT (CipherStringPosition == CipherString + CipherStringSize);
401 );
402
403 //
404 // Sets the ciphers for use by the Tls object.
405 //
406 if (SSL_set_cipher_list (TlsConn->Ssl, CipherString) <= 0) {
407 Status = EFI_UNSUPPORTED;
408 goto FreeCipherString;
409 }
410
411 Status = EFI_SUCCESS;
412
413 FreeCipherString:
414 FreePool (CipherString);
415
416 FreeMappedCipher:
417 FreePool (MappedCipher);
418
419 return Status;
420 }
421
422 /**
423 Set the compression method for TLS/SSL operations.
424
425 This function handles TLS/SSL integrated compression methods.
426
427 @param[in] CompMethod The compression method ID.
428
429 @retval EFI_SUCCESS The compression method for the communication was
430 set successfully.
431 @retval EFI_UNSUPPORTED Unsupported compression method.
432
433 **/
434 EFI_STATUS
435 EFIAPI
436 TlsSetCompressionMethod (
437 IN UINT8 CompMethod
438 )
439 {
440 COMP_METHOD *Cm;
441 INTN Ret;
442
443 Cm = NULL;
444 Ret = 0;
445
446 if (CompMethod == 0) {
447 //
448 // TLS defines one standard compression method, CompressionMethod.null (0),
449 // which specifies that data exchanged via the record protocol will not be compressed.
450 // So, return EFI_SUCCESS directly (RFC 3749).
451 //
452 return EFI_SUCCESS;
453 } else if (CompMethod == 1) {
454 Cm = COMP_zlib();
455 } else {
456 return EFI_UNSUPPORTED;
457 }
458
459 //
460 // Adds the compression method to the list of available
461 // compression methods.
462 //
463 Ret = SSL_COMP_add_compression_method (CompMethod, Cm);
464 if (Ret != 0) {
465 return EFI_UNSUPPORTED;
466 }
467
468 return EFI_SUCCESS;
469 }
470
471 /**
472 Set peer certificate verification mode for the TLS connection.
473
474 This function sets the verification mode flags for the TLS connection.
475
476 @param[in] Tls Pointer to the TLS object.
477 @param[in] VerifyMode A set of logically or'ed verification mode flags.
478
479 **/
480 VOID
481 EFIAPI
482 TlsSetVerify (
483 IN VOID *Tls,
484 IN UINT32 VerifyMode
485 )
486 {
487 TLS_CONNECTION *TlsConn;
488
489 TlsConn = (TLS_CONNECTION *) Tls;
490 if (TlsConn == NULL || TlsConn->Ssl == NULL) {
491 return;
492 }
493
494 //
495 // Set peer certificate verification parameters with NULL callback.
496 //
497 SSL_set_verify (TlsConn->Ssl, VerifyMode, NULL);
498 }
499
500 /**
501 Set the specified host name to be verified.
502
503 @param[in] Tls Pointer to the TLS object.
504 @param[in] Flags The setting flags during the validation.
505 @param[in] HostName The specified host name to be verified.
506
507 @retval EFI_SUCCESS The HostName setting was set successfully.
508 @retval EFI_INVALID_PARAMETER The parameter is invalid.
509 @retval EFI_ABORTED Invalid HostName setting.
510
511 **/
512 EFI_STATUS
513 EFIAPI
514 TlsSetVerifyHost (
515 IN VOID *Tls,
516 IN UINT32 Flags,
517 IN CHAR8 *HostName
518 )
519 {
520 TLS_CONNECTION *TlsConn;
521 X509_VERIFY_PARAM *VerifyParam;
522 UINTN BinaryAddressSize;
523 UINT8 BinaryAddress[MAX (NS_INADDRSZ, NS_IN6ADDRSZ)];
524 INTN ParamStatus;
525
526 TlsConn = (TLS_CONNECTION *) Tls;
527 if (TlsConn == NULL || TlsConn->Ssl == NULL || HostName == NULL) {
528 return EFI_INVALID_PARAMETER;
529 }
530
531 SSL_set_hostflags(TlsConn->Ssl, Flags);
532
533 VerifyParam = SSL_get0_param (TlsConn->Ssl);
534 ASSERT (VerifyParam != NULL);
535
536 BinaryAddressSize = 0;
537 if (inet_pton (AF_INET6, HostName, BinaryAddress) == 1) {
538 BinaryAddressSize = NS_IN6ADDRSZ;
539 } else if (inet_pton (AF_INET, HostName, BinaryAddress) == 1) {
540 BinaryAddressSize = NS_INADDRSZ;
541 }
542
543 if (BinaryAddressSize > 0) {
544 DEBUG ((DEBUG_VERBOSE, "%a:%a: parsed \"%a\" as an IPv%c address "
545 "literal\n", gEfiCallerBaseName, __FUNCTION__, HostName,
546 (UINTN)((BinaryAddressSize == NS_IN6ADDRSZ) ? '6' : '4')));
547 ParamStatus = X509_VERIFY_PARAM_set1_ip (VerifyParam, BinaryAddress,
548 BinaryAddressSize);
549 } else {
550 ParamStatus = X509_VERIFY_PARAM_set1_host (VerifyParam, HostName, 0);
551 }
552
553 return (ParamStatus == 1) ? EFI_SUCCESS : EFI_ABORTED;
554 }
555
556 /**
557 Sets a TLS/SSL session ID to be used during TLS/SSL connect.
558
559 This function sets a session ID to be used when the TLS/SSL connection is
560 to be established.
561
562 @param[in] Tls Pointer to the TLS object.
563 @param[in] SessionId Session ID data used for session resumption.
564 @param[in] SessionIdLen Length of Session ID in bytes.
565
566 @retval EFI_SUCCESS Session ID was set successfully.
567 @retval EFI_INVALID_PARAMETER The parameter is invalid.
568 @retval EFI_UNSUPPORTED No available session for ID setting.
569
570 **/
571 EFI_STATUS
572 EFIAPI
573 TlsSetSessionId (
574 IN VOID *Tls,
575 IN UINT8 *SessionId,
576 IN UINT16 SessionIdLen
577 )
578 {
579 TLS_CONNECTION *TlsConn;
580 SSL_SESSION *Session;
581
582 TlsConn = (TLS_CONNECTION *) Tls;
583 Session = NULL;
584
585 if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL) {
586 return EFI_INVALID_PARAMETER;
587 }
588
589 Session = SSL_get_session (TlsConn->Ssl);
590 if (Session == NULL) {
591 return EFI_UNSUPPORTED;
592 }
593
594 SSL_SESSION_set1_id (Session, (const unsigned char *)SessionId, SessionIdLen);
595
596 return EFI_SUCCESS;
597 }
598
599 /**
600 Adds the CA to the cert store when requesting Server or Client authentication.
601
602 This function adds the CA certificate to the list of CAs when requesting
603 Server or Client authentication for the chosen TLS connection.
604
605 @param[in] Tls Pointer to the TLS object.
606 @param[in] Data Pointer to the data buffer of a DER-encoded binary
607 X.509 certificate or PEM-encoded X.509 certificate.
608 @param[in] DataSize The size of data buffer in bytes.
609
610 @retval EFI_SUCCESS The operation succeeded.
611 @retval EFI_INVALID_PARAMETER The parameter is invalid.
612 @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.
613 @retval EFI_ABORTED Invalid X.509 certificate.
614
615 **/
616 EFI_STATUS
617 EFIAPI
618 TlsSetCaCertificate (
619 IN VOID *Tls,
620 IN VOID *Data,
621 IN UINTN DataSize
622 )
623 {
624 BIO *BioCert;
625 X509 *Cert;
626 X509_STORE *X509Store;
627 EFI_STATUS Status;
628 TLS_CONNECTION *TlsConn;
629 SSL_CTX *SslCtx;
630 INTN Ret;
631 UINTN ErrorCode;
632
633 BioCert = NULL;
634 Cert = NULL;
635 X509Store = NULL;
636 Status = EFI_SUCCESS;
637 TlsConn = (TLS_CONNECTION *) Tls;
638 Ret = 0;
639
640 if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) {
641 return EFI_INVALID_PARAMETER;
642 }
643
644 //
645 // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
646 // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.
647 //
648 Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize);
649 if (Cert == NULL) {
650 //
651 // Certificate is from PEM encoding.
652 //
653 BioCert = BIO_new (BIO_s_mem ());
654 if (BioCert == NULL) {
655 Status = EFI_OUT_OF_RESOURCES;
656 goto ON_EXIT;
657 }
658
659 if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {
660 Status = EFI_ABORTED;
661 goto ON_EXIT;
662 }
663
664 Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
665 if (Cert == NULL) {
666 Status = EFI_ABORTED;
667 goto ON_EXIT;
668 }
669 }
670
671 SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl);
672 X509Store = SSL_CTX_get_cert_store (SslCtx);
673 if (X509Store == NULL) {
674 Status = EFI_ABORTED;
675 goto ON_EXIT;
676 }
677
678 //
679 // Add certificate to X509 store
680 //
681 Ret = X509_STORE_add_cert (X509Store, Cert);
682 if (Ret != 1) {
683 ErrorCode = ERR_peek_last_error ();
684 //
685 // Ignore "already in table" errors
686 //
687 if (!(ERR_GET_FUNC (ErrorCode) == X509_F_X509_STORE_ADD_CERT &&
688 ERR_GET_REASON (ErrorCode) == X509_R_CERT_ALREADY_IN_HASH_TABLE)) {
689 Status = EFI_ABORTED;
690 goto ON_EXIT;
691 }
692 }
693
694 ON_EXIT:
695 if (BioCert != NULL) {
696 BIO_free (BioCert);
697 }
698
699 if (Cert != NULL) {
700 X509_free (Cert);
701 }
702
703 return Status;
704 }
705
706 /**
707 Loads the local public certificate into the specified TLS object.
708
709 This function loads the X.509 certificate into the specified TLS object
710 for TLS negotiation.
711
712 @param[in] Tls Pointer to the TLS object.
713 @param[in] Data Pointer to the data buffer of a DER-encoded binary
714 X.509 certificate or PEM-encoded X.509 certificate.
715 @param[in] DataSize The size of data buffer in bytes.
716
717 @retval EFI_SUCCESS The operation succeeded.
718 @retval EFI_INVALID_PARAMETER The parameter is invalid.
719 @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.
720 @retval EFI_ABORTED Invalid X.509 certificate.
721
722 **/
723 EFI_STATUS
724 EFIAPI
725 TlsSetHostPublicCert (
726 IN VOID *Tls,
727 IN VOID *Data,
728 IN UINTN DataSize
729 )
730 {
731 BIO *BioCert;
732 X509 *Cert;
733 EFI_STATUS Status;
734 TLS_CONNECTION *TlsConn;
735
736 BioCert = NULL;
737 Cert = NULL;
738 Status = EFI_SUCCESS;
739 TlsConn = (TLS_CONNECTION *) Tls;
740
741 if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) {
742 return EFI_INVALID_PARAMETER;
743 }
744
745 //
746 // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
747 // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.
748 //
749 Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize);
750 if (Cert == NULL) {
751 //
752 // Certificate is from PEM encoding.
753 //
754 BioCert = BIO_new (BIO_s_mem ());
755 if (BioCert == NULL) {
756 Status = EFI_OUT_OF_RESOURCES;
757 goto ON_EXIT;
758 }
759
760 if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {
761 Status = EFI_ABORTED;
762 goto ON_EXIT;
763 }
764
765 Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
766 if (Cert == NULL) {
767 Status = EFI_ABORTED;
768 goto ON_EXIT;
769 }
770 }
771
772 if (SSL_use_certificate (TlsConn->Ssl, Cert) != 1) {
773 Status = EFI_ABORTED;
774 goto ON_EXIT;
775 }
776
777 ON_EXIT:
778 if (BioCert != NULL) {
779 BIO_free (BioCert);
780 }
781
782 if (Cert != NULL) {
783 X509_free (Cert);
784 }
785
786 return Status;
787 }
788
789 /**
790 Adds the local private key to the specified TLS object.
791
792 This function adds the local private key (PEM-encoded RSA or PKCS#8 private
793 key) into the specified TLS object for TLS negotiation.
794
795 @param[in] Tls Pointer to the TLS object.
796 @param[in] Data Pointer to the data buffer of a PEM-encoded RSA
797 or PKCS#8 private key.
798 @param[in] DataSize The size of data buffer in bytes.
799
800 @retval EFI_SUCCESS The operation succeeded.
801 @retval EFI_UNSUPPORTED This function is not supported.
802 @retval EFI_ABORTED Invalid private key data.
803
804 **/
805 EFI_STATUS
806 EFIAPI
807 TlsSetHostPrivateKey (
808 IN VOID *Tls,
809 IN VOID *Data,
810 IN UINTN DataSize
811 )
812 {
813 return EFI_UNSUPPORTED;
814 }
815
816 /**
817 Adds the CA-supplied certificate revocation list for certificate validation.
818
819 This function adds the CA-supplied certificate revocation list data for
820 certificate validity checking.
821
822 @param[in] Data Pointer to the data buffer of a DER-encoded CRL data.
823 @param[in] DataSize The size of data buffer in bytes.
824
825 @retval EFI_SUCCESS The operation succeeded.
826 @retval EFI_UNSUPPORTED This function is not supported.
827 @retval EFI_ABORTED Invalid CRL data.
828
829 **/
830 EFI_STATUS
831 EFIAPI
832 TlsSetCertRevocationList (
833 IN VOID *Data,
834 IN UINTN DataSize
835 )
836 {
837 return EFI_UNSUPPORTED;
838 }
839
840 /**
841 Gets the protocol version used by the specified TLS connection.
842
843 This function returns the protocol version used by the specified TLS
844 connection.
845
846 If Tls is NULL, then ASSERT().
847
848 @param[in] Tls Pointer to the TLS object.
849
850 @return The protocol version of the specified TLS connection.
851
852 **/
853 UINT16
854 EFIAPI
855 TlsGetVersion (
856 IN VOID *Tls
857 )
858 {
859 TLS_CONNECTION *TlsConn;
860
861 TlsConn = (TLS_CONNECTION *) Tls;
862
863 ASSERT (TlsConn != NULL);
864
865 return (UINT16)(SSL_version (TlsConn->Ssl));
866 }
867
868 /**
869 Gets the connection end of the specified TLS connection.
870
871 This function returns the connection end (as client or as server) used by
872 the specified TLS connection.
873
874 If Tls is NULL, then ASSERT().
875
876 @param[in] Tls Pointer to the TLS object.
877
878 @return The connection end used by the specified TLS connection.
879
880 **/
881 UINT8
882 EFIAPI
883 TlsGetConnectionEnd (
884 IN VOID *Tls
885 )
886 {
887 TLS_CONNECTION *TlsConn;
888
889 TlsConn = (TLS_CONNECTION *) Tls;
890
891 ASSERT (TlsConn != NULL);
892
893 return (UINT8)SSL_is_server (TlsConn->Ssl);
894 }
895
896 /**
897 Gets the cipher suite used by the specified TLS connection.
898
899 This function returns current cipher suite used by the specified
900 TLS connection.
901
902 @param[in] Tls Pointer to the TLS object.
903 @param[in,out] CipherId The cipher suite used by the TLS object.
904
905 @retval EFI_SUCCESS The cipher suite was returned successfully.
906 @retval EFI_INVALID_PARAMETER The parameter is invalid.
907 @retval EFI_UNSUPPORTED Unsupported cipher suite.
908
909 **/
910 EFI_STATUS
911 EFIAPI
912 TlsGetCurrentCipher (
913 IN VOID *Tls,
914 IN OUT UINT16 *CipherId
915 )
916 {
917 TLS_CONNECTION *TlsConn;
918 CONST SSL_CIPHER *Cipher;
919
920 TlsConn = (TLS_CONNECTION *) Tls;
921 Cipher = NULL;
922
923 if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {
924 return EFI_INVALID_PARAMETER;
925 }
926
927 Cipher = SSL_get_current_cipher (TlsConn->Ssl);
928 if (Cipher == NULL) {
929 return EFI_UNSUPPORTED;
930 }
931
932 *CipherId = (SSL_CIPHER_get_id (Cipher)) & 0xFFFF;
933
934 return EFI_SUCCESS;
935 }
936
937 /**
938 Gets the compression methods used by the specified TLS connection.
939
940 This function returns current integrated compression methods used by
941 the specified TLS connection.
942
943 @param[in] Tls Pointer to the TLS object.
944 @param[in,out] CompressionId The current compression method used by
945 the TLS object.
946
947 @retval EFI_SUCCESS The compression method was returned successfully.
948 @retval EFI_INVALID_PARAMETER The parameter is invalid.
949 @retval EFI_ABORTED Invalid Compression method.
950 @retval EFI_UNSUPPORTED This function is not supported.
951
952 **/
953 EFI_STATUS
954 EFIAPI
955 TlsGetCurrentCompressionId (
956 IN VOID *Tls,
957 IN OUT UINT8 *CompressionId
958 )
959 {
960 return EFI_UNSUPPORTED;
961 }
962
963 /**
964 Gets the verification mode currently set in the TLS connection.
965
966 This function returns the peer verification mode currently set in the
967 specified TLS connection.
968
969 If Tls is NULL, then ASSERT().
970
971 @param[in] Tls Pointer to the TLS object.
972
973 @return The verification mode set in the specified TLS connection.
974
975 **/
976 UINT32
977 EFIAPI
978 TlsGetVerify (
979 IN VOID *Tls
980 )
981 {
982 TLS_CONNECTION *TlsConn;
983
984 TlsConn = (TLS_CONNECTION *) Tls;
985
986 ASSERT (TlsConn != NULL);
987
988 return SSL_get_verify_mode (TlsConn->Ssl);
989 }
990
991 /**
992 Gets the session ID used by the specified TLS connection.
993
994 This function returns the TLS/SSL session ID currently used by the
995 specified TLS connection.
996
997 @param[in] Tls Pointer to the TLS object.
998 @param[in,out] SessionId Buffer to contain the returned session ID.
999 @param[in,out] SessionIdLen The length of Session ID in bytes.
1000
1001 @retval EFI_SUCCESS The Session ID was returned successfully.
1002 @retval EFI_INVALID_PARAMETER The parameter is invalid.
1003 @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
1004
1005 **/
1006 EFI_STATUS
1007 EFIAPI
1008 TlsGetSessionId (
1009 IN VOID *Tls,
1010 IN OUT UINT8 *SessionId,
1011 IN OUT UINT16 *SessionIdLen
1012 )
1013 {
1014 TLS_CONNECTION *TlsConn;
1015 SSL_SESSION *Session;
1016 CONST UINT8 *SslSessionId;
1017
1018 TlsConn = (TLS_CONNECTION *) Tls;
1019 Session = NULL;
1020
1021 if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL || SessionIdLen == NULL) {
1022 return EFI_INVALID_PARAMETER;
1023 }
1024
1025 Session = SSL_get_session (TlsConn->Ssl);
1026 if (Session == NULL) {
1027 return EFI_UNSUPPORTED;
1028 }
1029
1030 SslSessionId = SSL_SESSION_get_id (Session, (unsigned int *)SessionIdLen);
1031 CopyMem (SessionId, SslSessionId, *SessionIdLen);
1032
1033 return EFI_SUCCESS;
1034 }
1035
1036 /**
1037 Gets the client random data used in the specified TLS connection.
1038
1039 This function returns the TLS/SSL client random data currently used in
1040 the specified TLS connection.
1041
1042 @param[in] Tls Pointer to the TLS object.
1043 @param[in,out] ClientRandom Buffer to contain the returned client
1044 random data (32 bytes).
1045
1046 **/
1047 VOID
1048 EFIAPI
1049 TlsGetClientRandom (
1050 IN VOID *Tls,
1051 IN OUT UINT8 *ClientRandom
1052 )
1053 {
1054 TLS_CONNECTION *TlsConn;
1055
1056 TlsConn = (TLS_CONNECTION *) Tls;
1057
1058 if (TlsConn == NULL || TlsConn->Ssl == NULL || ClientRandom == NULL) {
1059 return;
1060 }
1061
1062 SSL_get_client_random (TlsConn->Ssl, ClientRandom, SSL3_RANDOM_SIZE);
1063 }
1064
1065 /**
1066 Gets the server random data used in the specified TLS connection.
1067
1068 This function returns the TLS/SSL server random data currently used in
1069 the specified TLS connection.
1070
1071 @param[in] Tls Pointer to the TLS object.
1072 @param[in,out] ServerRandom Buffer to contain the returned server
1073 random data (32 bytes).
1074
1075 **/
1076 VOID
1077 EFIAPI
1078 TlsGetServerRandom (
1079 IN VOID *Tls,
1080 IN OUT UINT8 *ServerRandom
1081 )
1082 {
1083 TLS_CONNECTION *TlsConn;
1084
1085 TlsConn = (TLS_CONNECTION *) Tls;
1086
1087 if (TlsConn == NULL || TlsConn->Ssl == NULL || ServerRandom == NULL) {
1088 return;
1089 }
1090
1091 SSL_get_server_random (TlsConn->Ssl, ServerRandom, SSL3_RANDOM_SIZE);
1092 }
1093
1094 /**
1095 Gets the master key data used in the specified TLS connection.
1096
1097 This function returns the TLS/SSL master key material currently used in
1098 the specified TLS connection.
1099
1100 @param[in] Tls Pointer to the TLS object.
1101 @param[in,out] KeyMaterial Buffer to contain the returned key material.
1102
1103 @retval EFI_SUCCESS Key material was returned successfully.
1104 @retval EFI_INVALID_PARAMETER The parameter is invalid.
1105 @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
1106
1107 **/
1108 EFI_STATUS
1109 EFIAPI
1110 TlsGetKeyMaterial (
1111 IN VOID *Tls,
1112 IN OUT UINT8 *KeyMaterial
1113 )
1114 {
1115 TLS_CONNECTION *TlsConn;
1116 SSL_SESSION *Session;
1117
1118 TlsConn = (TLS_CONNECTION *) Tls;
1119 Session = NULL;
1120
1121 if (TlsConn == NULL || TlsConn->Ssl == NULL || KeyMaterial == NULL) {
1122 return EFI_INVALID_PARAMETER;
1123 }
1124
1125 Session = SSL_get_session (TlsConn->Ssl);
1126
1127 if (Session == NULL) {
1128 return EFI_UNSUPPORTED;
1129 }
1130
1131 SSL_SESSION_get_master_key (Session, KeyMaterial, SSL3_MASTER_SECRET_SIZE);
1132
1133 return EFI_SUCCESS;
1134 }
1135
1136 /**
1137 Gets the CA Certificate from the cert store.
1138
1139 This function returns the CA certificate for the chosen
1140 TLS connection.
1141
1142 @param[in] Tls Pointer to the TLS object.
1143 @param[out] Data Pointer to the data buffer to receive the CA
1144 certificate data sent to the client.
1145 @param[in,out] DataSize The size of data buffer in bytes.
1146
1147 @retval EFI_SUCCESS The operation succeeded.
1148 @retval EFI_UNSUPPORTED This function is not supported.
1149 @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
1150
1151 **/
1152 EFI_STATUS
1153 EFIAPI
1154 TlsGetCaCertificate (
1155 IN VOID *Tls,
1156 OUT VOID *Data,
1157 IN OUT UINTN *DataSize
1158 )
1159 {
1160 return EFI_UNSUPPORTED;
1161 }
1162
1163 /**
1164 Gets the local public Certificate set in the specified TLS object.
1165
1166 This function returns the local public certificate which was currently set
1167 in the specified TLS object.
1168
1169 @param[in] Tls Pointer to the TLS object.
1170 @param[out] Data Pointer to the data buffer to receive the local
1171 public certificate.
1172 @param[in,out] DataSize The size of data buffer in bytes.
1173
1174 @retval EFI_SUCCESS The operation succeeded.
1175 @retval EFI_INVALID_PARAMETER The parameter is invalid.
1176 @retval EFI_NOT_FOUND The certificate is not found.
1177 @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
1178
1179 **/
1180 EFI_STATUS
1181 EFIAPI
1182 TlsGetHostPublicCert (
1183 IN VOID *Tls,
1184 OUT VOID *Data,
1185 IN OUT UINTN *DataSize
1186 )
1187 {
1188 X509 *Cert;
1189 TLS_CONNECTION *TlsConn;
1190
1191 Cert = NULL;
1192 TlsConn = (TLS_CONNECTION *) Tls;
1193
1194 if (TlsConn == NULL || TlsConn->Ssl == NULL || DataSize == NULL || (*DataSize != 0 && Data == NULL)) {
1195 return EFI_INVALID_PARAMETER;
1196 }
1197
1198 Cert = SSL_get_certificate(TlsConn->Ssl);
1199 if (Cert == NULL) {
1200 return EFI_NOT_FOUND;
1201 }
1202
1203 //
1204 // Only DER encoding is supported currently.
1205 //
1206 if (*DataSize < (UINTN) i2d_X509 (Cert, NULL)) {
1207 *DataSize = (UINTN) i2d_X509 (Cert, NULL);
1208 return EFI_BUFFER_TOO_SMALL;
1209 }
1210
1211 *DataSize = (UINTN) i2d_X509 (Cert, (unsigned char **) &Data);
1212
1213 return EFI_SUCCESS;
1214 }
1215
1216 /**
1217 Gets the local private key set in the specified TLS object.
1218
1219 This function returns the local private key data which was currently set
1220 in the specified TLS object.
1221
1222 @param[in] Tls Pointer to the TLS object.
1223 @param[out] Data Pointer to the data buffer to receive the local
1224 private key data.
1225 @param[in,out] DataSize The size of data buffer in bytes.
1226
1227 @retval EFI_SUCCESS The operation succeeded.
1228 @retval EFI_UNSUPPORTED This function is not supported.
1229 @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
1230
1231 **/
1232 EFI_STATUS
1233 EFIAPI
1234 TlsGetHostPrivateKey (
1235 IN VOID *Tls,
1236 OUT VOID *Data,
1237 IN OUT UINTN *DataSize
1238 )
1239 {
1240 return EFI_UNSUPPORTED;
1241 }
1242
1243 /**
1244 Gets the CA-supplied certificate revocation list data set in the specified
1245 TLS object.
1246
1247 This function returns the CA-supplied certificate revocation list data which
1248 was currently set in the specified TLS object.
1249
1250 @param[out] Data Pointer to the data buffer to receive the CRL data.
1251 @param[in,out] DataSize The size of data buffer in bytes.
1252
1253 @retval EFI_SUCCESS The operation succeeded.
1254 @retval EFI_UNSUPPORTED This function is not supported.
1255 @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
1256
1257 **/
1258 EFI_STATUS
1259 EFIAPI
1260 TlsGetCertRevocationList (
1261 OUT VOID *Data,
1262 IN OUT UINTN *DataSize
1263 )
1264 {
1265 return EFI_UNSUPPORTED;
1266 }
1267