OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 #include "bin/secure_socket.h" | 5 #include "bin/secure_socket.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 int error = ERR_get_error(); | 369 int error = ERR_get_error(); |
370 Log::PrintErr("Failed: %s status %d", message, status); | 370 Log::PrintErr("Failed: %s status %d", message, status); |
371 char error_string[SSL_ERROR_MESSAGE_BUFFER_SIZE]; | 371 char error_string[SSL_ERROR_MESSAGE_BUFFER_SIZE]; |
372 ERR_error_string_n(error, error_string, SSL_ERROR_MESSAGE_BUFFER_SIZE); | 372 ERR_error_string_n(error, error_string, SSL_ERROR_MESSAGE_BUFFER_SIZE); |
373 Log::PrintErr("ERROR: %d %s\n", error, error_string); | 373 Log::PrintErr("ERROR: %d %s\n", error, error_string); |
374 } | 374 } |
375 ThrowIOException(status, type, message); | 375 ThrowIOException(status, type, message); |
376 } | 376 } |
377 | 377 |
378 | 378 |
379 void FUNCTION_NAME(SecurityContext_UsePrivateKey)(Dart_NativeArguments args) { | 379 void FUNCTION_NAME(SecurityContext_UsePrivateKeyAsBytes)( |
380 Dart_NativeArguments args) { | |
380 SSL_CTX* context = GetSecurityContext(args); | 381 SSL_CTX* context = GetSecurityContext(args); |
381 Dart_Handle filename_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 382 |
382 const char* filename = NULL; | 383 Dart_Handle key_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
383 if (Dart_IsString(filename_object)) { | 384 if (!Dart_IsTypedData(key_object) && !Dart_IsList(key_object)) { |
384 ThrowIfError(Dart_StringToCString(filename_object, &filename)); | |
385 } else { | |
386 Dart_ThrowException(DartUtils::NewDartArgumentError( | 385 Dart_ThrowException(DartUtils::NewDartArgumentError( |
387 "File argument to SecurityContext.usePrivateKey is not a String")); | 386 "keyBytes argument to SecurityContext.usePrivateKey " |
387 "is not a List<int>")); | |
388 } | 388 } |
389 | |
389 Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); | 390 Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); |
390 const char* password = NULL; | 391 const char* password = NULL; |
391 if (Dart_IsString(password_object)) { | 392 if (Dart_IsString(password_object)) { |
392 ThrowIfError(Dart_StringToCString(password_object, &password)); | 393 ThrowIfError(Dart_StringToCString(password_object, &password)); |
393 if (strlen(password) > PEM_BUFSIZE - 1) { | 394 if (strlen(password) > PEM_BUFSIZE - 1) { |
394 Dart_ThrowException(DartUtils::NewDartArgumentError( | 395 Dart_ThrowException(DartUtils::NewDartArgumentError( |
395 "SecurityContext.usePrivateKey password length is greater than" | 396 "SecurityContext.usePrivateKey password length is greater than" |
396 " 1023 (PEM_BUFSIZE)")); | 397 " 1023 (PEM_BUFSIZE)")); |
397 } | 398 } |
398 } else if (Dart_IsNull(password_object)) { | 399 } else if (Dart_IsNull(password_object)) { |
399 password = ""; | 400 password = ""; |
400 } else { | 401 } else { |
401 Dart_ThrowException(DartUtils::NewDartArgumentError( | 402 Dart_ThrowException(DartUtils::NewDartArgumentError( |
402 "SecurityContext.usePrivateKey password is not a String or null")); | 403 "SecurityContext.usePrivateKey password is not a String or null")); |
403 } | 404 } |
404 | 405 |
405 SSL_CTX_set_default_passwd_cb(context, PasswordCallback); | 406 uint8_t* key_bytes = NULL; |
406 SSL_CTX_set_default_passwd_cb_userdata(context, const_cast<char*>(password)); | 407 intptr_t key_bytes_len = 0; |
407 int status = SSL_CTX_use_PrivateKey_file(context, | 408 bool is_typed_data = false; |
408 filename, | 409 if (Dart_IsTypedData(key_object)) { |
409 SSL_FILETYPE_PEM); | 410 is_typed_data = true; |
411 Dart_TypedData_Type typ; | |
412 ThrowIfError(Dart_TypedDataAcquireData( | |
413 key_object, | |
414 &typ, | |
415 reinterpret_cast<void**>(&key_bytes), | |
416 &key_bytes_len)); | |
417 } else { | |
418 ASSERT(Dart_IsList(key_object)); | |
419 ThrowIfError(Dart_ListLength(key_object, &key_bytes_len)); | |
420 key_bytes = new uint8_t[key_bytes_len]; | |
421 ThrowIfError(Dart_ListGetAsBytes(key_object, 0, key_bytes, key_bytes_len)); | |
Bill Hesse
2016/01/29 14:41:50
Leak of key_bytes in this line. Perhaps this is a
zra
2016/01/29 16:47:49
deleted key_bytes on error.
| |
422 } | |
423 ASSERT(key_bytes != NULL); | |
424 | |
425 BIO* bio = BIO_new_mem_buf(key_bytes, key_bytes_len); | |
426 EVP_PKEY *key = PEM_read_bio_PrivateKey( | |
427 bio, NULL, PasswordCallback, const_cast<char*>(password)); | |
428 int status = SSL_CTX_use_PrivateKey(context, key); | |
429 BIO_free(bio); | |
430 if (is_typed_data) { | |
431 ThrowIfError(Dart_TypedDataReleaseData(key_object)); | |
432 } else { | |
433 delete key_bytes; | |
434 } | |
435 | |
410 // TODO(24184): Handle different expected errors here - file missing, | 436 // TODO(24184): Handle different expected errors here - file missing, |
411 // incorrect password, file not a PEM, and throw exceptions. | 437 // incorrect password, file not a PEM, and throw exceptions. |
412 // CheckStatus should also throw an exception in uncaught cases. | 438 // CheckStatus should also throw an exception in uncaught cases. |
413 CheckStatus(status, "TlsException", "Failure in usePrivateKey"); | 439 CheckStatus(status, "TlsException", "Failure in usePrivateKey"); |
414 SSL_CTX_set_default_passwd_cb_userdata(context, NULL); | |
415 } | 440 } |
416 | 441 |
417 | 442 |
418 void FUNCTION_NAME(SecurityContext_SetTrustedCertificates)( | 443 void FUNCTION_NAME(SecurityContext_SetTrustedCertificates)( |
419 Dart_NativeArguments args) { | 444 Dart_NativeArguments args) { |
420 SSL_CTX* context = GetSecurityContext(args); | 445 SSL_CTX* context = GetSecurityContext(args); |
421 Dart_Handle filename_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 446 Dart_Handle filename_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
422 const char* filename = NULL; | 447 const char* filename = NULL; |
423 if (Dart_IsString(filename_object)) { | 448 if (Dart_IsString(filename_object)) { |
424 ThrowIfError(Dart_StringToCString(filename_object, &filename)); | 449 ThrowIfError(Dart_StringToCString(filename_object, &filename)); |
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1117 } else { | 1142 } else { |
1118 if (SSL_LOG_DATA) Log::Print( | 1143 if (SSL_LOG_DATA) Log::Print( |
1119 "WriteEncrypted BIO_read wrote %d bytes\n", bytes_processed); | 1144 "WriteEncrypted BIO_read wrote %d bytes\n", bytes_processed); |
1120 } | 1145 } |
1121 } | 1146 } |
1122 return bytes_processed; | 1147 return bytes_processed; |
1123 } | 1148 } |
1124 | 1149 |
1125 } // namespace bin | 1150 } // namespace bin |
1126 } // namespace dart | 1151 } // namespace dart |
OLD | NEW |