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

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

Issue 11415290: Add a callback to SecureSocket for certificates that fail to be authenticated. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Free persistent handle upon destruction. Created 8 years 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 | Annotate | Revision Log
« no previous file with comments | « runtime/bin/secure_socket.h ('k') | runtime/bin/secure_socket_patch.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 ThrowIfError(Dart_GetNativeArgument(args, 1)); 136 ThrowIfError(Dart_GetNativeArgument(args, 1));
137 if (!Dart_IsClosure(handshake_complete)) { 137 if (!Dart_IsClosure(handshake_complete)) {
138 Dart_ThrowException(DartUtils::NewDartArgumentError( 138 Dart_ThrowException(DartUtils::NewDartArgumentError(
139 "Illegal argument to RegisterHandshakeCompleteCallback")); 139 "Illegal argument to RegisterHandshakeCompleteCallback"));
140 } 140 }
141 GetFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete); 141 GetFilter(args)->RegisterHandshakeCompleteCallback(handshake_complete);
142 Dart_ExitScope(); 142 Dart_ExitScope();
143 } 143 }
144 144
145 145
146 void FUNCTION_NAME(SecureSocket_RegisterBadCertificateCallback)(
147 Dart_NativeArguments args) {
148 Dart_EnterScope();
149 Dart_Handle callback =
150 ThrowIfError(Dart_GetNativeArgument(args, 1));
151 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) {
152 Dart_ThrowException(DartUtils::NewDartArgumentError(
153 "Illegal argument to RegisterBadCertificateCallback"));
154 }
155 GetFilter(args)->RegisterBadCertificateCallback(callback);
156 Dart_ExitScope();
157 }
158
159
146 void FUNCTION_NAME(SecureSocket_ProcessBuffer)(Dart_NativeArguments args) { 160 void FUNCTION_NAME(SecureSocket_ProcessBuffer)(Dart_NativeArguments args) {
147 Dart_EnterScope(); 161 Dart_EnterScope();
148 Dart_Handle buffer_id_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); 162 Dart_Handle buffer_id_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
149 int64_t buffer_id = DartUtils::GetIntegerValue(buffer_id_object); 163 int64_t buffer_id = DartUtils::GetIntegerValue(buffer_id_object);
150 if (buffer_id < 0 || buffer_id >= SSLFilter::kNumBuffers) { 164 if (buffer_id < 0 || buffer_id >= SSLFilter::kNumBuffers) {
151 Dart_ThrowException(DartUtils::NewDartArgumentError( 165 Dart_ThrowException(DartUtils::NewDartArgumentError(
152 "Illegal argument to ProcessBuffer")); 166 "Illegal argument to ProcessBuffer"));
153 } 167 }
154 168
155 intptr_t bytes_read = 169 intptr_t bytes_read =
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 } else { 212 } else {
199 Dart_ThrowException(DartUtils::NewDartArgumentError( 213 Dart_ThrowException(DartUtils::NewDartArgumentError(
200 "UseBuiltinRoots argument to SetCertificateDatabase is not a bool")); 214 "UseBuiltinRoots argument to SetCertificateDatabase is not a bool"));
201 } 215 }
202 216
203 SSLFilter::InitializeLibrary(certificate_database, password, builtin_roots); 217 SSLFilter::InitializeLibrary(certificate_database, password, builtin_roots);
204 Dart_ExitScope(); 218 Dart_ExitScope();
205 } 219 }
206 220
207 221
222 static bool CallBadCertificateCallback(Dart_Handle callback,
223 const char* subject_name,
224 const char* issuer_name,
225 int64_t start_validity,
226 int64_t end_validity) {
227 if (callback == NULL || Dart_IsNull(callback)) return false;
228 Dart_EnterScope();
229 Dart_Handle subject_name_object = DartUtils::NewString(subject_name);
230 Dart_Handle issuer_name_object = DartUtils::NewString(issuer_name);
231 Dart_Handle start_validity_int = Dart_NewInteger(start_validity);
232 Dart_Handle end_validity_int = Dart_NewInteger(end_validity);
233
234 Dart_Handle date_class =
235 DartUtils::GetDartClass(DartUtils::kCoreLibURL, "Date");
236 Dart_Handle from_milliseconds =
237 DartUtils::NewString("fromMillisecondsSinceEpoch");
238
239 Dart_Handle start_validity_date =
240 Dart_New(date_class, from_milliseconds, 1, &start_validity_int);
241 Dart_Handle end_validity_date =
242 Dart_New(date_class, from_milliseconds, 1, &end_validity_int);
243
244 Dart_Handle x509_class =
245 DartUtils::GetDartClass(DartUtils::kIOLibURL, "X509Certificate");
246 Dart_Handle arguments[] = { subject_name_object,
247 issuer_name_object,
248 start_validity_date,
249 end_validity_date };
250 Dart_Handle certificate = Dart_New(x509_class, Dart_Null(), 4, arguments);
251
252 Dart_Handle result =
253 ThrowIfError(Dart_InvokeClosure(callback, 1, &certificate));
254 bool c_result = Dart_IsBoolean(result) && DartUtils::GetBooleanValue(result);
255 Dart_ExitScope();
256 return c_result;
257 }
258
259
208 void SSLFilter::Init(Dart_Handle dart_this) { 260 void SSLFilter::Init(Dart_Handle dart_this) {
209 string_start_ = ThrowIfError( 261 string_start_ = ThrowIfError(
210 Dart_NewPersistentHandle(DartUtils::NewString("start"))); 262 Dart_NewPersistentHandle(DartUtils::NewString("start")));
211 string_length_ = ThrowIfError( 263 string_length_ = ThrowIfError(
212 Dart_NewPersistentHandle(DartUtils::NewString("length"))); 264 Dart_NewPersistentHandle(DartUtils::NewString("length")));
213 265
214 InitializeBuffers(dart_this); 266 InitializeBuffers(dart_this);
215 filter_ = memio_CreateIOLayer(kMemioBufferSize); 267 filter_ = memio_CreateIOLayer(kMemioBufferSize);
216 } 268 }
217 269
(...skipping 27 matching lines...) Expand all
245 } 297 }
246 } 298 }
247 299
248 300
249 void SSLFilter::RegisterHandshakeCompleteCallback(Dart_Handle complete) { 301 void SSLFilter::RegisterHandshakeCompleteCallback(Dart_Handle complete) {
250 ASSERT(NULL == handshake_complete_); 302 ASSERT(NULL == handshake_complete_);
251 handshake_complete_ = ThrowIfError(Dart_NewPersistentHandle(complete)); 303 handshake_complete_ = ThrowIfError(Dart_NewPersistentHandle(complete));
252 } 304 }
253 305
254 306
307 void SSLFilter::RegisterBadCertificateCallback(Dart_Handle complete) {
308 if (NULL != bad_certificate_callback_) {
309 Dart_DeletePersistentHandle(bad_certificate_callback_);
310 }
311 bad_certificate_callback_ = ThrowIfError(Dart_NewPersistentHandle(complete));
312 }
313
314
255 void SSLFilter::InitializeLibrary(const char* certificate_database, 315 void SSLFilter::InitializeLibrary(const char* certificate_database,
256 const char* password, 316 const char* password,
257 bool use_builtin_root_certificates) { 317 bool use_builtin_root_certificates) {
258 MutexLocker locker(&mutex_); 318 MutexLocker locker(&mutex_);
259 if (!library_initialized_) { 319 if (!library_initialized_) {
260 library_initialized_ = true; 320 library_initialized_ = true;
261 password_ = strdup(password); // This one copy persists until Dart exits. 321 password_ = strdup(password); // This one copy persists until Dart exits.
262 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); 322 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
263 // TODO(whesse): Verify there are no UTF-8 issues here. 323 // TODO(whesse): Verify there are no UTF-8 issues here.
264 PRUint32 init_flags = NSS_INIT_READONLY; 324 PRUint32 init_flags = NSS_INIT_READONLY;
(...skipping 29 matching lines...) Expand all
294 status = SSL_ConfigServerSessionIDCache(0, 0, 0, NULL); 354 status = SSL_ConfigServerSessionIDCache(0, 0, 0, NULL);
295 if (status != SECSuccess) { 355 if (status != SECSuccess) {
296 ThrowPRException("Unsuccessful SSL_ConfigServerSessionIDCache call."); 356 ThrowPRException("Unsuccessful SSL_ConfigServerSessionIDCache call.");
297 } 357 }
298 358
299 } else { 359 } else {
300 ThrowException("Called SSLFilter::InitializeLibrary more than once"); 360 ThrowException("Called SSLFilter::InitializeLibrary more than once");
301 } 361 }
302 } 362 }
303 363
364
304 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) { 365 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) {
305 if (!retry) { 366 if (!retry) {
306 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals. 367 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals.
307 } 368 }
308 return NULL; 369 return NULL;
309 } 370 }
310 371
372
373 SECStatus BadCertificateCallback(void* filter, PRFileDesc* fd) {
374 return static_cast<SSLFilter*>(filter)->HandleBadCertificate(fd);
375 }
376
377
378 SECStatus SSLFilter::HandleBadCertificate(PRFileDesc* fd) {
379 ASSERT(fd == filter_);
380 CERTCertificate* certificate = SSL_PeerCertificate(fd);
381 PRTime start_validity;
382 PRTime end_validity;
383 SECStatus status =
384 CERT_GetCertTimes(certificate, &start_validity, &end_validity);
385 if (status != SECSuccess) {
386 ThrowPRException("Cannot get validity times from certificate");
387 }
388 int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC;
389 int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC;
390 bool accept = CallBadCertificateCallback(bad_certificate_callback_,
391 certificate->subjectName,
392 certificate->issuerName,
393 start_epoch_ms,
394 end_epoch_ms);
395 return accept ? SECSuccess : SECFailure;
396 }
397
398
311 void SSLFilter::Connect(const char* host_name, 399 void SSLFilter::Connect(const char* host_name,
312 int port, 400 int port,
313 bool is_server, 401 bool is_server,
314 const char* certificate_name) { 402 const char* certificate_name) {
315 is_server_ = is_server; 403 is_server_ = is_server;
316 if (in_handshake_) { 404 if (in_handshake_) {
317 ThrowException("Connect called while already in handshake state."); 405 ThrowException("Connect called while already in handshake state.");
318 } 406 }
319 407
320 filter_ = SSL_ImportFD(NULL, filter_); 408 filter_ = SSL_ImportFD(NULL, filter_);
(...skipping 30 matching lines...) Expand all
351 status = SSL_ConfigSecureServer(filter_, certificate, key, kt_rsa); 439 status = SSL_ConfigSecureServer(filter_, certificate, key, kt_rsa);
352 if (status != SECSuccess) { 440 if (status != SECSuccess) {
353 ThrowPRException("Unsuccessful SSL_ConfigSecureServer call"); 441 ThrowPRException("Unsuccessful SSL_ConfigSecureServer call");
354 } 442 }
355 } else { // Client. 443 } else { // Client.
356 if (SSL_SetURL(filter_, host_name) == -1) { 444 if (SSL_SetURL(filter_, host_name) == -1) {
357 ThrowPRException("Unsuccessful SetURL call"); 445 ThrowPRException("Unsuccessful SetURL call");
358 } 446 }
359 } 447 }
360 448
361 PRBool as_server = is_server ? PR_TRUE : PR_FALSE; // Convert bool to PRBool. 449 // Install bad certificate callback, and pass 'this' to it if it is called.
450 status = SSL_BadCertHook(filter_,
451 BadCertificateCallback,
452 static_cast<void*>(this));
453
454 PRBool as_server = is_server ? PR_TRUE : PR_FALSE;
362 status = SSL_ResetHandshake(filter_, as_server); 455 status = SSL_ResetHandshake(filter_, as_server);
363 if (status != SECSuccess) { 456 if (status != SECSuccess) {
364 ThrowPRException("Unsuccessful SSL_ResetHandshake call"); 457 ThrowPRException("Unsuccessful SSL_ResetHandshake call");
365 } 458 }
366 459
367 // SetPeerAddress 460 // SetPeerAddress
368 PRNetAddr host_address; 461 PRNetAddr host_address;
369 char host_entry_buffer[PR_NETDB_BUF_SIZE]; 462 char host_entry_buffer[PR_NETDB_BUF_SIZE];
370 PRHostEnt host_entry; 463 PRHostEnt host_entry;
371 PRStatus rv = PR_GetHostByName(host_name, host_entry_buffer, 464 PRStatus rv = PR_GetHostByName(host_name, host_entry_buffer,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 500
408 501
409 void SSLFilter::Destroy() { 502 void SSLFilter::Destroy() {
410 for (int i = 0; i < kNumBuffers; ++i) { 503 for (int i = 0; i < kNumBuffers; ++i) {
411 Dart_DeletePersistentHandle(dart_buffer_objects_[i]); 504 Dart_DeletePersistentHandle(dart_buffer_objects_[i]);
412 delete[] buffers_[i]; 505 delete[] buffers_[i];
413 } 506 }
414 Dart_DeletePersistentHandle(string_start_); 507 Dart_DeletePersistentHandle(string_start_);
415 Dart_DeletePersistentHandle(string_length_); 508 Dart_DeletePersistentHandle(string_length_);
416 Dart_DeletePersistentHandle(handshake_complete_); 509 Dart_DeletePersistentHandle(handshake_complete_);
510 if (bad_certificate_callback_ != NULL) {
511 Dart_DeletePersistentHandle(bad_certificate_callback_);
512 }
417 // TODO(whesse): Free NSS objects here. 513 // TODO(whesse): Free NSS objects here.
418 } 514 }
419 515
420 516
421 intptr_t SSLFilter::ProcessBuffer(int buffer_index) { 517 intptr_t SSLFilter::ProcessBuffer(int buffer_index) {
422 Dart_Handle buffer_object = dart_buffer_objects_[buffer_index]; 518 Dart_Handle buffer_object = dart_buffer_objects_[buffer_index];
423 Dart_Handle start_object = ThrowIfError( 519 Dart_Handle start_object = ThrowIfError(
424 Dart_GetField(buffer_object, string_start_)); 520 Dart_GetField(buffer_object, string_start_));
425 Dart_Handle length_object = ThrowIfError( 521 Dart_Handle length_object = ThrowIfError(
426 Dart_GetField(buffer_object, string_length_)); 522 Dart_GetField(buffer_object, string_length_));
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 if (PR_WOULD_BLOCK_ERROR != pr_error) { 605 if (PR_WOULD_BLOCK_ERROR != pr_error) {
510 ThrowPRException("Error reading plaintext from SSLFilter"); 606 ThrowPRException("Error reading plaintext from SSLFilter");
511 } 607 }
512 bytes_processed = 0; 608 bytes_processed = 0;
513 } 609 }
514 break; 610 break;
515 } 611 }
516 } 612 }
517 return bytes_processed; 613 return bytes_processed;
518 } 614 }
OLDNEW
« no previous file with comments | « runtime/bin/secure_socket.h ('k') | runtime/bin/secure_socket_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698