1 /** @file
2   SSL/TLS Configuration 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 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 *
TlsGetCipherString(IN UINT16 CipherId)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
TlsSetVersion(IN VOID * Tls,IN UINT8 MajorVer,IN UINT8 MinorVer)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
TlsSetConnectionEnd(IN VOID * Tls,IN BOOLEAN IsServer)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
TlsSetCipherList(IN VOID * Tls,IN UINT16 * CipherId,IN UINTN CipherNum)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
TlsSetCompressionMethod(IN UINT8 CompMethod)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
TlsSetVerify(IN VOID * Tls,IN UINT32 VerifyMode)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
TlsSetSessionId(IN VOID * Tls,IN UINT8 * SessionId,IN UINT16 SessionIdLen)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
TlsSetCaCertificate(IN VOID * Tls,IN VOID * Data,IN UINTN DataSize)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;
425   unsigned long   ErrorCode;
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
TlsSetHostPublicCert(IN VOID * Tls,IN VOID * Data,IN UINTN DataSize)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
TlsSetHostPrivateKey(IN VOID * Tls,IN VOID * Data,IN UINTN DataSize)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
TlsSetCertRevocationList(IN VOID * Data,IN UINTN DataSize)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
TlsGetVersion(IN VOID * Tls)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
TlsGetConnectionEnd(IN VOID * Tls)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
TlsGetCurrentCipher(IN VOID * Tls,IN OUT UINT16 * CipherId)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
TlsGetCurrentCompressionId(IN VOID * Tls,IN OUT UINT8 * CompressionId)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
TlsGetVerify(IN VOID * Tls)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
TlsGetSessionId(IN VOID * Tls,IN OUT UINT8 * SessionId,IN OUT UINT16 * SessionIdLen)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
TlsGetClientRandom(IN VOID * Tls,IN OUT UINT8 * ClientRandom)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
TlsGetServerRandom(IN VOID * Tls,IN OUT UINT8 * ServerRandom)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
TlsGetKeyMaterial(IN VOID * Tls,IN OUT UINT8 * KeyMaterial)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
TlsGetCaCertificate(IN VOID * Tls,OUT VOID * Data,IN OUT UINTN * DataSize)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
TlsGetHostPublicCert(IN VOID * Tls,OUT VOID * Data,IN OUT UINTN * DataSize)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
TlsGetHostPrivateKey(IN VOID * Tls,OUT VOID * Data,IN OUT UINTN * DataSize)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
TlsGetCertRevocationList(OUT VOID * Data,IN OUT UINTN * DataSize)1048 TlsGetCertRevocationList (
1049   OUT    VOID                     *Data,
1050   IN OUT UINTN                    *DataSize
1051   )
1052 {
1053   return EFI_UNSUPPORTED;
1054 }
1055