@@ -953,6 +953,104 @@ 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+ }
1009+
1010+ /* Check OCSP response */
1011+ ret = cm .CertManagerCheckOCSPResponse (ocspData );
1012+ if (ret != WolfSSL .SSL_SUCCESS ) {
1013+ throw new CertificateException (
1014+ "OCSP response validation failed: " + ret );
1015+ }
1016+
1017+ WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
1018+ () -> "OCSP response validation successful" );
1019+
1020+ } catch (WolfSSLException e ) {
1021+ if (e .getMessage ().contains ("not compiled" )) {
1022+ /* OCSP not available, log and continue */
1023+ WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
1024+ () -> "OCSP support not available, skipping " +
1025+ "OCSP validation" );
1026+ } else {
1027+ throw new CertificateException ("OCSP validation error" , e );
1028+ }
1029+ } finally {
1030+ if (cm != null ) {
1031+ cm .free ();
1032+ }
1033+ }
1034+
1035+ } else {
1036+ WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
1037+ () -> "No OCSP data provided" );
1038+ }
1039+
1040+ /* Ignore TLS SCT data as wolfSSL doesn't support it */
1041+ if (tlsSctData != null && tlsSctData .length > 0 ) {
1042+ WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
1043+ () -> "TLS SCT data provided (" + tlsSctData .length +
1044+ " bytes), currently not processed" );
1045+ }
1046+
1047+ WolfSSLDebug .log (getClass (), WolfSSLDebug .INFO ,
1048+ () -> "leaving checkServerTrusted(chain, ocspData, tlsSctData, " +
1049+ "authType, host), success" );
1050+
1051+ return certList ;
1052+ }
1053+
9561054 /**
9571055 * Returns an array of certificate authorities which are trusted for
9581056 * authenticating peers.
0 commit comments