Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: runtime/bin/security_context.cc

Issue 2903743002: Porting SecureSocket to use BoringSSL on OSX (Closed)
Patch Set: Addressed missed comment from last patch set Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED)
6
7 #include "bin/security_context.h"
8
9 #include <openssl/bio.h>
10 #include <openssl/err.h>
11 #include <openssl/pkcs12.h>
12 #include <openssl/ssl.h>
13 #include <openssl/x509.h>
14
15 #include "platform/globals.h"
16
17 #include "bin/directory.h"
18 #include "bin/file.h"
19 #include "bin/log.h"
20 #include "bin/secure_socket_filter.h"
21 #include "bin/secure_socket_utils.h"
22
23 // Return the error from the containing function if handle is an error handle.
24 #define RETURN_IF_ERROR(handle) \
25 { \
26 Dart_Handle __handle = handle; \
27 if (Dart_IsError((__handle))) { \
28 return __handle; \
29 } \
30 }
31
32 namespace dart {
33 namespace bin {
34
35 SSLCertContext* SSLCertContext::GetSecurityContext(Dart_NativeArguments args) {
36 SSLCertContext* context;
37 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
38 ASSERT(Dart_IsInstance(dart_this));
39 ThrowIfError(Dart_GetNativeInstanceField(
40 dart_this, SSLCertContext::kSecurityContextNativeFieldIndex,
41 reinterpret_cast<intptr_t*>(&context)));
42 return context;
43 }
44
45
46 static void DeleteSecurityContext(void* isolate_data,
47 Dart_WeakPersistentHandle handle,
48 void* context_pointer) {
49 SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer);
50 context->Release();
51 }
52
53
54 static Dart_Handle SetSecurityContext(Dart_NativeArguments args,
55 SSLCertContext* context) {
56 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0);
57 RETURN_IF_ERROR(dart_this);
58 ASSERT(Dart_IsInstance(dart_this));
59 Dart_Handle err = Dart_SetNativeInstanceField(
60 dart_this, SSLCertContext::kSecurityContextNativeFieldIndex,
61 reinterpret_cast<intptr_t>(context));
62 RETURN_IF_ERROR(err);
63 Dart_NewWeakPersistentHandle(dart_this, context,
64 SSLCertContext::kApproximateSize,
65 DeleteSecurityContext);
66 return Dart_Null();
67 }
68
69
70 static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context,
71 BIO* bio,
72 const char* password) {
73 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
74 if (p12.get() == NULL) {
75 return 0;
76 }
77
78 EVP_PKEY* key = NULL;
79 X509* cert = NULL;
80 STACK_OF(X509)* ca_certs = NULL;
81 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
82 if (status == 0) {
83 return status;
84 }
85
86 ScopedX509Stack cert_stack(ca_certs);
87 X509_STORE* store = SSL_CTX_get_cert_store(context);
88 status = X509_STORE_add_cert(store, cert);
89 // X509_STORE_add_cert increments the reference count of cert on success.
90 X509_free(cert);
91 if (status == 0) {
92 return status;
93 }
94
95 X509* ca;
96 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) {
97 status = X509_STORE_add_cert(store, ca);
98 // X509_STORE_add_cert increments the reference count of cert on success.
99 X509_free(ca);
100 if (status == 0) {
101 return status;
102 }
103 }
104
105 return status;
106 }
107
108
109 static int SetTrustedCertificatesBytesPEM(SSL_CTX* context, BIO* bio) {
110 X509_STORE* store = SSL_CTX_get_cert_store(context);
111
112 int status = 0;
113 X509* cert = NULL;
114 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
115 status = X509_STORE_add_cert(store, cert);
116 // X509_STORE_add_cert increments the reference count of cert on success.
117 X509_free(cert);
118 if (status == 0) {
119 return status;
120 }
121 }
122
123 // If no PEM start line is found, it means that we read to the end of the
124 // file, or that the file isn't PEM. In the first case, status will be
125 // non-zero indicating success. In the second case, status will be 0,
126 // indicating that we should try to read as PKCS12. If there is some other
127 // error, we return it up to the caller.
128 return SecureSocketUtils::NoPEMStartLine() ? status : 0;
129 }
130
131
132 void SSLCertContext::SetTrustedCertificatesBytes(Dart_Handle cert_bytes,
133 const char* password) {
134 ScopedMemBIO bio(cert_bytes);
135 int status = SetTrustedCertificatesBytesPEM(context(), bio.bio());
136 if (status == 0) {
137 if (SecureSocketUtils::NoPEMStartLine()) {
138 ERR_clear_error();
139 BIO_reset(bio.bio());
140 status =
141 SetTrustedCertificatesBytesPKCS12(context(), bio.bio(), password);
142 }
143 } else {
144 // The PEM file was successfully parsed.
145 ERR_clear_error();
146 }
147
148 SecureSocketUtils::CheckStatus(status, "TlsException",
149 "Failure trusting builtin roots");
150 }
151
152
153 static int SetClientAuthoritiesPKCS12(SSL_CTX* context,
154 BIO* bio,
155 const char* password) {
156 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
157 if (p12.get() == NULL) {
158 return 0;
159 }
160
161 EVP_PKEY* key = NULL;
162 X509* cert = NULL;
163 STACK_OF(X509)* ca_certs = NULL;
164 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
165 if (status == 0) {
166 return status;
167 }
168
169 ScopedX509Stack cert_stack(ca_certs);
170 status = SSL_CTX_add_client_CA(context, cert);
171 // SSL_CTX_add_client_CA increments the reference count of cert on success.
172 X509_free(cert);
173 if (status == 0) {
174 return status;
175 }
176
177 X509* ca;
178 while ((ca = sk_X509_shift(cert_stack.get())) != NULL) {
179 status = SSL_CTX_add_client_CA(context, ca);
180 // SSL_CTX_add_client_CA increments the reference count of ca on success.
181 X509_free(ca); // The name has been extracted.
182 if (status == 0) {
183 return status;
184 }
185 }
186
187 return status;
188 }
189
190
191 static int SetClientAuthoritiesPEM(SSL_CTX* context, BIO* bio) {
192 int status = 0;
193 X509* cert = NULL;
194 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
195 status = SSL_CTX_add_client_CA(context, cert);
196 X509_free(cert); // The name has been extracted.
197 if (status == 0) {
198 return status;
199 }
200 }
201 return SecureSocketUtils::NoPEMStartLine() ? status : 0;
202 }
203
204
205 static int SetClientAuthorities(SSL_CTX* context,
206 BIO* bio,
207 const char* password) {
208 int status = SetClientAuthoritiesPEM(context, bio);
209 if (status == 0) {
210 if (SecureSocketUtils::NoPEMStartLine()) {
211 ERR_clear_error();
212 BIO_reset(bio);
213 status = SetClientAuthoritiesPKCS12(context, bio, password);
214 }
215 } else {
216 // The PEM file was successfully parsed.
217 ERR_clear_error();
218 }
219 return status;
220 }
221
222
223 void SSLCertContext::SetClientAuthoritiesBytes(
224 Dart_Handle client_authorities_bytes,
225 const char* password) {
226 int status;
227 {
228 ScopedMemBIO bio(client_authorities_bytes);
229 status = SetClientAuthorities(context(), bio.bio(), password);
230 }
231
232 SecureSocketUtils::CheckStatus(status, "TlsException",
233 "Failure in setClientAuthoritiesBytes");
234 }
235
236 void SSLCertContext::LoadRootCertFile(const char* file) {
237 if (SSL_LOG_STATUS) {
238 Log::Print("Looking for trusted roots in %s\n", file);
239 }
240 if (!File::Exists(file)) {
241 SecureSocketUtils::ThrowIOException(-1, "TlsException",
242 "Failed to find root cert file", NULL);
243 }
244 int status = SSL_CTX_load_verify_locations(context(), file, NULL);
245 SecureSocketUtils::CheckStatus(status, "TlsException",
246 "Failure trusting builtin roots");
247 if (SSL_LOG_STATUS) {
248 Log::Print("Trusting roots from: %s\n", file);
249 }
250 }
251
252
253 void SSLCertContext::AddCompiledInCerts() {
254 if (root_certificates_pem == NULL) {
255 if (SSL_LOG_STATUS) {
256 Log::Print("Missing compiled-in roots\n");
257 }
258 return;
259 }
260 X509_STORE* store = SSL_CTX_get_cert_store(context());
261 BIO* roots_bio =
262 BIO_new_mem_buf(const_cast<unsigned char*>(root_certificates_pem),
263 root_certificates_pem_length);
264 X509* root_cert;
265 // PEM_read_bio_X509 reads PEM-encoded certificates from a bio (in our case,
266 // backed by a memory buffer), and returns X509 objects, one by one.
267 // When the end of the bio is reached, it returns null.
268 while ((root_cert = PEM_read_bio_X509(roots_bio, NULL, NULL, NULL)) != NULL) {
269 int status = X509_STORE_add_cert(store, root_cert);
270 // X509_STORE_add_cert increments the reference count of cert on success.
271 X509_free(root_cert);
272 if (status == 0) {
273 break;
274 }
275 }
276 BIO_free(roots_bio);
277 // If there is an error here, it must be the error indicating that we are done
278 // reading PEM certificates.
279 ASSERT((ERR_peek_error() == 0) || SecureSocketUtils::NoPEMStartLine());
280 ERR_clear_error();
281 }
282
283
284 void SSLCertContext::LoadRootCertCache(const char* cache) {
285 if (SSL_LOG_STATUS) {
286 Log::Print("Looking for trusted roots in %s\n", cache);
287 }
288 if (Directory::Exists(cache) != Directory::EXISTS) {
289 SecureSocketUtils::ThrowIOException(-1, "TlsException",
290 "Failed to find root cert cache", NULL);
291 }
292 int status = SSL_CTX_load_verify_locations(context(), NULL, cache);
293 SecureSocketUtils::CheckStatus(status, "TlsException",
294 "Failure trusting builtin roots");
295 if (SSL_LOG_STATUS) {
296 Log::Print("Trusting roots from: %s\n", cache);
297 }
298 }
299
300
301 int PasswordCallback(char* buf, int size, int rwflag, void* userdata) {
302 char* password = static_cast<char*>(userdata);
303 ASSERT(size == PEM_BUFSIZE);
304 strncpy(buf, password, size);
305 return strlen(password);
306 }
307
308
309 static EVP_PKEY* GetPrivateKeyPKCS12(BIO* bio, const char* password) {
310 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
311 if (p12.get() == NULL) {
312 return NULL;
313 }
314
315 EVP_PKEY* key = NULL;
316 X509* cert = NULL;
317 STACK_OF(X509)* ca_certs = NULL;
318 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
319 if (status == 0) {
320 return NULL;
321 }
322
323 // We only care about the private key.
324 ScopedX509 delete_cert(cert);
325 ScopedX509Stack delete_ca_certs(ca_certs);
326 return key;
327 }
328
329
330 static EVP_PKEY* GetPrivateKey(BIO* bio, const char* password) {
331 EVP_PKEY* key = PEM_read_bio_PrivateKey(bio, NULL, PasswordCallback,
332 const_cast<char*>(password));
333 if (key == NULL) {
334 // We try reading data as PKCS12 only if reading as PEM was unsuccessful and
335 // if there is no indication that the data is malformed PEM. We assume the
336 // data is malformed PEM if it contains the start line, i.e. a line
337 // with ----- BEGIN.
338 if (SecureSocketUtils::NoPEMStartLine()) {
339 // Reset the bio, and clear the error from trying to read as PEM.
340 ERR_clear_error();
341 BIO_reset(bio);
342
343 // Try to decode as PKCS12.
344 key = GetPrivateKeyPKCS12(bio, password);
345 }
346 }
347 return key;
348 }
349
350
351 const char* SSLCertContext::GetPasswordArgument(Dart_NativeArguments args,
352 intptr_t index) {
353 Dart_Handle password_object =
354 ThrowIfError(Dart_GetNativeArgument(args, index));
355 const char* password = NULL;
356 if (Dart_IsString(password_object)) {
357 ThrowIfError(Dart_StringToCString(password_object, &password));
358 if (strlen(password) > PEM_BUFSIZE - 1) {
359 Dart_ThrowException(DartUtils::NewDartArgumentError(
360 "Password length is greater than 1023 (PEM_BUFSIZE)"));
361 }
362 } else if (Dart_IsNull(password_object)) {
363 password = "";
364 } else {
365 Dart_ThrowException(
366 DartUtils::NewDartArgumentError("Password is not a String or null"));
367 }
368 return password;
369 }
370
371
372 int AlpnCallback(SSL* ssl,
373 const uint8_t** out,
374 uint8_t* outlen,
375 const uint8_t* in,
376 unsigned int inlen,
377 void* arg) {
378 // 'in' and 'arg' are sequences of (length, data) strings with 1-byte lengths.
379 // 'arg' is 0-terminated. Finds the first string in 'arg' that is in 'in'.
380 uint8_t* server_list = static_cast<uint8_t*>(arg);
381 while (*server_list != 0) {
382 uint8_t protocol_length = *server_list++;
383 const uint8_t* client_list = in;
384 while (client_list < in + inlen) {
385 uint8_t client_protocol_length = *client_list++;
386 if (client_protocol_length == protocol_length) {
387 if (0 == memcmp(server_list, client_list, protocol_length)) {
388 *out = client_list;
389 *outlen = client_protocol_length;
390 return SSL_TLSEXT_ERR_OK; // Success
391 }
392 }
393 client_list += client_protocol_length;
394 }
395 server_list += protocol_length;
396 }
397 // TODO(23580): Make failure send a fatal alert instead of ignoring ALPN.
398 return SSL_TLSEXT_ERR_NOACK;
399 }
400
401
402 // Sets the protocol list for ALPN on a SSL object or a context.
403 void SSLCertContext::SetAlpnProtocolList(Dart_Handle protocols_handle,
404 SSL* ssl,
405 SSLCertContext* context,
406 bool is_server) {
407 // Enable ALPN (application layer protocol negotiation) if the caller provides
408 // a valid list of supported protocols.
409 Dart_TypedData_Type protocols_type;
410 uint8_t* protocol_string = NULL;
411 uint8_t* protocol_string_copy = NULL;
412 intptr_t protocol_string_len = 0;
413 int status;
414
415 Dart_Handle result = Dart_TypedDataAcquireData(
416 protocols_handle, &protocols_type,
417 reinterpret_cast<void**>(&protocol_string), &protocol_string_len);
418 if (Dart_IsError(result)) {
419 Dart_PropagateError(result);
420 }
421
422 if (protocols_type != Dart_TypedData_kUint8) {
423 Dart_TypedDataReleaseData(protocols_handle);
424 Dart_PropagateError(Dart_NewApiError(
425 "Unexpected type for protocols (expected valid Uint8List)."));
426 }
427
428 if (protocol_string_len > 0) {
429 if (is_server) {
430 // ALPN on server connections must be set on an SSL_CTX object,
431 // not on the SSL object of the individual connection.
432 ASSERT(context != NULL);
433 ASSERT(ssl == NULL);
434 // Because it must be passed as a single void*, terminate
435 // the list of (length, data) strings with a length 0 string.
436 protocol_string_copy =
437 static_cast<uint8_t*>(malloc(protocol_string_len + 1));
438 memmove(protocol_string_copy, protocol_string, protocol_string_len);
439 protocol_string_copy[protocol_string_len] = '\0';
440 SSL_CTX_set_alpn_select_cb(context->context(), AlpnCallback,
441 protocol_string_copy);
442 context->set_alpn_protocol_string(protocol_string_copy);
443 } else {
444 // The function makes a local copy of protocol_string, which it owns.
445 if (ssl != NULL) {
446 ASSERT(context == NULL);
447 status = SSL_set_alpn_protos(ssl, protocol_string, protocol_string_len);
448 } else {
449 ASSERT(context != NULL);
450 ASSERT(ssl == NULL);
451 status = SSL_CTX_set_alpn_protos(context->context(), protocol_string,
452 protocol_string_len);
453 }
454 ASSERT(status == 0); // The function returns a non-standard status.
455 }
456 }
457 Dart_TypedDataReleaseData(protocols_handle);
458 }
459
460
461 static int UseChainBytesPKCS12(SSL_CTX* context,
462 BIO* bio,
463 const char* password) {
464 ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
465 if (p12.get() == NULL) {
466 return 0;
467 }
468
469 EVP_PKEY* key = NULL;
470 X509* cert = NULL;
471 STACK_OF(X509)* ca_certs = NULL;
472 int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
473 if (status == 0) {
474 return status;
475 }
476
477 ScopedX509 x509(cert);
478 ScopedX509Stack certs(ca_certs);
479 status = SSL_CTX_use_certificate(context, x509.get());
480 if (ERR_peek_error() != 0) {
481 // Key/certificate mismatch doesn't imply status is 0.
482 status = 0;
483 }
484 if (status == 0) {
485 return status;
486 }
487
488 SSL_CTX_clear_chain_certs(context);
489
490 X509* ca;
491 while ((ca = sk_X509_shift(certs.get())) != NULL) {
492 status = SSL_CTX_add0_chain_cert(context, ca);
493 // SSL_CTX_add0_chain_cert does not inc ref count, so don't free unless the
494 // call fails.
495 if (status == 0) {
496 X509_free(ca);
497 return status;
498 }
499 }
500
501 return status;
502 }
503
504
505 static int UseChainBytesPEM(SSL_CTX* context, BIO* bio) {
506 int status = 0;
507 ScopedX509 x509(PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL));
508 if (x509.get() == NULL) {
509 return 0;
510 }
511
512 status = SSL_CTX_use_certificate(context, x509.get());
513 if (ERR_peek_error() != 0) {
514 // Key/certificate mismatch doesn't imply status is 0.
515 status = 0;
516 }
517 if (status == 0) {
518 return status;
519 }
520
521 SSL_CTX_clear_chain_certs(context);
522
523 X509* ca;
524 while ((ca = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
525 status = SSL_CTX_add0_chain_cert(context, ca);
526 // SSL_CTX_add0_chain_cert does not inc ref count, so don't free unless the
527 // call fails.
528 if (status == 0) {
529 X509_free(ca);
530 return status;
531 }
532 // Note that we must not free `ca` if it was successfully added to the
533 // chain. We must free the main certificate x509, though since its reference
534 // count is increased by SSL_CTX_use_certificate.
535 }
536
537 return SecureSocketUtils::NoPEMStartLine() ? status : 0;
538 }
539
540
541 static int UseChainBytes(SSL_CTX* context, BIO* bio, const char* password) {
542 int status = UseChainBytesPEM(context, bio);
543 if (status == 0) {
544 if (SecureSocketUtils::NoPEMStartLine()) {
545 ERR_clear_error();
546 BIO_reset(bio);
547 status = UseChainBytesPKCS12(context, bio, password);
548 }
549 } else {
550 // The PEM file was successfully read.
551 ERR_clear_error();
552 }
553 return status;
554 }
555
556
557 int SSLCertContext::UseCertificateChainBytes(Dart_Handle cert_chain_bytes,
558 const char* password) {
559 ScopedMemBIO bio(cert_chain_bytes);
560 return UseChainBytes(context(), bio.bio(), password);
561 }
562
563
564 static X509* GetX509Certificate(Dart_NativeArguments args) {
565 X509* certificate = NULL;
566 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
567 ASSERT(Dart_IsInstance(dart_this));
568 ThrowIfError(Dart_GetNativeInstanceField(
569 dart_this, SSLCertContext::kX509NativeFieldIndex,
570 reinterpret_cast<intptr_t*>(&certificate)));
571 return certificate;
572 }
573
574
575 Dart_Handle X509Helper::GetSubject(Dart_NativeArguments args) {
576 X509* certificate = GetX509Certificate(args);
577 X509_NAME* subject = X509_get_subject_name(certificate);
578 char* subject_string = X509_NAME_oneline(subject, NULL, 0);
579 if (subject_string == NULL) {
580 Dart_ThrowException(DartUtils::NewDartArgumentError(
581 "X509.subject failed to find subject's common name."));
582 }
583 Dart_Handle subject_handle = Dart_NewStringFromCString(subject_string);
584 OPENSSL_free(subject_string);
585 return subject_handle;
586 }
587
588
589 Dart_Handle X509Helper::GetIssuer(Dart_NativeArguments args) {
590 fprintf(stdout, "Getting issuer!\n");
591 X509* certificate = GetX509Certificate(args);
592 X509_NAME* issuer = X509_get_issuer_name(certificate);
593 char* issuer_string = X509_NAME_oneline(issuer, NULL, 0);
594 if (issuer_string == NULL) {
595 Dart_ThrowException(DartUtils::NewDartArgumentError(
596 "X509.issuer failed to find issuer's common name."));
597 }
598 Dart_Handle issuer_handle = Dart_NewStringFromCString(issuer_string);
599 OPENSSL_free(issuer_string);
600 return issuer_handle;
601 }
602
603
604 static Dart_Handle ASN1TimeToMilliseconds(ASN1_TIME* aTime) {
605 ASN1_UTCTIME* epoch_start = M_ASN1_UTCTIME_new();
606 ASN1_UTCTIME_set_string(epoch_start, "700101000000Z");
607 int days;
608 int seconds;
609 int result = ASN1_TIME_diff(&days, &seconds, epoch_start, aTime);
610 M_ASN1_UTCTIME_free(epoch_start);
611 if (result != 1) {
612 // TODO(whesse): Propagate an error to Dart.
613 Log::PrintErr("ASN1Time error %d\n", result);
614 }
615 return Dart_NewInteger((86400LL * days + seconds) * 1000LL);
616 }
617
618
619 Dart_Handle X509Helper::GetStartValidity(Dart_NativeArguments args) {
620 X509* certificate = GetX509Certificate(args);
621 ASN1_TIME* not_before = X509_get_notBefore(certificate);
622 return ASN1TimeToMilliseconds(not_before);
623 }
624
625
626 Dart_Handle X509Helper::GetEndValidity(Dart_NativeArguments args) {
627 X509* certificate = GetX509Certificate(args);
628 ASN1_TIME* not_after = X509_get_notAfter(certificate);
629 return ASN1TimeToMilliseconds(not_after);
630 }
631
632 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
633 Dart_NativeArguments args) {
634 SSLCertContext* context = SSLCertContext::GetSecurityContext(args);
635 const char* password = SSLCertContext::GetPasswordArgument(args, 2);
636
637 int status;
638 {
639 ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
640 EVP_PKEY* key = GetPrivateKey(bio.bio(), password);
641 status = SSL_CTX_use_PrivateKey(context->context(), key);
642 // SSL_CTX_use_PrivateKey increments the reference count of key on success,
643 // so we have to call EVP_PKEY_free on both success and failure.
644 EVP_PKEY_free(key);
645 }
646
647 // TODO(24184): Handle different expected errors here - file missing,
648 // incorrect password, file not a PEM, and throw exceptions.
649 // SecureSocketUtils::CheckStatus should also throw an exception in uncaught
650 // cases.
651 SecureSocketUtils::CheckStatus(status, "TlsException",
652 "Failure in usePrivateKeyBytes");
653 }
654
655
656 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) {
657 SSLFilter::InitializeLibrary();
658 SSL_CTX* ctx = SSL_CTX_new(TLS_method());
659 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, CertificateCallback);
660 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
661 SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM");
662 SSLCertContext* context = new SSLCertContext(ctx);
663 Dart_Handle err = SetSecurityContext(args, context);
664 if (Dart_IsError(err)) {
665 delete context;
666 Dart_PropagateError(err);
667 }
668 }
669
670
671 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)(
672 Dart_NativeArguments args) {
673 SSLCertContext* context = SSLCertContext::GetSecurityContext(args);
674 Dart_Handle cert_bytes = ThrowIfError(Dart_GetNativeArgument(args, 1));
675 const char* password = SSLCertContext::GetPasswordArgument(args, 2);
676
677 ASSERT(context != NULL);
678 ASSERT(password != NULL);
679 context->SetTrustedCertificatesBytes(cert_bytes, password);
680 }
681
682
683 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)(
684 Dart_NativeArguments args) {
685 SSLCertContext* context = SSLCertContext::GetSecurityContext(args);
686 Dart_Handle client_authorities_bytes =
687 ThrowIfError(Dart_GetNativeArgument(args, 1));
688 const char* password = SSLCertContext::GetPasswordArgument(args, 2);
689
690 ASSERT(context != NULL);
691 ASSERT(password != NULL);
692
693 context->SetClientAuthoritiesBytes(client_authorities_bytes, password);
694 }
695
696
697 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
698 Dart_NativeArguments args) {
699 SSLCertContext* context = SSLCertContext::GetSecurityContext(args);
700 Dart_Handle cert_chain_bytes = ThrowIfError(Dart_GetNativeArgument(args, 1));
701 const char* password = SSLCertContext::GetPasswordArgument(args, 2);
702
703 ASSERT(context != NULL);
704 ASSERT(password != NULL);
705
706 int status = context->UseCertificateChainBytes(cert_chain_bytes, password);
707
708 SecureSocketUtils::CheckStatus(status, "TlsException",
709 "Failure in useCertificateChainBytes");
710 }
711
712
713 void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) {
714 Dart_SetReturnValue(args, Dart_NewBoolean(true));
715 }
716
717
718 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
719 Dart_NativeArguments args) {
720 SSLCertContext* context = SSLCertContext::GetSecurityContext(args);
721
722 ASSERT(context != NULL);
723
724 context->TrustBuiltinRoots();
725 }
726
727
728 void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) {
729 Dart_SetReturnValue(args, X509Helper::GetSubject(args));
730 }
731
732
733 void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) {
734 Dart_SetReturnValue(args, X509Helper::GetIssuer(args));
735 }
736
737
738 void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) {
739 Dart_SetReturnValue(args, X509Helper::GetStartValidity(args));
740 }
741
742
743 void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) {
744 Dart_SetReturnValue(args, X509Helper::GetEndValidity(args));
745 }
746
747
748 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)(
749 Dart_NativeArguments args) {
750 SSLCertContext* context = SSLCertContext::GetSecurityContext(args);
751 Dart_Handle protocols_handle = ThrowIfError(Dart_GetNativeArgument(args, 1));
752 Dart_Handle is_server_handle = ThrowIfError(Dart_GetNativeArgument(args, 2));
753 if (Dart_IsBoolean(is_server_handle)) {
754 bool is_server = DartUtils::GetBooleanValue(is_server_handle);
755 SSLCertContext::SetAlpnProtocolList(protocols_handle, NULL, context,
756 is_server);
757 } else {
758 Dart_ThrowException(DartUtils::NewDartArgumentError(
759 "Non-boolean is_server argument passed to SetAlpnProtocols"));
760 }
761 }
762
763 } // namespace bin
764 } // namespace dart
zra 2017/06/05 21:06:31 Missing newline and comment after endif.
bkonyi 2017/06/06 00:48:34 Done.
765 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698