// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import <Cocoa/Cocoa.h>
#import <SecurityInterface/SFCertificatePanel.h>

#include "base/mac/foundation_util.h"
#include "base/mac/scoped_cftyperef.h"
#import "base/mac/scoped_nsobject.h"
#include "chrome/browser/certificate_viewer.h"
#include "components/constrained_window/constrained_window_views.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/web_contents.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util_ios_and_mac.h"
#include "net/cert/x509_util_mac.h"
#include "ui/base/cocoa/remote_views_window.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

@interface SFCertificatePanel (SystemPrivate)
// A system-private interface that dismisses a panel whose sheet was started by
// -beginSheetForWindow:
//        modalDelegate:
//       didEndSelector:
//          contextInfo:
//         certificates:
//            showGroup:
// as though the user clicked the button identified by returnCode. Verified
// present in 10.8.
- (void)_dismissWithCode:(NSInteger)code;
@end

@interface SSLCertificateViewerMac : NSObject

// Initializes |certificates_| with the certificate chain for a given
// certificate.
- (instancetype)initWithCertificate:(net::X509Certificate*)certificate
                     forWebContents:(content::WebContents*)webContents;

// Shows the certificate viewer as a Cocoa sheet.
- (void)showCertificateSheet:(NSWindow*)window;

// Closes the certificate viewer sheet.
- (void)closeCertificateSheet;

- (void)setOverlayWindow:(views::Widget*)overlayWindow;

// Closes the certificate viewer Cocoa sheet.
- (void)sheetDidEnd:(NSWindow*)parent
         returnCode:(NSInteger)returnCode
            context:(void*)context;
@end

@implementation SSLCertificateViewerMac {
  // The corresponding list of certificates.
  base::scoped_nsobject<NSArray> certificates_;
  base::scoped_nsobject<SFCertificatePanel> panel_;

  // Invisible overlay window used to block interaction with the tab underneath.
  views::Widget* overlayWindow_;
}

- (instancetype)initWithCertificate:(net::X509Certificate*)certificate
                     forWebContents:(content::WebContents*)webContents {
  if ((self = [super init])) {
    base::ScopedCFTypeRef<CFArrayRef> certChain(
        net::x509_util::CreateSecCertificateArrayForX509Certificate(
            certificate));
    if (!certChain)
      return self;
    NSArray* certificates = base::mac::CFToNSCast(certChain.get());
    certificates_.reset([certificates retain]);
  }

  // Explicitly disable revocation checking, regardless of user preferences
  // or system settings. The behaviour of SFCertificatePanel is to call
  // SecTrustEvaluate on the certificate(s) supplied, effectively
  // duplicating the behaviour of net::X509Certificate::Verify(). However,
  // this call stalls the UI if revocation checking is enabled in the
  // Keychain preferences or if the cert may be an EV cert. By disabling
  // revocation checking, the stall is limited to the time taken for path
  // building and verification, which should be minimized due to the path
  // being provided in |certificates|. This does not affect normal
  // revocation checking from happening, which is controlled by
  // net::X509Certificate::Verify() and user preferences, but will prevent
  // the certificate viewer UI from displaying which certificate is revoked.
  // This is acceptable, as certificate revocation will still be shown in
  // the page info bubble if a certificate in the chain is actually revoked.
  base::ScopedCFTypeRef<CFMutableArrayRef> policies(
      CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
  if (!policies.get()) {
    NOTREACHED();
    return self;
  }
  // Add a basic X.509 policy, in order to match the behaviour of
  // SFCertificatePanel when no policies are specified.
  base::ScopedCFTypeRef<SecPolicyRef> basicPolicy;
  OSStatus status =
      net::x509_util::CreateBasicX509Policy(basicPolicy.InitializeInto());
  if (status != noErr) {
    NOTREACHED();
    return self;
  }
  CFArrayAppendValue(policies, basicPolicy.get());

  status = net::x509_util::CreateRevocationPolicies(false, policies);
  if (status != noErr) {
    NOTREACHED();
    return self;
  }

  panel_.reset([[SFCertificatePanel alloc] init]);
  [panel_ setPolicies:base::mac::CFToNSCast(policies.get())];
  return self;
}

- (void)showCertificateSheet:(NSWindow*)window {
  [panel_ beginSheetForWindow:window
                modalDelegate:self
               didEndSelector:@selector(sheetDidEnd:returnCode:context:)
                  contextInfo:nil
                 certificates:certificates_
                    showGroup:YES];
}

- (void)closeCertificateSheet {
  // Closing the sheet using -[NSApp endSheet:] doesn't work so use the private
  // method. If the sheet is already closed then this is a call on nil and thus
  // a no-op.
  [panel_ _dismissWithCode:NSModalResponseCancel];
}

- (void)sheetDidEnd:(NSWindow*)parent
         returnCode:(NSInteger)returnCode
            context:(void*)context {
  overlayWindow_->Close();  // Asynchronously releases |self|.
  panel_.reset();
}

- (void)setOverlayWindow:(views::Widget*)overlayWindow {
  overlayWindow_ = overlayWindow;
}

@end

namespace {

// A fully transparent, borderless web-modal dialog used to display the
// OS-provided window-modal sheet that displays certificate information.
class CertificateAnchorWidgetDelegate : public views::WidgetDelegateView {
 public:
  CertificateAnchorWidgetDelegate(content::WebContents* web_contents,
                                  net::X509Certificate* cert)
      : certificate_viewer_([[SSLCertificateViewerMac alloc]
            initWithCertificate:cert
                 forWebContents:web_contents]) {
    views::Widget* overlayWindow =
        constrained_window::ShowWebModalDialogWithOverlayViews(this,
                                                               web_contents);
    NSWindow* overlayNSWindow =
        overlayWindow->GetNativeWindow().GetNativeNSWindow();
    // TODO(https://crbug.com/913303): The certificate viewer's interface to
    // Cocoa should be wrapped in a mojo interface in order to allow
    // instantiating across processes. As a temporary solution, create a
    // transparent in-process window to the front.
    if (ui::IsWindowUsingRemoteViews(overlayNSWindow)) {
      remote_views_clone_window_ =
          ui::CreateTransparentRemoteViewsClone(overlayNSWindow);
      overlayNSWindow = remote_views_clone_window_;
    }
    [certificate_viewer_ showCertificateSheet:overlayNSWindow];
    [certificate_viewer_ setOverlayWindow:overlayWindow];
  }

  ~CertificateAnchorWidgetDelegate() override {
    // Note that the SFCertificatePanel takes a reference to its delegate in its
    // -beginSheetForWindow:... method (bad SFCertificatePanel!) so break the
    // retain cycle by explicitly canceling the dialog.
    [certificate_viewer_ closeCertificateSheet];
    [remote_views_clone_window_ close];
  }

  // WidgetDelegate:
  ui::ModalType GetModalType() const override { return ui::MODAL_TYPE_CHILD; }

 private:
  base::scoped_nsobject<SSLCertificateViewerMac> certificate_viewer_;
  NSWindow* remote_views_clone_window_ = nil;

  DISALLOW_COPY_AND_ASSIGN(CertificateAnchorWidgetDelegate);
};

}  // namespace

void ShowCertificateViewer(content::WebContents* web_contents,
                           gfx::NativeWindow parent,
                           net::X509Certificate* cert) {
  // Shows a new widget, which owns the delegate.
  new CertificateAnchorWidgetDelegate(web_contents, cert);
}
