Cuberite
A lightweight, fast and extensible game server for Minecraft
SslContext.cpp
Go to the documentation of this file.
1 
2 // SslContext.cpp
3 
4 // Implements the cSslContext class that holds everything a single SSL context needs to function
5 
6 #include "Globals.h"
7 #include "../mbedTLS++/SslContext.h"
8 #include "../mbedTLS++/SslConfig.h"
9 
10 
11 
12 
13 
14 cSslContext::cSslContext(void) :
15  m_IsValid(false),
16  m_HasHandshaken(false)
17 {
18  mbedtls_ssl_init(&m_Ssl);
19 }
20 
21 
22 
23 
24 
25 cSslContext::~cSslContext()
26 {
27  mbedtls_ssl_free(&m_Ssl);
28 }
29 
30 
31 
32 
33 
34 int cSslContext::Initialize(std::shared_ptr<const cSslConfig> a_Config)
35 {
36  // Check double-initialization:
37  if (m_IsValid)
38  {
39  LOGWARNING("SSL: Double initialization is not supported.");
40  return MBEDTLS_ERR_SSL_BAD_INPUT_DATA; // There is no return value well-suited for this, reuse this one.
41  }
42 
43  // Check the Config:
44  m_Config = std::move(a_Config);
45  if (m_Config == nullptr)
46  {
47  ASSERT(!"Config must not be nullptr");
48  return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
49  }
50 
51  // Apply the configuration to the ssl context
52  int res = mbedtls_ssl_setup(&m_Ssl, m_Config->GetInternal());
53  if (res != 0)
54  {
55  return res;
56  }
57 
58  // Set the io callbacks
59  mbedtls_ssl_set_bio(&m_Ssl, this, SendEncrypted, ReceiveEncrypted, nullptr);
60 
61  m_IsValid = true;
62  return 0;
63 }
64 
65 
66 
67 
68 
69 int cSslContext::Initialize(bool a_IsClient)
70 {
71  if (a_IsClient)
72  {
73  return Initialize(cSslConfig::GetDefaultClientConfig());
74  }
75  else
76  {
77  return Initialize(cSslConfig::GetDefaultServerConfig());
78  }
79 }
80 
81 
82 
83 
84 
85 void cSslContext::SetExpectedPeerName(const std::string_view a_ExpectedPeerName)
86 {
87  ASSERT(m_IsValid); // Call Initialize() first
88  mbedtls_ssl_set_hostname(&m_Ssl, a_ExpectedPeerName.data());
89 }
90 
91 
92 
93 
94 
95 int cSslContext::WritePlain(const void * a_Data, size_t a_NumBytes)
96 {
97  ASSERT(m_IsValid); // Need to call Initialize() first
98  if (!m_HasHandshaken)
99  {
100  int res = Handshake();
101  if (res != 0)
102  {
103  return res;
104  }
105  }
106 
107  return mbedtls_ssl_write(&m_Ssl, static_cast<const unsigned char *>(a_Data), a_NumBytes);
108 }
109 
110 
111 
112 
113 
114 int cSslContext::ReadPlain(void * a_Data, size_t a_MaxBytes)
115 {
116  ASSERT(m_IsValid); // Need to call Initialize() first
117  if (!m_HasHandshaken)
118  {
119  int res = Handshake();
120  if (res != 0)
121  {
122  return res;
123  }
124  }
125 
126  return mbedtls_ssl_read(&m_Ssl, static_cast<unsigned char *>(a_Data), a_MaxBytes);
127 }
128 
129 
130 
131 
132 
133 int cSslContext::Handshake(void)
134 {
135  ASSERT(m_IsValid); // Need to call Initialize() first
136  ASSERT(!m_HasHandshaken); // Must not call twice
137 
138  int res = mbedtls_ssl_handshake(&m_Ssl);
139  if (res == 0)
140  {
141  m_HasHandshaken = true;
142  }
143  return res;
144 }
145 
146 
147 
148 
149 
150 int cSslContext::NotifyClose(void)
151 {
152  return mbedtls_ssl_close_notify(&m_Ssl);
153 }
154 
155 
156 
157 
#define ASSERT(x)
Definition: Globals.h:276
void LOGWARNING(std::string_view a_Format, const Args &... args)
Definition: LoggerSimple.h:67
static std::shared_ptr< const cSslConfig > GetDefaultServerConfig()
Returns the default config for server connections.
Definition: SslConfig.cpp:277
static std::shared_ptr< const cSslConfig > GetDefaultClientConfig()
Returns the default config for client connections.
Definition: SslConfig.cpp:267