@@ -953,6 +953,105 @@ public List<X509Certificate> checkServerTrusted(X509Certificate[] certs,
953953 return certList ;
954954 }
955955
956+ /**
957+ * Verifies a specified certificate chain.
958+ * Non standard API, this is called/needed by Android.
959+ *
960+ * Android expects this method signature for OCSP stapling support.
961+ * Native wolfSSL supports OCSP response processing via
962+ * wolfSSL_CertManagerCheckOCSPResponse(). The ocspData parameter
963+ * contains DER-encoded OCSP response data that is processed for
964+ * certificate revocation checking.
965+ *
966+ * @param chain Certificate chain to validate
967+ * @param ocspData OCSP response data (DER-encoded), may be null
968+ * @param tlsSctData TLS SCT data (unused, wolfSSL does not support SCT)
969+ * @param authType Authentication type
970+ * @param host Hostname of the server
971+ *
972+ * @return Certificate chain used for verification, ordered with leaf/peer
973+ * cert first, root CA cert last
974+ *
975+ * @throws CertificateException if chain does not verify properly
976+ */
977+ public List <X509Certificate > checkServerTrusted (X509Certificate [] chain ,
978+ byte [] ocspData , byte [] tlsSctData , String authType , String host )
979+ throws CertificateException {
980+
981+ int ret ;
982+ WolfSSLCertManager cm = null ;
983+
984+ WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
985+ () -> "entered checkServerTrusted(chain, ocspData, tlsSctData, " +
986+ "authType, host)" );
987+
988+ /* First verify the certificate chain normally, throws exception
989+ * if chain is invalid */
990+ List <X509Certificate > certList =
991+ checkServerTrusted (chain , authType , host );
992+
993+ /* Verify OCSP response data if provided */
994+ if (ocspData != null && ocspData .length > 0 ) {
995+
996+ WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
997+ () -> "Verifying OCSP response data (" + ocspData .length +
998+ " bytes)" );
999+
1000+ try {
1001+ cm = new WolfSSLCertManager ();
1002+
1003+ /* Load the trusted CAs that were used for cert verification */
1004+ ret = cm .CertManagerLoadCAKeyStore (this .store );
1005+ if (ret != WolfSSL .SSL_SUCCESS ) {
1006+ throw new CertificateException (
1007+ "Failed to load trusted CAs for OCSP verification, " +
1008+ "ret = " + ret );
1009+ }
1010+
1011+ /* Check OCSP response */
1012+ ret = cm .CertManagerCheckOCSPResponse (ocspData );
1013+ if (ret != WolfSSL .SSL_SUCCESS ) {
1014+ throw new CertificateException (
1015+ "OCSP response validation failed: " + ret );
1016+ }
1017+
1018+ WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
1019+ () -> "OCSP response validation successful" );
1020+
1021+ } catch (WolfSSLException e ) {
1022+ if (e .getMessage ().contains ("not compiled" )) {
1023+ /* OCSP not available, log and continue */
1024+ WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
1025+ () -> "OCSP support not available, skipping " +
1026+ "OCSP validation" );
1027+ } else {
1028+ throw new CertificateException ("OCSP validation error" , e );
1029+ }
1030+ } finally {
1031+ if (cm != null ) {
1032+ cm .free ();
1033+ }
1034+ }
1035+
1036+ } else {
1037+ WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
1038+ () -> "No OCSP data provided" );
1039+ }
1040+
1041+ /* Ignore TLS SCT data as wolfSSL doesn't support it */
1042+ if (tlsSctData != null && tlsSctData .length > 0 ) {
1043+ WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
1044+ () -> "TLS SCT data provided (" + tlsSctData .length +
1045+ " bytes), currently not processed" );
1046+ }
1047+
1048+ WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
1049+ () -> "leaving checkServerTrusted(chain, ocspData, tlsSctData, " +
1050+ "authType, host), success" );
1051+
1052+ return certList ;
1053+ }
1054+
9561055 /**
9571056 * Returns an array of certificate authorities which are trusted for
9581057 * authenticating peers.
0 commit comments