Adds SSLCertificateVerifier to the Java API.

The native API supports setting an SSLCertificateVerifier that can be used
to provide a custom certificate verifier for incoming SSL certificates. This
change provides this functionality to the Java API so that a Java implementation
can also be provided. It is expected this will only be used in specialized
circumstances and most users will not hit this code path.

Bug: webrtc:9541
Change-Id: Id3c75b8f288333b53edc2959bac533e3ec614978
Reviewed-on: https://webrtc-review.googlesource.com/89500
Commit-Queue: Benjamin Wright <benwright@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24057}
diff --git a/sdk/android/api/org/webrtc/PeerConnectionDependencies.java b/sdk/android/api/org/webrtc/PeerConnectionDependencies.java
index 8ecf0ff..fd765b1 100644
--- a/sdk/android/api/org/webrtc/PeerConnectionDependencies.java
+++ b/sdk/android/api/org/webrtc/PeerConnectionDependencies.java
@@ -20,18 +20,27 @@
  */
 public final class PeerConnectionDependencies {
   // Mandatory dependencies.
-  private PeerConnection.Observer observer;
+  private final PeerConnection.Observer observer;
+
+  // Optional fields.
+  private final SSLCertificateVerifier sslCertificateVerifier;
 
   public static class Builder {
     private PeerConnection.Observer observer;
+    private SSLCertificateVerifier sslCertificateVerifier;
 
     private Builder(PeerConnection.Observer observer) {
       this.observer = observer;
     }
 
+    public Builder setSSLCertificateVerifier(SSLCertificateVerifier sslCertificateVerifier) {
+      this.sslCertificateVerifier = sslCertificateVerifier;
+      return this;
+    }
+
     // Observer is a required dependency and so is forced in the construction of the object.
     public PeerConnectionDependencies createPeerConnectionDependencies() {
-      return new PeerConnectionDependencies(observer);
+      return new PeerConnectionDependencies(observer, sslCertificateVerifier);
     }
   }
 
@@ -43,7 +52,14 @@
     return observer;
   }
 
-  private PeerConnectionDependencies(PeerConnection.Observer observer) {
+  @Nullable
+  SSLCertificateVerifier getSSLCertificateVerifier() {
+    return sslCertificateVerifier;
+  }
+
+  private PeerConnectionDependencies(
+      PeerConnection.Observer observer, SSLCertificateVerifier sslCertificateVerifier) {
     this.observer = observer;
+    this.sslCertificateVerifier = sslCertificateVerifier;
   }
 }
diff --git a/sdk/android/api/org/webrtc/PeerConnectionFactory.java b/sdk/android/api/org/webrtc/PeerConnectionFactory.java
index e4e881f..3a76d7c 100644
--- a/sdk/android/api/org/webrtc/PeerConnectionFactory.java
+++ b/sdk/android/api/org/webrtc/PeerConnectionFactory.java
@@ -329,6 +329,25 @@
   }
 
   /**
+   * Internal helper function to pass the parameters down into the native JNI bridge.
+   */
+  @Nullable
+  PeerConnection createPeerConnectionInternal(PeerConnection.RTCConfiguration rtcConfig,
+      MediaConstraints constraints, PeerConnection.Observer observer,
+      SSLCertificateVerifier sslCertificateVerifier) {
+    long nativeObserver = PeerConnection.createNativePeerConnectionObserver(observer);
+    if (nativeObserver == 0) {
+      return null;
+    }
+    long nativePeerConnection = nativeCreatePeerConnection(
+        nativeFactory, rtcConfig, constraints, nativeObserver, sslCertificateVerifier);
+    if (nativePeerConnection == 0) {
+      return null;
+    }
+    return new PeerConnection(nativePeerConnection);
+  }
+
+  /**
    * Deprecated. PeerConnection constraints are deprecated. Supply values in rtcConfig struct
    * instead and use the method without constraints in the signature.
    */
@@ -336,16 +355,8 @@
   @Deprecated
   public PeerConnection createPeerConnection(PeerConnection.RTCConfiguration rtcConfig,
       MediaConstraints constraints, PeerConnection.Observer observer) {
-    long nativeObserver = PeerConnection.createNativePeerConnectionObserver(observer);
-    if (nativeObserver == 0) {
-      return null;
-    }
-    long nativePeerConnection =
-        nativeCreatePeerConnection(nativeFactory, rtcConfig, constraints, nativeObserver);
-    if (nativePeerConnection == 0) {
-      return null;
-    }
-    return new PeerConnection(nativePeerConnection);
+    return createPeerConnectionInternal(
+        rtcConfig, constraints, observer, /* sslCertificateVerifier= */ null);
   }
 
   /**
@@ -376,7 +387,8 @@
   @Nullable
   public PeerConnection createPeerConnection(
       PeerConnection.RTCConfiguration rtcConfig, PeerConnectionDependencies dependencies) {
-    return createPeerConnection(rtcConfig, null /* constraints */, dependencies.getObserver());
+    return createPeerConnectionInternal(rtcConfig, null /* constraints */,
+        dependencies.getObserver(), dependencies.getSSLCertificateVerifier());
   }
 
   public MediaStream createLocalMediaStream(String label) {
@@ -514,7 +526,8 @@
       VideoDecoderFactory decoderFactory, long nativeAudioProcessor,
       long nativeFecControllerFactory);
   private static native long nativeCreatePeerConnection(long factory,
-      PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver);
+      PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver,
+      SSLCertificateVerifier sslCertificateVerifier);
   private static native long nativeCreateLocalMediaStream(long factory, String label);
   private static native long nativeCreateVideoSource(long factory, boolean is_screencast);
   private static native long nativeCreateVideoTrack(
diff --git a/sdk/android/api/org/webrtc/SSLCertificateVerifier.java b/sdk/android/api/org/webrtc/SSLCertificateVerifier.java
new file mode 100644
index 0000000..461cd3b
--- /dev/null
+++ b/sdk/android/api/org/webrtc/SSLCertificateVerifier.java
@@ -0,0 +1,27 @@
+/*
+ *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+package org.webrtc;
+
+/**
+ * The SSLCertificateVerifier interface allows API users to provide custom
+ * logic to verify certificates.
+ */
+public interface SSLCertificateVerifier {
+  /**
+   * Implementations of verify allow applications to provide custom logic for
+   * verifying certificates. This is not required by default and should be used
+   * with care.
+   *
+   * @param certificate A byte array containing a DER encoded X509 certificate.
+   * @return True if the certificate is verified and trusted else false.
+   */
+  @CalledByNative boolean verify(byte[] certificate);
+}