diff --git a/lib/SimpleSAML/Utilities.php b/lib/SimpleSAML/Utilities.php
index 2e823a24a3d6659cea2e84b4eeedcebc160a4e91..409ceb444ddba4ef805c5ac625c6199d2085d82c 100644
--- a/lib/SimpleSAML/Utilities.php
+++ b/lib/SimpleSAML/Utilities.php
@@ -1798,6 +1798,131 @@ class SimpleSAML_Utilities {
 			);
 	}
 
+
+	/**
+	 * Validate a certificate against a CA file, by using the builtin
+	 * openssl_x509_checkpurpose function
+	 *
+	 * @param string $certificate  The certificate, in PEM format.
+	 * @param string $caFile  File with trusted certificates, in PEM-format.
+	 * @return boolean|string TRUE on success, or a string with error messages if it failed.
+	 */
+	private static function validateCABuiltIn($certificate, $caFile) {
+		assert('is_string($certificate)');
+		assert('is_string($caFile)');
+
+		/* Clear openssl errors. */
+		while(openssl_error_string() !== FALSE);
+
+		$res = openssl_x509_checkpurpose($certificate, X509_PURPOSE_ANY, array($caFile));
+
+		$errors = '';
+		/* Log errors. */
+		while( ($error = openssl_error_string()) !== FALSE) {
+			$errors .= ' [' . $error . ']';
+		}
+
+		if($res !== TRUE) {
+			return $errors;
+		}
+
+		return TRUE;
+	}
+
+
+	/**
+	 * Validate the certificate used to sign the XML against a CA file, by using the "openssl verify" command.
+	 *
+	 * This function uses the openssl verify command to verify a certificate, to work around limitations
+	 * on the openssl_x509_checkpurpose function. That function will not work on certificates without a purpose
+	 * set.
+	 *
+	 * @param string $certificate  The certificate, in PEM format.
+	 * @param string $caFile  File with trusted certificates, in PEM-format.
+	 * @return boolean|string TRUE on success, a string with error messages on failure.
+	 */
+	private static function validateCAExec($certificate, $caFile) {
+		assert('is_string($certificate)');
+		assert('is_string($caFile)');
+
+		$command = array(
+			'openssl', 'verify',
+			'-CAfile', $caFile,
+			'-purpose', 'any',
+			);
+
+		$cmdline = '';
+		foreach($command as $c) {
+			$cmdline .= escapeshellarg($c) . ' ';
+		}
+
+		$cmdline .= '2>&1';
+		$descSpec = array(
+			0 => array('pipe', 'r'),
+			1 => array('pipe', 'w'),
+			);
+		$process = proc_open($cmdline, $descSpec, $pipes);
+		if (!is_resource($process)) {
+			throw new Exception('Failed to execute verification command: ' . $cmdline);
+		}
+
+		if (fwrite($pipes[0], $certificate) === FALSE) {
+			throw new Exception('Failed to write certificate for verification.');
+		}
+		fclose($pipes[0]);
+
+		$out = '';
+		while (!feof($pipes[1])) {
+			$line = trim(fgets($pipes[1]));
+			if(strlen($line) > 0) {
+				$out .= ' [' . $line . ']';
+			}
+		}
+		fclose($pipes[1]);
+
+		$status = proc_close($process);
+		if ($status !== 0 || $out !== ' [stdin: OK]') {
+			return $out;
+		}
+
+		return TRUE;
+	}
+
+
+	/**
+	 * Validate the certificate used to sign the XML against a CA file.
+	 *
+	 * This function throws an exception if unable to validate against the given CA file.
+	 *
+	 * @param string $certificate  The certificate, in PEM format.
+	 * @param string $caFile  File with trusted certificates, in PEM-format.
+	 */
+	public static function validateCA($certificate, $caFile) {
+		assert('is_string($certificate)');
+		assert('is_string($caFile)');
+
+		if (!file_exists($caFile)) {
+			throw new Exception('Could not load CA file: ' . $caFile);
+		}
+
+		SimpleSAML_Logger::debug('Validating certificate against CA file: ' . var_export($caFile, TRUE));
+
+		$resBuiltin = self::validateCABuiltIn($certificate, $caFile);
+		if ($resBuiltin !== TRUE) {
+			SimpleSAML_Logger::debug('Failed to validate with internal function: ' . var_export($resBuiltin, TRUE));
+
+			$resExternal = self::validateCAExec($certificate, $caFile);
+			if ($resExternal !== TRUE) {
+				SimpleSAML_Logger::debug('Failed to validate with external function: ' . var_export($resExternal, TRUE));
+				throw new Exception('Could not verify certificate against CA file "'
+					. $caFile . '". Internal result:' . $resBuiltin .
+					' External result:' . $resExternal);
+			}
+		}
+
+		SimpleSAML_Logger::debug('Successfully validated certificate.');
+	}
+
 }
 
 ?>
\ No newline at end of file
diff --git a/lib/SimpleSAML/XML/Validator.php b/lib/SimpleSAML/XML/Validator.php
index fef30bddb0caa804860198212382f5de0bdf40ac..46b42aac5ad903901c7de22d44c5b46e574a1bee 100644
--- a/lib/SimpleSAML/XML/Validator.php
+++ b/lib/SimpleSAML/XML/Validator.php
@@ -275,97 +275,6 @@ class SimpleSAML_XML_Validator {
 	}
 
 
-	/**
-	 * Validate the certificate used to sign the XML against a CA file, by using the builtin
-	 * openssl_x509_checkpurpose function
-	 *
-	 * This function throws an exception if unable to validate against the given CA file.
-	 *
-	 * @param $caFile  File with trusted certificates, in PEM-format.
-	 * @return  TRUE on success, or a string with error messages if it failed.
-	 */
-	private function validateCABuiltIn($caFile) {
-
-		/* Clear openssl errors. */
-		while(openssl_error_string() !== FALSE);
-
-		$res = openssl_x509_checkpurpose($this->x509Certificate, X509_PURPOSE_ANY, array($caFile));
-
-		$errors = '';
-		/* Log errors. */
-		while( ($error = openssl_error_string()) !== FALSE) {
-			$errors .= ' [' . $error . ']';
-		}
-
-		if($res === -1) {
-			return $errors;
-		}
-
-
-		if($res !== TRUE) {
-			return $errors;
-		}
-
-		return TRUE;
-	}
-
-
-	/**
-	 * Validate the certificate used to sign the XML against a CA file, by using the "openssl verify" command.
-	 *
-	 * This function uses the openssl verify command to verify a certificate, to work around limitations
-	 * on the openssl_x509_checkpurpose function. That function will not work on certificates without a purpose
-	 * set.
-	 *
-	 * @param $caFile  File with trusted certificates, in PEM-format.
-	 * @return  TRUE on success, a string with error messages on failure.
-	 */
-	private function validateCAExec($caFile) {
-
-		$command = array(
-			'openssl', 'verify',
-			'-CAfile', $caFile,
-			'-purpose', 'any',
-			);
-
-		$cmdline = '';
-		foreach($command as $c) {
-			$cmdline .= escapeshellarg($c) . ' ';
-		}
-
-		$cmdline .= '2>&1';
-		$descSpec = array(
-			0 => array('pipe', 'r'),
-			1 => array('pipe', 'w'),
-			);
-		$process = proc_open($cmdline, $descSpec, $pipes);
-		if(!is_resource($process)) {
-			throw new Exception('Failed to execute verification command: ' . $cmdline . "\n");
-		}
-
-		if(fwrite($pipes[0], $this->x509Certificate) === FALSE) {
-			throw new Exception('Failed to write certificate for verification.' . "\n");
-		}
-		fclose($pipes[0]);
-
-		$out = '';
-		while(!feof($pipes[1])) {
-			$line = trim(fgets($pipes[1]));
-			if(strlen($line) > 0) {
-				$out .= ' [' . $line . ']';
-			}
-		}
-		fclose($pipes[1]);
-
-		$status = proc_close($process);
-		if($status !== 0 || $out !== ' [stdin: OK]') {
-			return $out;
-		}
-
-		return TRUE;
-	}
-
-
 	/**
 	 * Validate the certificate used to sign the XML against a CA file.
 	 *
@@ -377,24 +286,11 @@ class SimpleSAML_XML_Validator {
 
 		assert('is_string($caFile)');
 
-		if(!file_exists($caFile)) {
-			throw new Exception('Could not load CA file: ' . $caFile);
-		}
-
 		if($this->x509Certificate === NULL) {
 			throw new Exception('Key used to sign the message was not an X509 certificate.');
 		}
 
-		$resBuiltIn = $this->validateCABuiltIn($caFile);
-		if($resBuiltIn !== TRUE) {
-			$resExternal = $this->validateCAExec($caFile);
-			if($resExternal !== TRUE) {
-				$certFingerprint = self::calculateX509Fingerprint($this->x509Certificate);
-				throw new Exception('Could not verify certificate with fingerprint ' . $certFingerprint .
-					' against CA file "' . $caFile . '". Internal result:' . $resBuiltIn .
-					' External result:' . $resExternal);
-			}
-		}
+		SimpleSAML_Utilities::validateCA($this->x509Certificate, $caFile);
 	}
 
 }