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

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: 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
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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 ThrowException("Called SSLFilter::InitializeLibrary more than once"); 360 ThrowException("Called SSLFilter::InitializeLibrary more than once");
301 } 361 }
302 } 362 }
303 363
304 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) { 364 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) {
305 if (!retry) { 365 if (!retry) {
306 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals. 366 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals.
307 } 367 }
308 return NULL; 368 return NULL;
309 } 369 }
310 370
Mads Ager (google) 2012/12/05 07:30:53 Inconsistent spacing. Two new lines between other
Bill Hesse 2012/12/05 12:35:38 Done.
371 SECStatus BadCertificateCallback(void* filter, PRFileDesc* fd) {
372 return static_cast<SSLFilter*>(filter)->HandleBadCertificate(fd);
373 }
374
375 SECStatus SSLFilter::HandleBadCertificate(PRFileDesc* fd) {
376 ASSERT(fd == filter_);
377 // PRInt32 error_code = PR_GetError();
Mads Ager (google) 2012/12/05 07:30:53 Remove.
Bill Hesse 2012/12/05 12:35:38 Done.
378 CERTCertificate* certificate = SSL_PeerCertificate(fd);
379 PRTime start_validity;
380 PRTime end_validity;
381 SECStatus status =
382 CERT_GetCertTimes(certificate, &start_validity, &end_validity);
383 if (status != SECSuccess) {
384 ThrowPRException("Cannot get validity times from certificate");
385 }
386
387 int64_t start_epoch_ms =
388 static_cast<int64_t>(start_validity) / PR_USEC_PER_MSEC;
Mads Ager (google) 2012/12/05 07:30:53 Do you get warnings if you do not have the static
389 int64_t end_epoch_ms =
390 static_cast<int64_t>(end_validity) / PR_USEC_PER_MSEC;
391
392 return CallBadCertificateCallback(bad_certificate_callback_,
Mads Ager (google) 2012/12/05 07:30:53 I would find it easier to read if this was: bool
Bill Hesse 2012/12/05 12:35:38 Done.
393 certificate->subjectName,
394 certificate->issuerName,
395 start_epoch_ms,
396 end_epoch_ms)
397 ? SECSuccess
398 : SECFailure;
399 }
400
401
311 void SSLFilter::Connect(const char* host_name, 402 void SSLFilter::Connect(const char* host_name,
312 int port, 403 int port,
313 bool is_server, 404 bool is_server,
314 const char* certificate_name) { 405 const char* certificate_name) {
315 is_server_ = is_server; 406 is_server_ = is_server;
316 if (in_handshake_) { 407 if (in_handshake_) {
317 ThrowException("Connect called while already in handshake state."); 408 ThrowException("Connect called while already in handshake state.");
318 } 409 }
319 410
320 filter_ = SSL_ImportFD(NULL, filter_); 411 filter_ = SSL_ImportFD(NULL, filter_);
(...skipping 30 matching lines...) Expand all
351 status = SSL_ConfigSecureServer(filter_, certificate, key, kt_rsa); 442 status = SSL_ConfigSecureServer(filter_, certificate, key, kt_rsa);
352 if (status != SECSuccess) { 443 if (status != SECSuccess) {
353 ThrowPRException("Unsuccessful SSL_ConfigSecureServer call"); 444 ThrowPRException("Unsuccessful SSL_ConfigSecureServer call");
354 } 445 }
355 } else { // Client. 446 } else { // Client.
356 if (SSL_SetURL(filter_, host_name) == -1) { 447 if (SSL_SetURL(filter_, host_name) == -1) {
357 ThrowPRException("Unsuccessful SetURL call"); 448 ThrowPRException("Unsuccessful SetURL call");
358 } 449 }
359 } 450 }
360 451
361 PRBool as_server = is_server ? PR_TRUE : PR_FALSE; // Convert bool to PRBool. 452 PRBool as_server = is_server ? PR_TRUE : PR_FALSE;
Bill Hesse 2012/12/04 19:02:09 Whoops - I'll move this down below the new stuff.
453
454 // Install bad certificate callback, and pass 'this' to it if it is called.
455 status = SSL_BadCertHook(filter_,
456 BadCertificateCallback,
457 static_cast<void *>(this));
Mads Ager (google) 2012/12/05 07:30:53 void * -> void*
Bill Hesse 2012/12/05 12:35:38 Done.
458
362 status = SSL_ResetHandshake(filter_, as_server); 459 status = SSL_ResetHandshake(filter_, as_server);
363 if (status != SECSuccess) { 460 if (status != SECSuccess) {
364 ThrowPRException("Unsuccessful SSL_ResetHandshake call"); 461 ThrowPRException("Unsuccessful SSL_ResetHandshake call");
365 } 462 }
366 463
367 // SetPeerAddress 464 // SetPeerAddress
368 PRNetAddr host_address; 465 PRNetAddr host_address;
369 char host_entry_buffer[PR_NETDB_BUF_SIZE]; 466 char host_entry_buffer[PR_NETDB_BUF_SIZE];
370 PRHostEnt host_entry; 467 PRHostEnt host_entry;
371 PRStatus rv = PR_GetHostByName(host_name, host_entry_buffer, 468 PRStatus rv = PR_GetHostByName(host_name, host_entry_buffer,
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 if (PR_WOULD_BLOCK_ERROR != pr_error) { 606 if (PR_WOULD_BLOCK_ERROR != pr_error) {
510 ThrowPRException("Error reading plaintext from SSLFilter"); 607 ThrowPRException("Error reading plaintext from SSLFilter");
511 } 608 }
512 bytes_processed = 0; 609 bytes_processed = 0;
513 } 610 }
514 break; 611 break;
515 } 612 }
516 } 613 }
517 return bytes_processed; 614 return bytes_processed;
518 } 615 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698