OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED) | 5 #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED) |
6 | 6 |
7 #include "bin/security_context.h" | 7 #include "bin/security_context.h" |
8 | 8 |
9 #include <openssl/bio.h> | 9 #include <openssl/bio.h> |
10 #include <openssl/err.h> | 10 #include <openssl/err.h> |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 "BadCertificateCallback returned a value that was not a boolean", | 69 "BadCertificateCallback returned a value that was not a boolean", |
70 Dart_Null())); | 70 Dart_Null())); |
71 } | 71 } |
72 if (Dart_IsError(result)) { | 72 if (Dart_IsError(result)) { |
73 filter->callback_error = result; | 73 filter->callback_error = result; |
74 return 0; | 74 return 0; |
75 } | 75 } |
76 return DartUtils::GetBooleanValue(result); | 76 return DartUtils::GetBooleanValue(result); |
77 } | 77 } |
78 | 78 |
79 | |
80 SSLCertContext* SSLCertContext::GetSecurityContext(Dart_NativeArguments args) { | 79 SSLCertContext* SSLCertContext::GetSecurityContext(Dart_NativeArguments args) { |
81 SSLCertContext* context; | 80 SSLCertContext* context; |
82 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 81 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
83 ASSERT(Dart_IsInstance(dart_this)); | 82 ASSERT(Dart_IsInstance(dart_this)); |
84 ThrowIfError(Dart_GetNativeInstanceField( | 83 ThrowIfError(Dart_GetNativeInstanceField( |
85 dart_this, SSLCertContext::kSecurityContextNativeFieldIndex, | 84 dart_this, SSLCertContext::kSecurityContextNativeFieldIndex, |
86 reinterpret_cast<intptr_t*>(&context))); | 85 reinterpret_cast<intptr_t*>(&context))); |
87 return context; | 86 return context; |
88 } | 87 } |
89 | 88 |
90 | |
91 static void DeleteSecurityContext(void* isolate_data, | 89 static void DeleteSecurityContext(void* isolate_data, |
92 Dart_WeakPersistentHandle handle, | 90 Dart_WeakPersistentHandle handle, |
93 void* context_pointer) { | 91 void* context_pointer) { |
94 SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer); | 92 SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer); |
95 context->Release(); | 93 context->Release(); |
96 } | 94 } |
97 | 95 |
98 | |
99 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, | 96 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, |
100 SSLCertContext* context) { | 97 SSLCertContext* context) { |
101 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); | 98 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); |
102 RETURN_IF_ERROR(dart_this); | 99 RETURN_IF_ERROR(dart_this); |
103 ASSERT(Dart_IsInstance(dart_this)); | 100 ASSERT(Dart_IsInstance(dart_this)); |
104 Dart_Handle err = Dart_SetNativeInstanceField( | 101 Dart_Handle err = Dart_SetNativeInstanceField( |
105 dart_this, SSLCertContext::kSecurityContextNativeFieldIndex, | 102 dart_this, SSLCertContext::kSecurityContextNativeFieldIndex, |
106 reinterpret_cast<intptr_t>(context)); | 103 reinterpret_cast<intptr_t>(context)); |
107 RETURN_IF_ERROR(err); | 104 RETURN_IF_ERROR(err); |
108 Dart_NewWeakPersistentHandle(dart_this, context, | 105 Dart_NewWeakPersistentHandle(dart_this, context, |
109 SSLCertContext::kApproximateSize, | 106 SSLCertContext::kApproximateSize, |
110 DeleteSecurityContext); | 107 DeleteSecurityContext); |
111 return Dart_Null(); | 108 return Dart_Null(); |
112 } | 109 } |
113 | 110 |
114 | |
115 static void ReleaseCertificate(void* isolate_data, | 111 static void ReleaseCertificate(void* isolate_data, |
116 Dart_WeakPersistentHandle handle, | 112 Dart_WeakPersistentHandle handle, |
117 void* context_pointer) { | 113 void* context_pointer) { |
118 X509* cert = reinterpret_cast<X509*>(context_pointer); | 114 X509* cert = reinterpret_cast<X509*>(context_pointer); |
119 X509_free(cert); | 115 X509_free(cert); |
120 } | 116 } |
121 | 117 |
122 | |
123 static intptr_t EstimateX509Size(X509* certificate) { | 118 static intptr_t EstimateX509Size(X509* certificate) { |
124 intptr_t length = i2d_X509(certificate, NULL); | 119 intptr_t length = i2d_X509(certificate, NULL); |
125 return length > 0 ? length : 0; | 120 return length > 0 ? length : 0; |
126 } | 121 } |
127 | 122 |
128 | |
129 // Returns the handle for a Dart object wrapping the X509 certificate object. | 123 // Returns the handle for a Dart object wrapping the X509 certificate object. |
130 // The caller should own a reference to the X509 object whose reference count | 124 // The caller should own a reference to the X509 object whose reference count |
131 // won't drop to zero before the ReleaseCertificate finalizer runs. | 125 // won't drop to zero before the ReleaseCertificate finalizer runs. |
132 Dart_Handle X509Helper::WrappedX509Certificate(X509* certificate) { | 126 Dart_Handle X509Helper::WrappedX509Certificate(X509* certificate) { |
133 if (certificate == NULL) { | 127 if (certificate == NULL) { |
134 return Dart_Null(); | 128 return Dart_Null(); |
135 } | 129 } |
136 Dart_Handle x509_type = | 130 Dart_Handle x509_type = |
137 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate"); | 131 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate"); |
138 if (Dart_IsError(x509_type)) { | 132 if (Dart_IsError(x509_type)) { |
(...skipping 17 matching lines...) Expand all Loading... |
156 } | 150 } |
157 const intptr_t approximate_size_of_certificate = | 151 const intptr_t approximate_size_of_certificate = |
158 sizeof(*certificate) + EstimateX509Size(certificate); | 152 sizeof(*certificate) + EstimateX509Size(certificate); |
159 ASSERT(approximate_size_of_certificate > 0); | 153 ASSERT(approximate_size_of_certificate > 0); |
160 Dart_NewWeakPersistentHandle(result, reinterpret_cast<void*>(certificate), | 154 Dart_NewWeakPersistentHandle(result, reinterpret_cast<void*>(certificate), |
161 approximate_size_of_certificate, | 155 approximate_size_of_certificate, |
162 ReleaseCertificate); | 156 ReleaseCertificate); |
163 return result; | 157 return result; |
164 } | 158 } |
165 | 159 |
166 | |
167 static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context, | 160 static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context, |
168 BIO* bio, | 161 BIO* bio, |
169 const char* password) { | 162 const char* password) { |
170 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); | 163 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); |
171 if (p12.get() == NULL) { | 164 if (p12.get() == NULL) { |
172 return 0; | 165 return 0; |
173 } | 166 } |
174 | 167 |
175 EVP_PKEY* key = NULL; | 168 EVP_PKEY* key = NULL; |
176 X509* cert = NULL; | 169 X509* cert = NULL; |
(...skipping 18 matching lines...) Expand all Loading... |
195 // X509_STORE_add_cert increments the reference count of cert on success. | 188 // X509_STORE_add_cert increments the reference count of cert on success. |
196 X509_free(ca); | 189 X509_free(ca); |
197 if (status == 0) { | 190 if (status == 0) { |
198 return status; | 191 return status; |
199 } | 192 } |
200 } | 193 } |
201 | 194 |
202 return status; | 195 return status; |
203 } | 196 } |
204 | 197 |
205 | |
206 static int SetTrustedCertificatesBytesPEM(SSL_CTX* context, BIO* bio) { | 198 static int SetTrustedCertificatesBytesPEM(SSL_CTX* context, BIO* bio) { |
207 X509_STORE* store = SSL_CTX_get_cert_store(context); | 199 X509_STORE* store = SSL_CTX_get_cert_store(context); |
208 | 200 |
209 int status = 0; | 201 int status = 0; |
210 X509* cert = NULL; | 202 X509* cert = NULL; |
211 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { | 203 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { |
212 status = X509_STORE_add_cert(store, cert); | 204 status = X509_STORE_add_cert(store, cert); |
213 // X509_STORE_add_cert increments the reference count of cert on success. | 205 // X509_STORE_add_cert increments the reference count of cert on success. |
214 X509_free(cert); | 206 X509_free(cert); |
215 if (status == 0) { | 207 if (status == 0) { |
216 return status; | 208 return status; |
217 } | 209 } |
218 } | 210 } |
219 | 211 |
220 // If no PEM start line is found, it means that we read to the end of the | 212 // If no PEM start line is found, it means that we read to the end of the |
221 // file, or that the file isn't PEM. In the first case, status will be | 213 // file, or that the file isn't PEM. In the first case, status will be |
222 // non-zero indicating success. In the second case, status will be 0, | 214 // non-zero indicating success. In the second case, status will be 0, |
223 // indicating that we should try to read as PKCS12. If there is some other | 215 // indicating that we should try to read as PKCS12. If there is some other |
224 // error, we return it up to the caller. | 216 // error, we return it up to the caller. |
225 return SecureSocketUtils::NoPEMStartLine() ? status : 0; | 217 return SecureSocketUtils::NoPEMStartLine() ? status : 0; |
226 } | 218 } |
227 | 219 |
228 | |
229 void SSLCertContext::SetTrustedCertificatesBytes(Dart_Handle cert_bytes, | 220 void SSLCertContext::SetTrustedCertificatesBytes(Dart_Handle cert_bytes, |
230 const char* password) { | 221 const char* password) { |
231 int status = 0; | 222 int status = 0; |
232 { | 223 { |
233 ScopedMemBIO bio(cert_bytes); | 224 ScopedMemBIO bio(cert_bytes); |
234 status = SetTrustedCertificatesBytesPEM(context(), bio.bio()); | 225 status = SetTrustedCertificatesBytesPEM(context(), bio.bio()); |
235 if (status == 0) { | 226 if (status == 0) { |
236 if (SecureSocketUtils::NoPEMStartLine()) { | 227 if (SecureSocketUtils::NoPEMStartLine()) { |
237 ERR_clear_error(); | 228 ERR_clear_error(); |
238 BIO_reset(bio.bio()); | 229 BIO_reset(bio.bio()); |
239 status = | 230 status = |
240 SetTrustedCertificatesBytesPKCS12(context(), bio.bio(), password); | 231 SetTrustedCertificatesBytesPKCS12(context(), bio.bio(), password); |
241 } | 232 } |
242 } else { | 233 } else { |
243 // The PEM file was successfully parsed. | 234 // The PEM file was successfully parsed. |
244 ERR_clear_error(); | 235 ERR_clear_error(); |
245 } | 236 } |
246 } | 237 } |
247 SecureSocketUtils::CheckStatus(status, "TlsException", | 238 SecureSocketUtils::CheckStatus(status, "TlsException", |
248 "Failure trusting builtin roots"); | 239 "Failure trusting builtin roots"); |
249 } | 240 } |
250 | 241 |
251 | |
252 static int SetClientAuthoritiesPKCS12(SSL_CTX* context, | 242 static int SetClientAuthoritiesPKCS12(SSL_CTX* context, |
253 BIO* bio, | 243 BIO* bio, |
254 const char* password) { | 244 const char* password) { |
255 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); | 245 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); |
256 if (p12.get() == NULL) { | 246 if (p12.get() == NULL) { |
257 return 0; | 247 return 0; |
258 } | 248 } |
259 | 249 |
260 EVP_PKEY* key = NULL; | 250 EVP_PKEY* key = NULL; |
261 X509* cert = NULL; | 251 X509* cert = NULL; |
(...skipping 17 matching lines...) Expand all Loading... |
279 // SSL_CTX_add_client_CA increments the reference count of ca on success. | 269 // SSL_CTX_add_client_CA increments the reference count of ca on success. |
280 X509_free(ca); // The name has been extracted. | 270 X509_free(ca); // The name has been extracted. |
281 if (status == 0) { | 271 if (status == 0) { |
282 return status; | 272 return status; |
283 } | 273 } |
284 } | 274 } |
285 | 275 |
286 return status; | 276 return status; |
287 } | 277 } |
288 | 278 |
289 | |
290 static int SetClientAuthoritiesPEM(SSL_CTX* context, BIO* bio) { | 279 static int SetClientAuthoritiesPEM(SSL_CTX* context, BIO* bio) { |
291 int status = 0; | 280 int status = 0; |
292 X509* cert = NULL; | 281 X509* cert = NULL; |
293 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { | 282 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { |
294 status = SSL_CTX_add_client_CA(context, cert); | 283 status = SSL_CTX_add_client_CA(context, cert); |
295 X509_free(cert); // The name has been extracted. | 284 X509_free(cert); // The name has been extracted. |
296 if (status == 0) { | 285 if (status == 0) { |
297 return status; | 286 return status; |
298 } | 287 } |
299 } | 288 } |
300 return SecureSocketUtils::NoPEMStartLine() ? status : 0; | 289 return SecureSocketUtils::NoPEMStartLine() ? status : 0; |
301 } | 290 } |
302 | 291 |
303 | |
304 static int SetClientAuthorities(SSL_CTX* context, | 292 static int SetClientAuthorities(SSL_CTX* context, |
305 BIO* bio, | 293 BIO* bio, |
306 const char* password) { | 294 const char* password) { |
307 int status = SetClientAuthoritiesPEM(context, bio); | 295 int status = SetClientAuthoritiesPEM(context, bio); |
308 if (status == 0) { | 296 if (status == 0) { |
309 if (SecureSocketUtils::NoPEMStartLine()) { | 297 if (SecureSocketUtils::NoPEMStartLine()) { |
310 ERR_clear_error(); | 298 ERR_clear_error(); |
311 BIO_reset(bio); | 299 BIO_reset(bio); |
312 status = SetClientAuthoritiesPKCS12(context, bio, password); | 300 status = SetClientAuthoritiesPKCS12(context, bio, password); |
313 } | 301 } |
314 } else { | 302 } else { |
315 // The PEM file was successfully parsed. | 303 // The PEM file was successfully parsed. |
316 ERR_clear_error(); | 304 ERR_clear_error(); |
317 } | 305 } |
318 return status; | 306 return status; |
319 } | 307 } |
320 | 308 |
321 | |
322 void SSLCertContext::SetClientAuthoritiesBytes( | 309 void SSLCertContext::SetClientAuthoritiesBytes( |
323 Dart_Handle client_authorities_bytes, | 310 Dart_Handle client_authorities_bytes, |
324 const char* password) { | 311 const char* password) { |
325 int status; | 312 int status; |
326 { | 313 { |
327 ScopedMemBIO bio(client_authorities_bytes); | 314 ScopedMemBIO bio(client_authorities_bytes); |
328 status = SetClientAuthorities(context(), bio.bio(), password); | 315 status = SetClientAuthorities(context(), bio.bio(), password); |
329 } | 316 } |
330 | 317 |
331 SecureSocketUtils::CheckStatus(status, "TlsException", | 318 SecureSocketUtils::CheckStatus(status, "TlsException", |
332 "Failure in setClientAuthoritiesBytes"); | 319 "Failure in setClientAuthoritiesBytes"); |
333 } | 320 } |
334 | 321 |
335 void SSLCertContext::LoadRootCertFile(const char* file) { | 322 void SSLCertContext::LoadRootCertFile(const char* file) { |
336 if (SSL_LOG_STATUS) { | 323 if (SSL_LOG_STATUS) { |
337 Log::Print("Looking for trusted roots in %s\n", file); | 324 Log::Print("Looking for trusted roots in %s\n", file); |
338 } | 325 } |
339 if (!File::Exists(file)) { | 326 if (!File::Exists(file)) { |
340 SecureSocketUtils::ThrowIOException(-1, "TlsException", | 327 SecureSocketUtils::ThrowIOException(-1, "TlsException", |
341 "Failed to find root cert file", NULL); | 328 "Failed to find root cert file", NULL); |
342 } | 329 } |
343 int status = SSL_CTX_load_verify_locations(context(), file, NULL); | 330 int status = SSL_CTX_load_verify_locations(context(), file, NULL); |
344 SecureSocketUtils::CheckStatus(status, "TlsException", | 331 SecureSocketUtils::CheckStatus(status, "TlsException", |
345 "Failure trusting builtin roots"); | 332 "Failure trusting builtin roots"); |
346 if (SSL_LOG_STATUS) { | 333 if (SSL_LOG_STATUS) { |
347 Log::Print("Trusting roots from: %s\n", file); | 334 Log::Print("Trusting roots from: %s\n", file); |
348 } | 335 } |
349 } | 336 } |
350 | 337 |
351 | |
352 void SSLCertContext::AddCompiledInCerts() { | 338 void SSLCertContext::AddCompiledInCerts() { |
353 if (root_certificates_pem == NULL) { | 339 if (root_certificates_pem == NULL) { |
354 if (SSL_LOG_STATUS) { | 340 if (SSL_LOG_STATUS) { |
355 Log::Print("Missing compiled-in roots\n"); | 341 Log::Print("Missing compiled-in roots\n"); |
356 } | 342 } |
357 return; | 343 return; |
358 } | 344 } |
359 X509_STORE* store = SSL_CTX_get_cert_store(context()); | 345 X509_STORE* store = SSL_CTX_get_cert_store(context()); |
360 BIO* roots_bio = | 346 BIO* roots_bio = |
361 BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem), | 347 BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem), |
(...skipping 10 matching lines...) Expand all Loading... |
372 break; | 358 break; |
373 } | 359 } |
374 } | 360 } |
375 BIO_free(roots_bio); | 361 BIO_free(roots_bio); |
376 // If there is an error here, it must be the error indicating that we are done | 362 // If there is an error here, it must be the error indicating that we are done |
377 // reading PEM certificates. | 363 // reading PEM certificates. |
378 ASSERT((ERR_peek_error() == 0) || SecureSocketUtils::NoPEMStartLine()); | 364 ASSERT((ERR_peek_error() == 0) || SecureSocketUtils::NoPEMStartLine()); |
379 ERR_clear_error(); | 365 ERR_clear_error(); |
380 } | 366 } |
381 | 367 |
382 | |
383 void SSLCertContext::LoadRootCertCache(const char* cache) { | 368 void SSLCertContext::LoadRootCertCache(const char* cache) { |
384 if (SSL_LOG_STATUS) { | 369 if (SSL_LOG_STATUS) { |
385 Log::Print("Looking for trusted roots in %s\n", cache); | 370 Log::Print("Looking for trusted roots in %s\n", cache); |
386 } | 371 } |
387 if (Directory::Exists(cache) != Directory::EXISTS) { | 372 if (Directory::Exists(cache) != Directory::EXISTS) { |
388 SecureSocketUtils::ThrowIOException(-1, "TlsException", | 373 SecureSocketUtils::ThrowIOException(-1, "TlsException", |
389 "Failed to find root cert cache", NULL); | 374 "Failed to find root cert cache", NULL); |
390 } | 375 } |
391 int status = SSL_CTX_load_verify_locations(context(), NULL, cache); | 376 int status = SSL_CTX_load_verify_locations(context(), NULL, cache); |
392 SecureSocketUtils::CheckStatus(status, "TlsException", | 377 SecureSocketUtils::CheckStatus(status, "TlsException", |
393 "Failure trusting builtin roots"); | 378 "Failure trusting builtin roots"); |
394 if (SSL_LOG_STATUS) { | 379 if (SSL_LOG_STATUS) { |
395 Log::Print("Trusting roots from: %s\n", cache); | 380 Log::Print("Trusting roots from: %s\n", cache); |
396 } | 381 } |
397 } | 382 } |
398 | 383 |
399 | |
400 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) { | 384 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) { |
401 char* password = static_cast<char*>(userdata); | 385 char* password = static_cast<char*>(userdata); |
402 ASSERT(size == PEM_BUFSIZE); | 386 ASSERT(size == PEM_BUFSIZE); |
403 strncpy(buf, password, size); | 387 strncpy(buf, password, size); |
404 return strlen(password); | 388 return strlen(password); |
405 } | 389 } |
406 | 390 |
407 | |
408 static EVP_PKEY* GetPrivateKeyPKCS12(BIO* bio, const char* password) { | 391 static EVP_PKEY* GetPrivateKeyPKCS12(BIO* bio, const char* password) { |
409 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); | 392 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); |
410 if (p12.get() == NULL) { | 393 if (p12.get() == NULL) { |
411 return NULL; | 394 return NULL; |
412 } | 395 } |
413 | 396 |
414 EVP_PKEY* key = NULL; | 397 EVP_PKEY* key = NULL; |
415 X509* cert = NULL; | 398 X509* cert = NULL; |
416 STACK_OF(X509)* ca_certs = NULL; | 399 STACK_OF(X509)* ca_certs = NULL; |
417 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs); | 400 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs); |
418 if (status == 0) { | 401 if (status == 0) { |
419 return NULL; | 402 return NULL; |
420 } | 403 } |
421 | 404 |
422 // We only care about the private key. | 405 // We only care about the private key. |
423 ScopedX509 delete_cert(cert); | 406 ScopedX509 delete_cert(cert); |
424 ScopedX509Stack delete_ca_certs(ca_certs); | 407 ScopedX509Stack delete_ca_certs(ca_certs); |
425 return key; | 408 return key; |
426 } | 409 } |
427 | 410 |
428 | |
429 static EVP_PKEY* GetPrivateKey(BIO* bio, const char* password) { | 411 static EVP_PKEY* GetPrivateKey(BIO* bio, const char* password) { |
430 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio, NULL, PasswordCallback, | 412 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio, NULL, PasswordCallback, |
431 const_cast<char*>(password)); | 413 const_cast<char*>(password)); |
432 if (key == NULL) { | 414 if (key == NULL) { |
433 // We try reading data as PKCS12 only if reading as PEM was unsuccessful and | 415 // We try reading data as PKCS12 only if reading as PEM was unsuccessful and |
434 // if there is no indication that the data is malformed PEM. We assume the | 416 // if there is no indication that the data is malformed PEM. We assume the |
435 // data is malformed PEM if it contains the start line, i.e. a line | 417 // data is malformed PEM if it contains the start line, i.e. a line |
436 // with ----- BEGIN. | 418 // with ----- BEGIN. |
437 if (SecureSocketUtils::NoPEMStartLine()) { | 419 if (SecureSocketUtils::NoPEMStartLine()) { |
438 // Reset the bio, and clear the error from trying to read as PEM. | 420 // Reset the bio, and clear the error from trying to read as PEM. |
439 ERR_clear_error(); | 421 ERR_clear_error(); |
440 BIO_reset(bio); | 422 BIO_reset(bio); |
441 | 423 |
442 // Try to decode as PKCS12. | 424 // Try to decode as PKCS12. |
443 key = GetPrivateKeyPKCS12(bio, password); | 425 key = GetPrivateKeyPKCS12(bio, password); |
444 } | 426 } |
445 } | 427 } |
446 return key; | 428 return key; |
447 } | 429 } |
448 | 430 |
449 | |
450 const char* SSLCertContext::GetPasswordArgument(Dart_NativeArguments args, | 431 const char* SSLCertContext::GetPasswordArgument(Dart_NativeArguments args, |
451 intptr_t index) { | 432 intptr_t index) { |
452 Dart_Handle password_object = | 433 Dart_Handle password_object = |
453 ThrowIfError(Dart_GetNativeArgument(args, index)); | 434 ThrowIfError(Dart_GetNativeArgument(args, index)); |
454 const char* password = NULL; | 435 const char* password = NULL; |
455 if (Dart_IsString(password_object)) { | 436 if (Dart_IsString(password_object)) { |
456 ThrowIfError(Dart_StringToCString(password_object, &password)); | 437 ThrowIfError(Dart_StringToCString(password_object, &password)); |
457 if (strlen(password) > PEM_BUFSIZE - 1) { | 438 if (strlen(password) > PEM_BUFSIZE - 1) { |
458 Dart_ThrowException(DartUtils::NewDartArgumentError( | 439 Dart_ThrowException(DartUtils::NewDartArgumentError( |
459 "Password length is greater than 1023 (PEM_BUFSIZE)")); | 440 "Password length is greater than 1023 (PEM_BUFSIZE)")); |
460 } | 441 } |
461 } else if (Dart_IsNull(password_object)) { | 442 } else if (Dart_IsNull(password_object)) { |
462 password = ""; | 443 password = ""; |
463 } else { | 444 } else { |
464 Dart_ThrowException( | 445 Dart_ThrowException( |
465 DartUtils::NewDartArgumentError("Password is not a String or null")); | 446 DartUtils::NewDartArgumentError("Password is not a String or null")); |
466 } | 447 } |
467 return password; | 448 return password; |
468 } | 449 } |
469 | 450 |
470 | |
471 int AlpnCallback(SSL* ssl, | 451 int AlpnCallback(SSL* ssl, |
472 const uint8_t** out, | 452 const uint8_t** out, |
473 uint8_t* outlen, | 453 uint8_t* outlen, |
474 const uint8_t* in, | 454 const uint8_t* in, |
475 unsigned int inlen, | 455 unsigned int inlen, |
476 void* arg) { | 456 void* arg) { |
477 // 'in' and 'arg' are sequences of (length, data) strings with 1-byte lengths. | 457 // 'in' and 'arg' are sequences of (length, data) strings with 1-byte lengths. |
478 // 'arg' is 0-terminated. Finds the first string in 'arg' that is in 'in'. | 458 // 'arg' is 0-terminated. Finds the first string in 'arg' that is in 'in'. |
479 uint8_t* server_list = static_cast<uint8_t*>(arg); | 459 uint8_t* server_list = static_cast<uint8_t*>(arg); |
480 while (*server_list != 0) { | 460 while (*server_list != 0) { |
481 uint8_t protocol_length = *server_list++; | 461 uint8_t protocol_length = *server_list++; |
482 const uint8_t* client_list = in; | 462 const uint8_t* client_list = in; |
483 while (client_list < in + inlen) { | 463 while (client_list < in + inlen) { |
484 uint8_t client_protocol_length = *client_list++; | 464 uint8_t client_protocol_length = *client_list++; |
485 if (client_protocol_length == protocol_length) { | 465 if (client_protocol_length == protocol_length) { |
486 if (0 == memcmp(server_list, client_list, protocol_length)) { | 466 if (0 == memcmp(server_list, client_list, protocol_length)) { |
487 *out = client_list; | 467 *out = client_list; |
488 *outlen = client_protocol_length; | 468 *outlen = client_protocol_length; |
489 return SSL_TLSEXT_ERR_OK; // Success | 469 return SSL_TLSEXT_ERR_OK; // Success |
490 } | 470 } |
491 } | 471 } |
492 client_list += client_protocol_length; | 472 client_list += client_protocol_length; |
493 } | 473 } |
494 server_list += protocol_length; | 474 server_list += protocol_length; |
495 } | 475 } |
496 // TODO(23580): Make failure send a fatal alert instead of ignoring ALPN. | 476 // TODO(23580): Make failure send a fatal alert instead of ignoring ALPN. |
497 return SSL_TLSEXT_ERR_NOACK; | 477 return SSL_TLSEXT_ERR_NOACK; |
498 } | 478 } |
499 | 479 |
500 | |
501 // Sets the protocol list for ALPN on a SSL object or a context. | 480 // Sets the protocol list for ALPN on a SSL object or a context. |
502 void SSLCertContext::SetAlpnProtocolList(Dart_Handle protocols_handle, | 481 void SSLCertContext::SetAlpnProtocolList(Dart_Handle protocols_handle, |
503 SSL* ssl, | 482 SSL* ssl, |
504 SSLCertContext* context, | 483 SSLCertContext* context, |
505 bool is_server) { | 484 bool is_server) { |
506 // Enable ALPN (application layer protocol negotiation) if the caller provides | 485 // Enable ALPN (application layer protocol negotiation) if the caller provides |
507 // a valid list of supported protocols. | 486 // a valid list of supported protocols. |
508 Dart_TypedData_Type protocols_type; | 487 Dart_TypedData_Type protocols_type; |
509 uint8_t* protocol_string = NULL; | 488 uint8_t* protocol_string = NULL; |
510 uint8_t* protocol_string_copy = NULL; | 489 uint8_t* protocol_string_copy = NULL; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 ASSERT(ssl == NULL); | 528 ASSERT(ssl == NULL); |
550 status = SSL_CTX_set_alpn_protos(context->context(), protocol_string, | 529 status = SSL_CTX_set_alpn_protos(context->context(), protocol_string, |
551 protocol_string_len); | 530 protocol_string_len); |
552 } | 531 } |
553 ASSERT(status == 0); // The function returns a non-standard status. | 532 ASSERT(status == 0); // The function returns a non-standard status. |
554 } | 533 } |
555 } | 534 } |
556 Dart_TypedDataReleaseData(protocols_handle); | 535 Dart_TypedDataReleaseData(protocols_handle); |
557 } | 536 } |
558 | 537 |
559 | |
560 static int UseChainBytesPKCS12(SSL_CTX* context, | 538 static int UseChainBytesPKCS12(SSL_CTX* context, |
561 BIO* bio, | 539 BIO* bio, |
562 const char* password) { | 540 const char* password) { |
563 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); | 541 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL)); |
564 if (p12.get() == NULL) { | 542 if (p12.get() == NULL) { |
565 return 0; | 543 return 0; |
566 } | 544 } |
567 | 545 |
568 EVP_PKEY* key = NULL; | 546 EVP_PKEY* key = NULL; |
569 X509* cert = NULL; | 547 X509* cert = NULL; |
(...skipping 23 matching lines...) Expand all Loading... |
593 // call fails. | 571 // call fails. |
594 if (status == 0) { | 572 if (status == 0) { |
595 X509_free(ca); | 573 X509_free(ca); |
596 return status; | 574 return status; |
597 } | 575 } |
598 } | 576 } |
599 | 577 |
600 return status; | 578 return status; |
601 } | 579 } |
602 | 580 |
603 | |
604 static int UseChainBytesPEM(SSL_CTX* context, BIO* bio) { | 581 static int UseChainBytesPEM(SSL_CTX* context, BIO* bio) { |
605 int status = 0; | 582 int status = 0; |
606 ScopedX509 x509(PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL)); | 583 ScopedX509 x509(PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL)); |
607 if (x509.get() == NULL) { | 584 if (x509.get() == NULL) { |
608 return 0; | 585 return 0; |
609 } | 586 } |
610 | 587 |
611 status = SSL_CTX_use_certificate(context, x509.get()); | 588 status = SSL_CTX_use_certificate(context, x509.get()); |
612 if (ERR_peek_error() != 0) { | 589 if (ERR_peek_error() != 0) { |
613 // Key/certificate mismatch doesn't imply status is 0. | 590 // Key/certificate mismatch doesn't imply status is 0. |
(...skipping 15 matching lines...) Expand all Loading... |
629 return status; | 606 return status; |
630 } | 607 } |
631 // Note that we must not free `ca` if it was successfully added to the | 608 // Note that we must not free `ca` if it was successfully added to the |
632 // chain. We must free the main certificate x509, though since its reference | 609 // chain. We must free the main certificate x509, though since its reference |
633 // count is increased by SSL_CTX_use_certificate. | 610 // count is increased by SSL_CTX_use_certificate. |
634 } | 611 } |
635 | 612 |
636 return SecureSocketUtils::NoPEMStartLine() ? status : 0; | 613 return SecureSocketUtils::NoPEMStartLine() ? status : 0; |
637 } | 614 } |
638 | 615 |
639 | |
640 static int UseChainBytes(SSL_CTX* context, BIO* bio, const char* password) { | 616 static int UseChainBytes(SSL_CTX* context, BIO* bio, const char* password) { |
641 int status = UseChainBytesPEM(context, bio); | 617 int status = UseChainBytesPEM(context, bio); |
642 if (status == 0) { | 618 if (status == 0) { |
643 if (SecureSocketUtils::NoPEMStartLine()) { | 619 if (SecureSocketUtils::NoPEMStartLine()) { |
644 ERR_clear_error(); | 620 ERR_clear_error(); |
645 BIO_reset(bio); | 621 BIO_reset(bio); |
646 status = UseChainBytesPKCS12(context, bio, password); | 622 status = UseChainBytesPKCS12(context, bio, password); |
647 } | 623 } |
648 } else { | 624 } else { |
649 // The PEM file was successfully read. | 625 // The PEM file was successfully read. |
650 ERR_clear_error(); | 626 ERR_clear_error(); |
651 } | 627 } |
652 return status; | 628 return status; |
653 } | 629 } |
654 | 630 |
655 | |
656 int SSLCertContext::UseCertificateChainBytes(Dart_Handle cert_chain_bytes, | 631 int SSLCertContext::UseCertificateChainBytes(Dart_Handle cert_chain_bytes, |
657 const char* password) { | 632 const char* password) { |
658 ScopedMemBIO bio(cert_chain_bytes); | 633 ScopedMemBIO bio(cert_chain_bytes); |
659 return UseChainBytes(context(), bio.bio(), password); | 634 return UseChainBytes(context(), bio.bio(), password); |
660 } | 635 } |
661 | 636 |
662 | |
663 static X509* GetX509Certificate(Dart_NativeArguments args) { | 637 static X509* GetX509Certificate(Dart_NativeArguments args) { |
664 X509* certificate = NULL; | 638 X509* certificate = NULL; |
665 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); | 639 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); |
666 ASSERT(Dart_IsInstance(dart_this)); | 640 ASSERT(Dart_IsInstance(dart_this)); |
667 ThrowIfError(Dart_GetNativeInstanceField( | 641 ThrowIfError(Dart_GetNativeInstanceField( |
668 dart_this, SSLCertContext::kX509NativeFieldIndex, | 642 dart_this, SSLCertContext::kX509NativeFieldIndex, |
669 reinterpret_cast<intptr_t*>(&certificate))); | 643 reinterpret_cast<intptr_t*>(&certificate))); |
670 return certificate; | 644 return certificate; |
671 } | 645 } |
672 | 646 |
673 | |
674 Dart_Handle X509Helper::GetSubject(Dart_NativeArguments args) { | 647 Dart_Handle X509Helper::GetSubject(Dart_NativeArguments args) { |
675 X509* certificate = GetX509Certificate(args); | 648 X509* certificate = GetX509Certificate(args); |
676 X509_NAME* subject = X509_get_subject_name(certificate); | 649 X509_NAME* subject = X509_get_subject_name(certificate); |
677 char* subject_string = X509_NAME_oneline(subject, NULL, 0); | 650 char* subject_string = X509_NAME_oneline(subject, NULL, 0); |
678 if (subject_string == NULL) { | 651 if (subject_string == NULL) { |
679 Dart_ThrowException(DartUtils::NewDartArgumentError( | 652 Dart_ThrowException(DartUtils::NewDartArgumentError( |
680 "X509.subject failed to find subject's common name.")); | 653 "X509.subject failed to find subject's common name.")); |
681 } | 654 } |
682 Dart_Handle subject_handle = Dart_NewStringFromCString(subject_string); | 655 Dart_Handle subject_handle = Dart_NewStringFromCString(subject_string); |
683 OPENSSL_free(subject_string); | 656 OPENSSL_free(subject_string); |
684 return subject_handle; | 657 return subject_handle; |
685 } | 658 } |
686 | 659 |
687 | |
688 Dart_Handle X509Helper::GetIssuer(Dart_NativeArguments args) { | 660 Dart_Handle X509Helper::GetIssuer(Dart_NativeArguments args) { |
689 fprintf(stdout, "Getting issuer!\n"); | 661 fprintf(stdout, "Getting issuer!\n"); |
690 X509* certificate = GetX509Certificate(args); | 662 X509* certificate = GetX509Certificate(args); |
691 X509_NAME* issuer = X509_get_issuer_name(certificate); | 663 X509_NAME* issuer = X509_get_issuer_name(certificate); |
692 char* issuer_string = X509_NAME_oneline(issuer, NULL, 0); | 664 char* issuer_string = X509_NAME_oneline(issuer, NULL, 0); |
693 if (issuer_string == NULL) { | 665 if (issuer_string == NULL) { |
694 Dart_ThrowException(DartUtils::NewDartArgumentError( | 666 Dart_ThrowException(DartUtils::NewDartArgumentError( |
695 "X509.issuer failed to find issuer's common name.")); | 667 "X509.issuer failed to find issuer's common name.")); |
696 } | 668 } |
697 Dart_Handle issuer_handle = Dart_NewStringFromCString(issuer_string); | 669 Dart_Handle issuer_handle = Dart_NewStringFromCString(issuer_string); |
698 OPENSSL_free(issuer_string); | 670 OPENSSL_free(issuer_string); |
699 return issuer_handle; | 671 return issuer_handle; |
700 } | 672 } |
701 | 673 |
702 | |
703 static Dart_Handle ASN1TimeToMilliseconds(ASN1_TIME* aTime) { | 674 static Dart_Handle ASN1TimeToMilliseconds(ASN1_TIME* aTime) { |
704 ASN1_UTCTIME* epoch_start = M_ASN1_UTCTIME_new(); | 675 ASN1_UTCTIME* epoch_start = M_ASN1_UTCTIME_new(); |
705 ASN1_UTCTIME_set_string(epoch_start, "700101000000Z"); | 676 ASN1_UTCTIME_set_string(epoch_start, "700101000000Z"); |
706 int days; | 677 int days; |
707 int seconds; | 678 int seconds; |
708 int result = ASN1_TIME_diff(&days, &seconds, epoch_start, aTime); | 679 int result = ASN1_TIME_diff(&days, &seconds, epoch_start, aTime); |
709 M_ASN1_UTCTIME_free(epoch_start); | 680 M_ASN1_UTCTIME_free(epoch_start); |
710 if (result != 1) { | 681 if (result != 1) { |
711 // TODO(whesse): Propagate an error to Dart. | 682 // TODO(whesse): Propagate an error to Dart. |
712 Log::PrintErr("ASN1Time error %d\n", result); | 683 Log::PrintErr("ASN1Time error %d\n", result); |
713 } | 684 } |
714 return Dart_NewInteger((86400LL * days + seconds) * 1000LL); | 685 return Dart_NewInteger((86400LL * days + seconds) * 1000LL); |
715 } | 686 } |
716 | 687 |
717 | |
718 Dart_Handle X509Helper::GetStartValidity(Dart_NativeArguments args) { | 688 Dart_Handle X509Helper::GetStartValidity(Dart_NativeArguments args) { |
719 X509* certificate = GetX509Certificate(args); | 689 X509* certificate = GetX509Certificate(args); |
720 ASN1_TIME* not_before = X509_get_notBefore(certificate); | 690 ASN1_TIME* not_before = X509_get_notBefore(certificate); |
721 return ASN1TimeToMilliseconds(not_before); | 691 return ASN1TimeToMilliseconds(not_before); |
722 } | 692 } |
723 | 693 |
724 | |
725 Dart_Handle X509Helper::GetEndValidity(Dart_NativeArguments args) { | 694 Dart_Handle X509Helper::GetEndValidity(Dart_NativeArguments args) { |
726 X509* certificate = GetX509Certificate(args); | 695 X509* certificate = GetX509Certificate(args); |
727 ASN1_TIME* not_after = X509_get_notAfter(certificate); | 696 ASN1_TIME* not_after = X509_get_notAfter(certificate); |
728 return ASN1TimeToMilliseconds(not_after); | 697 return ASN1TimeToMilliseconds(not_after); |
729 } | 698 } |
730 | 699 |
731 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( | 700 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( |
732 Dart_NativeArguments args) { | 701 Dart_NativeArguments args) { |
733 SSLCertContext* context = SSLCertContext::GetSecurityContext(args); | 702 SSLCertContext* context = SSLCertContext::GetSecurityContext(args); |
734 const char* password = SSLCertContext::GetPasswordArgument(args, 2); | 703 const char* password = SSLCertContext::GetPasswordArgument(args, 2); |
735 | 704 |
736 int status; | 705 int status; |
737 { | 706 { |
738 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); | 707 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1))); |
739 EVP_PKEY* key = GetPrivateKey(bio.bio(), password); | 708 EVP_PKEY* key = GetPrivateKey(bio.bio(), password); |
740 status = SSL_CTX_use_PrivateKey(context->context(), key); | 709 status = SSL_CTX_use_PrivateKey(context->context(), key); |
741 // SSL_CTX_use_PrivateKey increments the reference count of key on success, | 710 // SSL_CTX_use_PrivateKey increments the reference count of key on success, |
742 // so we have to call EVP_PKEY_free on both success and failure. | 711 // so we have to call EVP_PKEY_free on both success and failure. |
743 EVP_PKEY_free(key); | 712 EVP_PKEY_free(key); |
744 } | 713 } |
745 | 714 |
746 // TODO(24184): Handle different expected errors here - file missing, | 715 // TODO(24184): Handle different expected errors here - file missing, |
747 // incorrect password, file not a PEM, and throw exceptions. | 716 // incorrect password, file not a PEM, and throw exceptions. |
748 // SecureSocketUtils::CheckStatus should also throw an exception in uncaught | 717 // SecureSocketUtils::CheckStatus should also throw an exception in uncaught |
749 // cases. | 718 // cases. |
750 SecureSocketUtils::CheckStatus(status, "TlsException", | 719 SecureSocketUtils::CheckStatus(status, "TlsException", |
751 "Failure in usePrivateKeyBytes"); | 720 "Failure in usePrivateKeyBytes"); |
752 } | 721 } |
753 | 722 |
754 | |
755 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) { | 723 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) { |
756 SSLFilter::InitializeLibrary(); | 724 SSLFilter::InitializeLibrary(); |
757 SSL_CTX* ctx = SSL_CTX_new(TLS_method()); | 725 SSL_CTX* ctx = SSL_CTX_new(TLS_method()); |
758 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLCertContext::CertificateCallback); | 726 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, SSLCertContext::CertificateCallback); |
759 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION); | 727 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION); |
760 SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM"); | 728 SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM"); |
761 SSLCertContext* context = new SSLCertContext(ctx); | 729 SSLCertContext* context = new SSLCertContext(ctx); |
762 Dart_Handle err = SetSecurityContext(args, context); | 730 Dart_Handle err = SetSecurityContext(args, context); |
763 if (Dart_IsError(err)) { | 731 if (Dart_IsError(err)) { |
764 delete context; | 732 delete context; |
765 Dart_PropagateError(err); | 733 Dart_PropagateError(err); |
766 } | 734 } |
767 } | 735 } |
768 | 736 |
769 | |
770 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( | 737 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( |
771 Dart_NativeArguments args) { | 738 Dart_NativeArguments args) { |
772 SSLCertContext* context = SSLCertContext::GetSecurityContext(args); | 739 SSLCertContext* context = SSLCertContext::GetSecurityContext(args); |
773 Dart_Handle cert_bytes = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 740 Dart_Handle cert_bytes = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
774 const char* password = SSLCertContext::GetPasswordArgument(args, 2); | 741 const char* password = SSLCertContext::GetPasswordArgument(args, 2); |
775 | 742 |
776 ASSERT(context != NULL); | 743 ASSERT(context != NULL); |
777 ASSERT(password != NULL); | 744 ASSERT(password != NULL); |
778 context->SetTrustedCertificatesBytes(cert_bytes, password); | 745 context->SetTrustedCertificatesBytes(cert_bytes, password); |
779 } | 746 } |
780 | 747 |
781 | |
782 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( | 748 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( |
783 Dart_NativeArguments args) { | 749 Dart_NativeArguments args) { |
784 SSLCertContext* context = SSLCertContext::GetSecurityContext(args); | 750 SSLCertContext* context = SSLCertContext::GetSecurityContext(args); |
785 Dart_Handle client_authorities_bytes = | 751 Dart_Handle client_authorities_bytes = |
786 ThrowIfError(Dart_GetNativeArgument(args, 1)); | 752 ThrowIfError(Dart_GetNativeArgument(args, 1)); |
787 const char* password = SSLCertContext::GetPasswordArgument(args, 2); | 753 const char* password = SSLCertContext::GetPasswordArgument(args, 2); |
788 | 754 |
789 ASSERT(context != NULL); | 755 ASSERT(context != NULL); |
790 ASSERT(password != NULL); | 756 ASSERT(password != NULL); |
791 | 757 |
792 context->SetClientAuthoritiesBytes(client_authorities_bytes, password); | 758 context->SetClientAuthoritiesBytes(client_authorities_bytes, password); |
793 } | 759 } |
794 | 760 |
795 | |
796 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)( | 761 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)( |
797 Dart_NativeArguments args) { | 762 Dart_NativeArguments args) { |
798 SSLCertContext* context = SSLCertContext::GetSecurityContext(args); | 763 SSLCertContext* context = SSLCertContext::GetSecurityContext(args); |
799 Dart_Handle cert_chain_bytes = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 764 Dart_Handle cert_chain_bytes = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
800 const char* password = SSLCertContext::GetPasswordArgument(args, 2); | 765 const char* password = SSLCertContext::GetPasswordArgument(args, 2); |
801 | 766 |
802 ASSERT(context != NULL); | 767 ASSERT(context != NULL); |
803 ASSERT(password != NULL); | 768 ASSERT(password != NULL); |
804 | 769 |
805 int status = context->UseCertificateChainBytes(cert_chain_bytes, password); | 770 int status = context->UseCertificateChainBytes(cert_chain_bytes, password); |
806 | 771 |
807 SecureSocketUtils::CheckStatus(status, "TlsException", | 772 SecureSocketUtils::CheckStatus(status, "TlsException", |
808 "Failure in useCertificateChainBytes"); | 773 "Failure in useCertificateChainBytes"); |
809 } | 774 } |
810 | 775 |
811 | |
812 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)( | 776 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)( |
813 Dart_NativeArguments args) { | 777 Dart_NativeArguments args) { |
814 SSLCertContext* context = SSLCertContext::GetSecurityContext(args); | 778 SSLCertContext* context = SSLCertContext::GetSecurityContext(args); |
815 | 779 |
816 ASSERT(context != NULL); | 780 ASSERT(context != NULL); |
817 | 781 |
818 context->TrustBuiltinRoots(); | 782 context->TrustBuiltinRoots(); |
819 } | 783 } |
820 | 784 |
821 | |
822 void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) { | 785 void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) { |
823 Dart_SetReturnValue(args, X509Helper::GetSubject(args)); | 786 Dart_SetReturnValue(args, X509Helper::GetSubject(args)); |
824 } | 787 } |
825 | 788 |
826 | |
827 void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) { | 789 void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) { |
828 Dart_SetReturnValue(args, X509Helper::GetIssuer(args)); | 790 Dart_SetReturnValue(args, X509Helper::GetIssuer(args)); |
829 } | 791 } |
830 | 792 |
831 | |
832 void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) { | 793 void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) { |
833 Dart_SetReturnValue(args, X509Helper::GetStartValidity(args)); | 794 Dart_SetReturnValue(args, X509Helper::GetStartValidity(args)); |
834 } | 795 } |
835 | 796 |
836 | |
837 void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) { | 797 void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) { |
838 Dart_SetReturnValue(args, X509Helper::GetEndValidity(args)); | 798 Dart_SetReturnValue(args, X509Helper::GetEndValidity(args)); |
839 } | 799 } |
840 | 800 |
841 | |
842 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( | 801 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( |
843 Dart_NativeArguments args) { | 802 Dart_NativeArguments args) { |
844 SSLCertContext* context = SSLCertContext::GetSecurityContext(args); | 803 SSLCertContext* context = SSLCertContext::GetSecurityContext(args); |
845 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 804 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
846 Dart_Handle is_server_handle = ThrowIfError(Dart_GetNativeArgument(args, 2)); | 805 Dart_Handle is_server_handle = ThrowIfError(Dart_GetNativeArgument(args, 2)); |
847 if (Dart_IsBoolean(is_server_handle)) { | 806 if (Dart_IsBoolean(is_server_handle)) { |
848 bool is_server = DartUtils::GetBooleanValue(is_server_handle); | 807 bool is_server = DartUtils::GetBooleanValue(is_server_handle); |
849 SSLCertContext::SetAlpnProtocolList(protocols_handle, NULL, context, | 808 SSLCertContext::SetAlpnProtocolList(protocols_handle, NULL, context, |
850 is_server); | 809 is_server); |
851 } else { | 810 } else { |
852 Dart_ThrowException(DartUtils::NewDartArgumentError( | 811 Dart_ThrowException(DartUtils::NewDartArgumentError( |
853 "Non-boolean is_server argument passed to SetAlpnProtocols")); | 812 "Non-boolean is_server argument passed to SetAlpnProtocols")); |
854 } | 813 } |
855 } | 814 } |
856 | 815 |
857 } // namespace bin | 816 } // namespace bin |
858 } // namespace dart | 817 } // namespace dart |
859 | 818 |
860 #endif // !defined(DART_IO_DISABLED) && | 819 #endif // !defined(DART_IO_DISABLED) && |
861 // !defined(DART_IO_SECURE_SOCKET_DISABLED) | 820 // !defined(DART_IO_SECURE_SOCKET_DISABLED) |
OLD | NEW |