• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 #ifndef SRC_TLS_WRAP_H_
23 #define SRC_TLS_WRAP_H_
24 
25 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
26 
27 #include "node_crypto.h"  // SSLWrap
28 
29 #include "allocated_buffer.h"
30 #include "async_wrap.h"
31 #include "stream_wrap.h"
32 #include "v8.h"
33 
34 #include <openssl/ssl.h>
35 
36 #include <string>
37 
38 namespace node {
39 
40 // Forward-declarations
41 class Environment;
42 class WriteWrap;
43 namespace crypto {
44 class SecureContext;
45 class NodeBIO;
46 }
47 
48 class TLSWrap : public AsyncWrap,
49                 public crypto::SSLWrap<TLSWrap>,
50                 public StreamBase,
51                 public StreamListener {
52  public:
53   ~TLSWrap() override;
54 
55   static void Initialize(v8::Local<v8::Object> target,
56                          v8::Local<v8::Value> unused,
57                          v8::Local<v8::Context> context,
58                          void* priv);
59 
60   // Implement StreamBase:
61   bool IsAlive() override;
62   bool IsClosing() override;
63   bool IsIPCPipe() override;
64   int GetFD() override;
65   ShutdownWrap* CreateShutdownWrap(
66       v8::Local<v8::Object> req_wrap_object) override;
67   AsyncWrap* GetAsyncWrap() override;
68 
69 
70   // Implement StreamResource:
71   int ReadStart() override;  // Exposed to JS
72   int ReadStop() override;   // Exposed to JS
73   int DoShutdown(ShutdownWrap* req_wrap) override;
74   int DoWrite(WriteWrap* w,
75               uv_buf_t* bufs,
76               size_t count,
77               uv_stream_t* send_handle) override;
78   // Return error_ string or nullptr if it's empty.
79   const char* Error() const override;
80   // Reset error_ string to empty. Not related to "clear text".
81   void ClearError() override;
82 
83 
84   // Called by the done() callback of the 'newSession' event.
85   void NewSessionDoneCb();
86 
87   // Implement MemoryRetainer:
88   void MemoryInfo(MemoryTracker* tracker) const override;
89   SET_MEMORY_INFO_NAME(TLSWrap)
90   SET_SELF_SIZE(TLSWrap)
91 
92   std::string diagnostic_name() const override;
93 
94  protected:
95   // Alternative to StreamListener::stream(), that returns a StreamBase instead
96   // of a StreamResource.
underlying_stream()97   inline StreamBase* underlying_stream() {
98     return static_cast<StreamBase*>(stream_);
99   }
100 
101   static const int kClearOutChunkSize = 16384;
102 
103   // Maximum number of bytes for hello parser
104   static const int kMaxHelloLength = 16384;
105 
106   // Usual ServerHello + Certificate size
107   static const int kInitialClientBufferLength = 4096;
108 
109   // Maximum number of buffers passed to uv_write()
110   static const int kSimultaneousBufferCount = 10;
111 
112   TLSWrap(Environment* env,
113           v8::Local<v8::Object> obj,
114           Kind kind,
115           StreamBase* stream,
116           crypto::SecureContext* sc);
117 
118   static void SSLInfoCallback(const SSL* ssl_, int where, int ret);
119   void InitSSL();
120   // SSL has a "clear" text (unencrypted) side (to/from the node API) and
121   // encrypted ("enc") text side (to/from the underlying socket/stream).
122   // On each side data flows "in" or "out" of SSL context.
123   //
124   // EncIn() doesn't exist. Encrypted data is pushed from underlying stream into
125   // enc_in_ via the stream listener's OnStreamAlloc()/OnStreamRead() interface.
126   void EncOut();  // Write encrypted data from enc_out_ to underlying stream.
127   void ClearIn();  // SSL_write() clear data "in" to SSL.
128   void ClearOut();  // SSL_read() clear text "out" from SSL.
129 
130   // Call Done() on outstanding WriteWrap request.
131   bool InvokeQueued(int status, const char* error_str = nullptr);
132 
133   // Drive the SSL state machine by attempting to SSL_read() and SSL_write() to
134   // it. Transparent handshakes mean SSL_read() might trigger I/O on the
135   // underlying stream even if there is no clear text to read or write.
Cycle()136   inline void Cycle() {
137     // Prevent recursion
138     if (++cycle_depth_ > 1)
139       return;
140 
141     for (; cycle_depth_ > 0; cycle_depth_--) {
142       ClearIn();
143       ClearOut();
144       // EncIn() doesn't exist, it happens via stream listener callbacks.
145       EncOut();
146     }
147   }
148 
149   // Implement StreamListener:
150   // Returns buf that points into enc_in_.
151   uv_buf_t OnStreamAlloc(size_t size) override;
152   void OnStreamRead(ssize_t nread, const uv_buf_t& buf) override;
153   void OnStreamAfterWrite(WriteWrap* w, int status) override;
154 
155   v8::Local<v8::Value> GetSSLError(int status, int* err, std::string* msg);
156 
157   static void OnClientHelloParseEnd(void* arg);
158   static void Wrap(const v8::FunctionCallbackInfo<v8::Value>& args);
159   static void Receive(const v8::FunctionCallbackInfo<v8::Value>& args);
160   static void Start(const v8::FunctionCallbackInfo<v8::Value>& args);
161   static void SetVerifyMode(const v8::FunctionCallbackInfo<v8::Value>& args);
162   static void EnableSessionCallbacks(
163       const v8::FunctionCallbackInfo<v8::Value>& args);
164   static void EnableKeylogCallback(
165       const v8::FunctionCallbackInfo<v8::Value>& args);
166   static void EnableTrace(const v8::FunctionCallbackInfo<v8::Value>& args);
167   static void EnableCertCb(const v8::FunctionCallbackInfo<v8::Value>& args);
168   static void DestroySSL(const v8::FunctionCallbackInfo<v8::Value>& args);
169   static void GetServername(const v8::FunctionCallbackInfo<v8::Value>& args);
170   static void SetServername(const v8::FunctionCallbackInfo<v8::Value>& args);
171   static int SelectSNIContextCallback(SSL* s, int* ad, void* arg);
172 
173 #ifndef OPENSSL_NO_PSK
174   static void SetPskIdentityHint(
175       const v8::FunctionCallbackInfo<v8::Value>& args);
176   static void EnablePskCallback(
177       const v8::FunctionCallbackInfo<v8::Value>& args);
178   static unsigned int PskServerCallback(SSL* s,
179                                         const char* identity,
180                                         unsigned char* psk,
181                                         unsigned int max_psk_len);
182   static unsigned int PskClientCallback(SSL* s,
183                                         const char* hint,
184                                         char* identity,
185                                         unsigned int max_identity_len,
186                                         unsigned char* psk,
187                                         unsigned int max_psk_len);
188 #endif
189 
190   crypto::SecureContext* sc_;
191   // BIO buffers hold encrypted data.
192   BIO* enc_in_ = nullptr;   // StreamListener fills this for SSL_read().
193   BIO* enc_out_ = nullptr;  // SSL_write()/handshake fills this for EncOut().
194   // Waiting for ClearIn() to pass to SSL_write().
195   AllocatedBuffer pending_cleartext_input_;
196   size_t write_size_ = 0;
197   BaseObjectPtr<AsyncWrap> current_write_;
198   bool in_dowrite_ = false;
199   BaseObjectPtr<AsyncWrap> current_empty_write_;
200   bool write_callback_scheduled_ = false;
201   bool started_ = false;
202   bool established_ = false;
203   bool shutdown_ = false;
204   std::string error_;
205   int cycle_depth_ = 0;
206 
207   // If true - delivered EOF to the js-land, either after `close_notify`, or
208   // after the `UV_EOF` on socket.
209   bool eof_ = false;
210 
211  private:
212   static void GetWriteQueueSize(
213       const v8::FunctionCallbackInfo<v8::Value>& info);
214 
215   crypto::BIOPointer bio_trace_;
216 };
217 
218 }  // namespace node
219 
220 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
221 
222 #endif  // SRC_TLS_WRAP_H_
223