Fix breakages in https://codereview.chromium.org/1155713003/
[chromium-blink-merge.git] / ios / web / web_state / wk_web_view_ssl_error_util.mm
blob18b38f89955e7eca8b45c92d231d1b8d8c9703dd
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "ios/web/web_state/wk_web_view_ssl_error_util.h"
7 #include "base/strings/sys_string_conversions.h"
8 #include "net/cert/x509_certificate.h"
9 #include "net/ssl/ssl_info.h"
11 namespace web {
13 // This key was determined by inspecting userInfo dict of an SSL error.
14 NSString* const kNSErrorPeerCertificateChainKey =
15     @"NSErrorPeerCertificateChainKey";
19 namespace {
21 // Creates certificate from subject string.
22 net::X509Certificate* CreateCertFromSubject(NSString* subject) {
23   std::string issuer = "";
24   base::Time start_date;
25   base::Time expiration_date;
26   return new net::X509Certificate(base::SysNSStringToUTF8(subject),
27                                   issuer,
28                                   start_date,
29                                   expiration_date);
32 // Creates certificate from array of SecCertificateRef objects.
33 net::X509Certificate* CreateCertFromChain(NSArray* certs) {
34   if (certs.count == 0)
35     return nullptr;
36   net::X509Certificate::OSCertHandles intermediates;
37   for (NSUInteger i = 1; i < certs.count; i++) {
38     intermediates.push_back(reinterpret_cast<SecCertificateRef>(certs[i]));
39   }
40   return net::X509Certificate::CreateFromHandle(
41       reinterpret_cast<SecCertificateRef>(certs[0]), intermediates);
44 // Creates certificate using information extracted from NSError.
45 net::X509Certificate* CreateCertFromSSLError(NSError* error) {
46   net::X509Certificate* cert = CreateCertFromChain(
47       error.userInfo[web::kNSErrorPeerCertificateChainKey]);
48   if (cert)
49     return cert;
50   return CreateCertFromSubject(
51       error.userInfo[NSURLErrorFailingURLStringErrorKey]);
54 // Maps NSError code to net::CertStatus.
55 net::CertStatus GetCertStatusFromNSErrorCode(NSInteger code) {
56   switch (code) {
57     // Regardless of real certificate problem the system always returns
58     // NSURLErrorServerCertificateUntrusted. The mapping is done in case this
59     // bug is fixed (rdar://18517043).
60     case NSURLErrorServerCertificateUntrusted:
61     case NSURLErrorSecureConnectionFailed:
62     case NSURLErrorServerCertificateHasUnknownRoot:
63     case NSURLErrorClientCertificateRejected:
64     case NSURLErrorClientCertificateRequired:
65       return net::CERT_STATUS_INVALID;
66     case NSURLErrorServerCertificateHasBadDate:
67     case NSURLErrorServerCertificateNotYetValid:
68       return net::CERT_STATUS_DATE_INVALID;
69   }
70   NOTREACHED();
71   return 0;
74 }  // namespace
77 namespace web {
79 BOOL IsWKWebViewSSLError(NSError* error) {
80   // SSL errors range is (-2000..-1200], represented by kCFURLError constants:
81   // (kCFURLErrorCannotLoadFromNetwork..kCFURLErrorSecureConnectionFailed].
82   // It's reasonable to expect that all SSL errors will have the error code
83   // less or equal to NSURLErrorSecureConnectionFailed but greater than
84   // NSURLErrorCannotLoadFromNetwork.
85   return [error.domain isEqualToString:NSURLErrorDomain] &&
86          (error.code <= NSURLErrorSecureConnectionFailed &&
87           NSURLErrorCannotLoadFromNetwork < error.code);
90 void GetSSLInfoFromWKWebViewSSLError(NSError* error, net::SSLInfo* ssl_info) {
91   DCHECK(IsWKWebViewSSLError(error));
92   ssl_info->cert_status = GetCertStatusFromNSErrorCode(error.code);
93   ssl_info->cert = CreateCertFromSSLError(error);
96 }  // namespace web