Bug 790809 - Add callback for in libpkix for extra app checks (in usage sslserver). r=dkeeler
authorCamilo Viecco <cviecco@mozilla.com>
Wed, 05 Feb 2014 14:49:14 -0800
changeset 167565 d2afdb4177dd84980ecf89370aaa68f9e34f8f01
parent 167564 24ad87cccbe5ce0cdb8b94991917b1226477d9e1
child 167566 3a10c46057955b7000a0ad917094d7fb668bb3db
push id26174
push userkwierso@gmail.com
push dateSat, 08 Feb 2014 00:55:48 +0000
treeherdermozilla-central@2c873eff7dc2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdkeeler
bugs790809
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 790809 - Add callback for in libpkix for extra app checks (in usage sslserver). r=dkeeler
security/certverifier/CertVerifier.cpp
--- a/security/certverifier/CertVerifier.cpp
+++ b/security/certverifier/CertVerifier.cpp
@@ -88,16 +88,34 @@ insertErrorIntoVerifyLog(CERTCertificate
     verifyLog->tail = node;
   }
   verifyLog->count++;
 
   return SECSuccess;
 }
 #endif
 
+SECStatus chainValidationCallback(void* state, const CERTCertList* certList,
+                                  PRBool* chainOK)
+{
+  *chainOK = PR_FALSE;
+
+  PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, ("verifycert: Inside the Callback \n"));
+
+  // On sanity failure we fail closed.
+  if (!certList) {
+    PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, ("verifycert: Short circuit, callback, "
+                                            "sanity check failed \n"));
+    PR_SetError(PR_INVALID_STATE_ERROR, 0);
+    return SECFailure;
+  }
+  *chainOK = PR_TRUE;
+  return SECSuccess;
+}
+
 static SECStatus
 ClassicVerifyCert(CERTCertificate* cert,
                   const SECCertificateUsage usage,
                   const PRTime time,
                   void* pinArg,
                   /*optional out*/ ScopedCERTCertList* validationChain,
                   /*optional out*/ CERTVerifyLog* verifyLog)
 {
@@ -295,26 +313,36 @@ CertVerifier::VerifyCert(CERTCertificate
   rev.chainTests.cert_rev_flags_per_method = revFlagsPerMethod;
   rev.leafTests.number_of_preferred_methods =
   rev.chainTests.number_of_preferred_methods = 1;
 
   rev.leafTests.number_of_defined_methods =
   rev.chainTests.number_of_defined_methods = cert_revocation_method_ocsp + 1;
 
   const bool localOnly = flags & FLAG_LOCAL_ONLY;
-  CERTValInParam cvin[6];
+  CERTValInParam cvin[7];
 
   // Parameters for both EV and DV validation
   cvin[0].type = cert_pi_useAIACertFetch;
   cvin[0].value.scalar.b = mMissingCertDownloadEnabled && !localOnly;
   cvin[1].type = cert_pi_revocationFlags;
   cvin[1].value.pointer.revocation = &rev;
   cvin[2].type = cert_pi_date;
   cvin[2].value.scalar.time = time;
   i = 3;
+
+  CERTChainVerifyCallback callbackContainer;
+  if (usage == certificateUsageSSLServer) {
+    callbackContainer.isChainValid = chainValidationCallback;
+    callbackContainer.isChainValidArg = nullptr;
+    cvin[i].type = cert_pi_chainVerifyCallback;
+    cvin[i].value.pointer.chainVerifyCallback = &callbackContainer;
+    ++i;
+  }
+
   const size_t evParamLocation = i;
 
   if (evPolicy != SEC_OID_UNKNOWN) {
     // EV setup!
     // XXX 859872 The current flags are not quite correct. (use
     // of ocsp flags for crl preferences).
     uint64_t ocspRevMethodFlags =
       CERT_REV_M_TEST_USING_THIS_METHOD