Flutter Engine
The Flutter Engine
secure_socket_utils.h
Go to the documentation of this file.
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_UTILS_H_
6#define RUNTIME_BIN_SECURE_SOCKET_UTILS_H_
7
8#include <openssl/bio.h>
9#include <openssl/err.h>
10#include <openssl/pkcs12.h>
11#include <openssl/ssl.h>
12#include <openssl/x509.h>
13
14#include "platform/globals.h"
15
16#include "bin/dartutils.h"
18
19namespace dart {
20namespace bin {
21
22const bool SSL_LOG_STATUS = false;
23const bool SSL_LOG_DATA = false;
24const bool SSL_LOG_CERTS = false;
25
27 public:
28 static constexpr int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000;
29
30 static void ThrowIOException(int status,
31 const char* exception_type,
32 const char* message,
33 const SSL* ssl);
34
35 static void CheckStatusSSL(int status,
36 const char* type,
37 const char* message,
38 const SSL* ssl);
39
40 static void CheckStatus(int status, const char* type, const char* message);
41
42 static bool IsCurrentTimeInsideCertValidDateRange(X509* root_cert);
43
44 static bool NoPEMStartLine() {
45 uint32_t last_error = ERR_peek_last_error();
46 return (ERR_GET_LIB(last_error) == ERR_LIB_PEM) &&
47 (ERR_GET_REASON(last_error) == PEM_R_NO_START_LINE);
48 }
49
50 static uint32_t FetchErrorString(const SSL* ssl, TextBuffer* text_buffer);
51};
52
53// Where the argument to the constructor is the handle for an object
54// implementing List<int>, this class creates a scope in which a memory-backed
55// BIO is allocated. Leaving the scope cleans up the BIO and the buffer that
56// was used to create it.
57//
58// Do not make Dart_ API calls while in a ScopedMemBIO.
59// Do not call Dart_PropagateError while in a ScopedMemBIO.
61 public:
62 explicit ScopedMemBIO(Dart_Handle object) {
63 if (!Dart_IsTypedData(object) && !Dart_IsList(object)) {
65 DartUtils::NewDartArgumentError("Argument is not a List<int>"));
66 }
67
68 uint8_t* bytes = nullptr;
69 intptr_t bytes_len = 0;
70 bool is_typed_data = false;
71 if (Dart_IsTypedData(object)) {
72 is_typed_data = true;
75 object, &typ, reinterpret_cast<void**>(&bytes), &bytes_len));
76 } else {
77 ASSERT(Dart_IsList(object));
78 ThrowIfError(Dart_ListLength(object, &bytes_len));
79 bytes = Dart_ScopeAllocate(bytes_len);
80 ASSERT(bytes != nullptr);
81 ThrowIfError(Dart_ListGetAsBytes(object, 0, bytes, bytes_len));
82 }
83
84 object_ = object;
85 bytes_ = bytes;
86 bytes_len_ = bytes_len;
87 bio_ = BIO_new_mem_buf(bytes, bytes_len);
88 ASSERT(bio_ != nullptr);
89 is_typed_data_ = is_typed_data;
90 }
91
93 ASSERT(bio_ != nullptr);
94 if (is_typed_data_) {
95 BIO_free(bio_);
97 } else {
98 BIO_free(bio_);
99 }
100 }
101
102 BIO* bio() {
103 ASSERT(bio_ != nullptr);
104 return bio_;
105 }
106
107 uint8_t* data() { return bytes_; }
108 intptr_t length() { return bytes_len_; }
109
110 private:
111 Dart_Handle object_;
112 uint8_t* bytes_;
113 intptr_t bytes_len_;
114 BIO* bio_;
115 bool is_typed_data_;
116
117 DISALLOW_ALLOCATION();
118 DISALLOW_COPY_AND_ASSIGN(ScopedMemBIO);
119};
120
121template <typename T, void (*free_func)(T*)>
123 public:
124 explicit ScopedSSLType(T* obj) : obj_(obj) {}
125
127 if (obj_ != nullptr) {
128 free_func(obj_);
129 }
130 }
131
132 T* get() { return obj_; }
133 const T* get() const { return obj_; }
134
136 T* result = obj_;
137 obj_ = nullptr;
138 return result;
139 }
140
141 private:
142 T* obj_;
143
144 DISALLOW_ALLOCATION();
145 DISALLOW_COPY_AND_ASSIGN(ScopedSSLType);
146};
147
148template <typename T, typename E, void (*func)(E*)>
150 public:
151 explicit ScopedSSLStackType(T* obj) : obj_(obj) {}
152
154 if (obj_ != nullptr) {
155 OPENSSL_sk_pop_free_ex(reinterpret_cast<OPENSSL_STACK*>(obj_),
156 call_free_func, free_func);
157 }
158 }
159
160 T* get() { return obj_; }
161 const T* get() const { return obj_; }
162
164 T* result = obj_;
165 obj_ = nullptr;
166 return result;
167 }
168
169 private:
170 static void free_func(void* element) { func(reinterpret_cast<E*>(element)); }
171 static void call_free_func(void (*free_func)(void*), void* element) {
172 free_func(element);
173 }
174
175 T* obj_;
176
177 DISALLOW_ALLOCATION();
178 DISALLOW_COPY_AND_ASSIGN(ScopedSSLStackType);
179};
180
183typedef ScopedSSLStackType<STACK_OF(X509), X509, X509_free> ScopedX509Stack;
184
185} // namespace bin
186} // namespace dart
187
188#endif // RUNTIME_BIN_SECURE_SOCKET_UTILS_H_
GLenum type
static Dart_Handle NewDartArgumentError(const char *message)
Definition: dartutils.cc:746
ScopedMemBIO(Dart_Handle object)
static constexpr int SSL_ERROR_MESSAGE_BUFFER_SIZE
static bool IsCurrentTimeInsideCertValidDateRange(X509 *root_cert)
static void ThrowIOException(int status, const char *exception_type, const char *message, const SSL *ssl)
static uint32_t FetchErrorString(const SSL *ssl, TextBuffer *text_buffer)
static void CheckStatusSSL(int status, const char *type, const char *message, const SSL *ssl)
static void CheckStatus(int status, const char *type, const char *message)
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
Dart_TypedData_Type
Definition: dart_api.h:2612
#define ASSERT(E)
GAsyncResult * result
Win32Message message
const bool SSL_LOG_STATUS
static Dart_Handle ThrowIfError(Dart_Handle handle)
Definition: dartutils.h:31
ScopedSSLType< X509, X509_free > ScopedX509
const bool SSL_LOG_DATA
ScopedSSLType< PKCS12, PKCS12_free > ScopedPKCS12
const bool SSL_LOG_CERTS
ScopedSSLStackType< STACK_OF(X509), X509, X509_free > ScopedX509Stack
Definition: dart_vm.cc:33
DART_EXPORT uint8_t * Dart_ScopeAllocate(intptr_t size)
DART_EXPORT Dart_Handle Dart_TypedDataAcquireData(Dart_Handle object, Dart_TypedData_Type *type, void **data, intptr_t *len)
DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list, intptr_t offset, uint8_t *native_array, intptr_t length)
DART_EXPORT Dart_Handle Dart_TypedDataReleaseData(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_ListLength(Dart_Handle list, intptr_t *len)
DART_EXPORT bool Dart_IsList(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception)
DART_EXPORT bool Dart_IsTypedData(Dart_Handle handle)
#define T
Definition: precompiler.cc:65