1// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_BIN_SECURE_SOCKET_FILTER_H_
6#define RUNTIME_BIN_SECURE_SOCKET_FILTER_H_
7
8#include <openssl/bio.h>
9#include <openssl/ssl.h>
10#include <openssl/x509.h>
11
12#include "bin/builtin.h"
13#include "bin/reference_counting.h"
14#include "bin/security_context.h"
15#include "platform/utils.h"
16
17namespace dart {
18namespace bin {
19
20/* These are defined in root_certificates.cc. */
21extern const unsigned char* root_certificates_pem;
22extern unsigned int root_certificates_pem_length;
23
24class SSLFilter : public ReferenceCounted<SSLFilter> {
25 public:
26 static void Init();
27 static void Cleanup();
28
29 // These enums must agree with those in sdk/lib/io/secure_socket.dart.
30 enum BufferIndex {
31 kReadPlaintext,
32 kWritePlaintext,
33 kReadEncrypted,
34 kWriteEncrypted,
35 kNumBuffers,
36 kFirstEncrypted = kReadEncrypted
37 };
38
39 static const intptr_t kApproximateSize;
40 static const int kSSLFilterNativeFieldIndex = 0;
41
42 SSLFilter()
43 : callback_error(NULL),
44 ssl_(NULL),
45 socket_side_(NULL),
46 string_start_(NULL),
47 string_length_(NULL),
48 handshake_complete_(NULL),
49 bad_certificate_callback_(NULL),
50 in_handshake_(false),
51 hostname_(NULL) {}
52
53 ~SSLFilter();
54
55 char* hostname() const { return hostname_; }
56 bool is_server() const { return is_server_; }
57 bool is_client() const { return !is_server_; }
58
59 Dart_Handle Init(Dart_Handle dart_this);
60 void Connect(const char* hostname,
61 SSLCertContext* context,
62 bool is_server,
63 bool request_client_certificate,
64 bool require_client_certificate,
65 Dart_Handle protocols_handle);
66 void Destroy();
67 void FreeResources();
68 void Handshake();
69 void GetSelectedProtocol(Dart_NativeArguments args);
70 void Renegotiate(bool use_session_cache,
71 bool request_client_certificate,
72 bool require_client_certificate);
73 void RegisterHandshakeCompleteCallback(Dart_Handle handshake_complete);
74 void RegisterBadCertificateCallback(Dart_Handle callback);
75 Dart_Handle bad_certificate_callback() {
76 return Dart_HandleFromPersistent(bad_certificate_callback_);
77 }
78 int ProcessReadPlaintextBuffer(int start, int end);
79 int ProcessWritePlaintextBuffer(int start, int end);
80 int ProcessReadEncryptedBuffer(int start, int end);
81 int ProcessWriteEncryptedBuffer(int start, int end);
82 bool ProcessAllBuffers(int starts[kNumBuffers],
83 int ends[kNumBuffers],
84 bool in_handshake);
85 Dart_Handle PeerCertificate();
86 static void InitializeLibrary();
87 Dart_Handle callback_error;
88
89 static CObject* ProcessFilterRequest(const CObjectArray& request);
90
91 // The index of the external data field in _ssl that points to the SSLFilter.
92 static int filter_ssl_index;
93
94 private:
95 static const intptr_t kInternalBIOSize;
96 static bool library_initialized_;
97 static Mutex* mutex_; // To protect library initialization.
98
99 SSL* ssl_;
100 BIO* socket_side_;
101
102 uint8_t* buffers_[kNumBuffers];
103 int buffer_size_;
104 int encrypted_buffer_size_;
105 Dart_PersistentHandle string_start_;
106 Dart_PersistentHandle string_length_;
107 Dart_PersistentHandle dart_buffer_objects_[kNumBuffers];
108 Dart_PersistentHandle handshake_complete_;
109 Dart_PersistentHandle bad_certificate_callback_;
110 bool in_handshake_;
111 bool is_server_;
112 char* hostname_;
113
114 static bool IsBufferEncrypted(int i) {
115 return static_cast<BufferIndex>(i) >= kFirstEncrypted;
116 }
117 Dart_Handle InitializeBuffers(Dart_Handle dart_this);
118 void InitializePlatformData();
119
120 DISALLOW_COPY_AND_ASSIGN(SSLFilter);
121};
122
123} // namespace bin
124} // namespace dart
125
126#endif // RUNTIME_BIN_SECURE_SOCKET_FILTER_H_
127