• 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 "async_wrap.h"
30 #include "stream_wrap.h"
31 #include "v8.h"
32 
33 #include <openssl/ssl.h>
34 
35 #include <string>
36 
37 namespace node {
38 
39 // Forward-declarations
40 class Environment;
41 class WriteWrap;
42 namespace crypto {
43 class SecureContext;
44 class NodeBIO;
45 }
46 
47 class TLSWrap : public AsyncWrap,
48                 public crypto::SSLWrap<TLSWrap>,
49                 public StreamBase,
50                 public StreamListener {
51  public:
52   ~TLSWrap() override;
53 
54   static void Initialize(v8::Local<v8::Object> target,
55                          v8::Local<v8::Value> unused,
56                          v8::Local<v8::Context> context,
57                          void* priv);
58 
59   // Implement StreamBase:
60   bool IsAlive() override;
61   bool IsClosing() override;
62   bool IsIPCPipe() override;
63   int GetFD() override;
64   ShutdownWrap* CreateShutdownWrap(
65       v8::Local<v8::Object> req_wrap_object) override;
66   AsyncWrap* GetAsyncWrap() override;
67 
68 
69   // Implement StreamResource:
70   int ReadStart() override;  // Exposed to JS
71   int ReadStop() override;   // Exposed to JS
72   int DoShutdown(ShutdownWrap* req_wrap) override;
73   int DoWrite(WriteWrap* w,
74               uv_buf_t* bufs,
75               size_t count,
76               uv_stream_t* send_handle) override;
77   // Return error_ string or nullptr if it's empty.
78   const char* Error() const override;
79   // Reset error_ string to empty. Not related to "clear text".
80   void ClearError() override;
81 
82 
83   // Called by the done() callback of the 'newSession' event.
84   void NewSessionDoneCb();
85 
86   // Implement MemoryRetainer:
87   void MemoryInfo(MemoryTracker* tracker) const override;
88   SET_MEMORY_INFO_NAME(TLSWrap)
89   SET_SELF_SIZE(TLSWrap)
90 
91   std::string diagnostic_name() const override;
92 
93  protected:
94   // Alternative to StreamListener::stream(), that returns a StreamBase instead
95   // of a StreamResource.
underlying_stream()96   inline StreamBase* underlying_stream() {
97     return static_cast<StreamBase*>(stream_);
98   }
99 
100   static const int kClearOutChunkSize = 16384;
101 
102   // Maximum number of bytes for hello parser
103   static const int kMaxHelloLength = 16384;
104 
105   // Usual ServerHello + Certificate size
106   static const int kInitialClientBufferLength = 4096;
107 
108   // Maximum number of buffers passed to uv_write()
109   static const int kSimultaneousBufferCount = 10;
110 
111   TLSWrap(Environment* env,
112           v8::Local<v8::Object> obj,
113           Kind kind,
114           StreamBase* stream,
115           crypto::SecureContext* sc);
116 
117   static void SSLInfoCallback(const SSL* ssl_, int where, int ret);
118   void InitSSL();
119   // SSL has a "clear" text (unencrypted) side (to/from the node API) and
120   // encrypted ("enc") text side (to/from the underlying socket/stream).
121   // On each side data flows "in" or "out" of SSL context.
122   //
123   // EncIn() doesn't exist. Encrypted data is pushed from underlying stream into
124   // enc_in_ via the stream listener's OnStreamAlloc()/OnStreamRead() interface.
125   void EncOut();  // Write encrypted data from enc_out_ to underlying stream.
126   void ClearIn();  // SSL_write() clear data "in" to SSL.
127   void ClearOut();  // SSL_read() clear text "out" from SSL.
128 
129   // Call Done() on outstanding WriteWrap request.
130   bool InvokeQueued(int status, const char* error_str = nullptr);
131 
132   // Drive the SSL state machine by attempting to SSL_read() and SSL_write() to
133   // it. Transparent handshakes mean SSL_read() might trigger I/O on the
134   // underlying stream even if there is no clear text to read or write.
Cycle()135   inline void Cycle() {
136     // Prevent recursion
137     if (++cycle_depth_ > 1)
138       return;
139 
140     for (; cycle_depth_ > 0; cycle_depth_--) {
141       ClearIn();
142       ClearOut();
143       // EncIn() doesn't exist, it happens via stream listener callbacks.
144       EncOut();
145     }
146   }
147 
148   // Implement StreamListener:
149   // Returns buf that points into enc_in_.
150   uv_buf_t OnStreamAlloc(size_t size) override;
151   void OnStreamRead(ssize_t nread, const uv_buf_t& buf) override;
152   void OnStreamAfterWrite(WriteWrap* w, int status) override;
153 
154   v8::Local<v8::Value> GetSSLError(int status, int* err, std::string* msg);
155 
156   static void OnClientHelloParseEnd(void* arg);
157   static void Wrap(const v8::FunctionCallbackInfo<v8::Value>& args);
158   static void Receive(const v8::FunctionCallbackInfo<v8::Value>& args);
159   static void Start(const v8::FunctionCallbackInfo<v8::Value>& args);
160   static void SetVerifyMode(const v8::FunctionCallbackInfo<v8::Value>& args);
161   static void EnableSessionCallbacks(
162       const v8::FunctionCallbackInfo<v8::Value>& args);
163   static void EnableKeylogCallback(
164       const v8::FunctionCallbackInfo<v8::Value>& args);
165   static void EnableTrace(const v8::FunctionCallbackInfo<v8::Value>& args);
166   static void EnableCertCb(const v8::FunctionCallbackInfo<v8::Value>& args);
167   static void DestroySSL(const v8::FunctionCallbackInfo<v8::Value>& args);
168   static void GetServername(const v8::FunctionCallbackInfo<v8::Value>& args);
169   static void SetServername(const v8::FunctionCallbackInfo<v8::Value>& args);
170   static int SelectSNIContextCallback(SSL* s, int* ad, void* arg);
171 
172 #ifndef OPENSSL_NO_PSK
173   static void SetPskIdentityHint(
174       const v8::FunctionCallbackInfo<v8::Value>& args);
175   static void EnablePskCallback(
176       const v8::FunctionCallbackInfo<v8::Value>& args);
177   static unsigned int PskServerCallback(SSL* s,
178                                         const char* identity,
179                                         unsigned char* psk,
180                                         unsigned int max_psk_len);
181   static unsigned int PskClientCallback(SSL* s,
182                                         const char* hint,
183                                         char* identity,
184                                         unsigned int max_identity_len,
185                                         unsigned char* psk,
186                                         unsigned int max_psk_len);
187 #endif
188 
189   crypto::SecureContext* sc_;
190   // BIO buffers hold encrypted data.
191   BIO* enc_in_ = nullptr;   // StreamListener fills this for SSL_read().
192   BIO* enc_out_ = nullptr;  // SSL_write()/handshake fills this for EncOut().
193   // Waiting for ClearIn() to pass to SSL_write().
194   AllocatedBuffer pending_cleartext_input_;
195   size_t write_size_ = 0;
196   WriteWrap* current_write_ = nullptr;
197   bool in_dowrite_ = false;
198   WriteWrap* current_empty_write_ = nullptr;
199   bool write_callback_scheduled_ = false;
200   bool started_ = false;
201   bool established_ = false;
202   bool shutdown_ = false;
203   std::string error_;
204   int cycle_depth_ = 0;
205 
206   // If true - delivered EOF to the js-land, either after `close_notify`, or
207   // after the `UV_EOF` on socket.
208   bool eof_ = false;
209 
210  private:
211   static void GetWriteQueueSize(
212       const v8::FunctionCallbackInfo<v8::Value>& info);
213 
214   crypto::BIOPointer bio_trace_;
215 };
216 
217 }  // namespace node
218 
219 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
220 
221 #endif  // SRC_TLS_WRAP_H_
222