ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
SimpleSAML\XML\Validator Class Reference
+ Collaboration diagram for SimpleSAML\XML\Validator:

Public Member Functions

 __construct ($xmlNode, $idAttribute=null, $publickey=false)
 This function initializes the validator. More...
 
 getX509Certificate ()
 Retrieve the X509 certificate which was used to sign the XML. More...
 
 validateFingerprint ($fingerprints)
 Validate the fingerprint of the certificate which was used to sign this document. More...
 
 isNodeValidated ($node)
 This function checks if the given XML node was signed. More...
 
 validateCA ($caFile)
 Validate the certificate used to sign the XML against a CA file. More...
 

Static Public Member Functions

static validateCertificate ($certificate, $caFile)
 Validate the certificate used to sign the XML against a CA file. More...
 

Static Private Member Functions

static calculateX509Fingerprint ($x509cert)
 Calculates the fingerprint of an X509 certificate. More...
 
static validateCertificateFingerprint ($certificate, $fingerprints)
 Helper function for validating the fingerprint. More...
 
static validateCABuiltIn ($certificate, $caFile)
 Validate a certificate against a CA file, by using the builtin openssl_x509_checkpurpose function. More...
 
static validateCAExec ($certificate, $caFile)
 Validate the certificate used to sign the XML against a CA file, by using the "openssl verify" command. More...
 

Private Attributes

 $x509Certificate
 
 $validNodes = null
 

Detailed Description

Definition at line 16 of file Validator.php.

Constructor & Destructor Documentation

◆ __construct()

SimpleSAML\XML\Validator::__construct (   $xmlNode,
  $idAttribute = null,
  $publickey = false 
)

This function initializes the validator.

This function accepts an optional parameter $publickey, which is the public key or certificate which should be used to validate the signature. This parameter can take the following values:

  • NULL/FALSE: No validation will be performed. This is the default.
  • A string: Assumed to be a PEM-encoded certificate / public key.
  • An array: Assumed to be an array returned by SimpleSAML_Utilities::loadPublicKey.
Parameters
\DOMNode$xmlNodeThe XML node which contains the Signature element.
string | array$idAttributeThe ID attribute which is used in node references. If this attribute is NULL (the default), then we will use whatever is the default ID. Can be eigther a string with one value, or an array with multiple ID attrbute names.
array | bool$publickeyThe public key / certificate which should be used to validate the XML node.
Exceptions

Exception

Definition at line 49 of file Validator.php.

50 {
51 assert('$xmlNode instanceof \DOMNode');
52
53 if ($publickey === null) {
54 $publickey = false;
55 } elseif (is_string($publickey)) {
56 $publickey = array(
57 'PEM' => $publickey,
58 );
59 } else {
60 assert('$publickey === FALSE || is_array($publickey)');
61 }
62
63 // Create an XML security object
64 $objXMLSecDSig = new XMLSecurityDSig();
65
66 // Add the id attribute if the user passed in an id attribute
67 if ($idAttribute !== null) {
68 if (is_string($idAttribute)) {
69 $objXMLSecDSig->idKeys[] = $idAttribute;
70 } elseif (is_array($idAttribute)) {
71 foreach ($idAttribute as $ida) {
72 $objXMLSecDSig->idKeys[] = $ida;
73 }
74 }
75 }
76
77 // Locate the XMLDSig Signature element to be used
78 $signatureElement = $objXMLSecDSig->locateSignature($xmlNode);
79 if (!$signatureElement) {
80 throw new \Exception('Could not locate XML Signature element.');
81 }
82
83 // Canonicalize the XMLDSig SignedInfo element in the message
84 $objXMLSecDSig->canonicalizeSignedInfo();
85
86 // Validate referenced xml nodes
87 if (!$objXMLSecDSig->validateReference()) {
88 throw new \Exception('XMLsec: digest validation failed');
89 }
90
91
92 // Find the key used to sign the document
93 $objKey = $objXMLSecDSig->locateKey();
94 if (empty($objKey)) {
95 throw new \Exception('Error loading key to handle XML signature');
96 }
97
98 // Load the key data
99 if ($publickey !== false && array_key_exists('PEM', $publickey)) {
100 // We have PEM data for the public key / certificate
101 $objKey->loadKey($publickey['PEM']);
102 } else {
103 // No PEM data. Search for key in signature
104
105 if (!XMLSecEnc::staticLocateKeyInfo($objKey, $signatureElement)) {
106 throw new \Exception('Error finding key data for XML signature validation.');
107 }
108
109 if ($publickey !== false) {
110 /* $publickey is set, and should therefore contain one or more fingerprints.
111 * Check that the response contains a certificate with a matching
112 * fingerprint.
113 */
114 assert('is_array($publickey["certFingerprint"])');
115
116 $certificate = $objKey->getX509Certificate();
117 if ($certificate === null) {
118 // Wasn't signed with an X509 certificate
119 throw new \Exception('Message wasn\'t signed with an X509 certificate,' .
120 ' and no public key was provided in the metadata.');
121 }
122
123 self::validateCertificateFingerprint($certificate, $publickey['certFingerprint']);
124 // Key OK
125 }
126 }
127
128 // Check the signature
129 if ($objXMLSecDSig->verify($objKey) !== 1) {
130 throw new \Exception("Unable to validate Signature");
131 }
132
133 // Extract the certificate
134 $this->x509Certificate = $objKey->getX509Certificate();
135
136 // Find the list of validated nodes
137 $this->validNodes = $objXMLSecDSig->getValidatedNodes();
138 }
static staticLocateKeyInfo($objBaseKey=null, $node=null)
Definition: XMLSecEnc.php:410
static validateCertificateFingerprint($certificate, $fingerprints)
Helper function for validating the fingerprint.
Definition: Validator.php:206
if(@file_exists(dirname(__FILE__).'/lang/eng.php')) $certificate
Definition: example_052.php:77

References $certificate, RobRichards\XMLSecLibs\XMLSecEnc\staticLocateKeyInfo(), and SimpleSAML\XML\Validator\validateCertificateFingerprint().

+ Here is the call graph for this function:

Member Function Documentation

◆ calculateX509Fingerprint()

static SimpleSAML\XML\Validator::calculateX509Fingerprint (   $x509cert)
staticprivate

Calculates the fingerprint of an X509 certificate.

Parameters
string$x509certThe certificate as a base64-encoded string. The string may optionally be framed with '--—BEGIN CERTIFICATE--—' and '--—END CERTIFICATE--—'.
Returns
string The fingerprint as a 40-character lowercase hexadecimal number. NULL is returned if the argument isn't an X509 certificate.

Definition at line 163 of file Validator.php.

164 {
165 assert('is_string($x509cert)');
166
167 $lines = explode("\n", $x509cert);
168
169 $data = '';
170
171 foreach ($lines as $line) {
172 // Remove '\r' from end of line if present
173 $line = rtrim($line);
174 if ($line === '-----BEGIN CERTIFICATE-----') {
175 // Delete junk from before the certificate
176 $data = '';
177 } elseif ($line === '-----END CERTIFICATE-----') {
178 // Ignore data after the certificate
179 break;
180 } elseif ($line === '-----BEGIN PUBLIC KEY-----') {
181 // This isn't an X509 certificate
182 return null;
183 } else {
184 // Append the current line to the certificate data
185 $data .= $line;
186 }
187 }
188
189 /* $data now contains the certificate as a base64-encoded string. The fingerprint
190 * of the certificate is the sha1-hash of the certificate.
191 */
192 return strtolower(sha1(base64_decode($data)));
193 }

References $data.

Referenced by SimpleSAML\XML\Validator\validateCertificateFingerprint().

+ Here is the caller graph for this function:

◆ getX509Certificate()

SimpleSAML\XML\Validator::getX509Certificate ( )

Retrieve the X509 certificate which was used to sign the XML.

This function will return the certificate as a PEM-encoded string. If the XML wasn't signed by an X509 certificate, NULL will be returned.

Returns
string The certificate as a PEM-encoded string, or NULL if not signed with an X509 certificate.

Definition at line 149 of file Validator.php.

150 {
152 }

References SimpleSAML\XML\Validator\$x509Certificate.

◆ isNodeValidated()

SimpleSAML\XML\Validator::isNodeValidated (   $node)

This function checks if the given XML node was signed.

Parameters
\DOMNode$nodeThe XML node which we should verify that was signed.
Returns
bool TRUE if this node (or a parent node) was signed. FALSE if not.

Definition at line 275 of file Validator.php.

276 {
277 assert('$node instanceof \DOMNode');
278
279 while ($node !== null) {
280 if (in_array($node, $this->validNodes, true)) {
281 return true;
282 }
283
284 $node = $node->parentNode;
285 }
286
287 /* Neither this node nor any of the parent nodes could be found in the list of
288 * signed nodes.
289 */
290 return false;
291 }

◆ validateCA()

SimpleSAML\XML\Validator::validateCA (   $caFile)

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.

Parameters
string$caFileFile with trusted certificates, in PEM-format.
Exceptions

Exception

Definition at line 302 of file Validator.php.

303 {
304 assert('is_string($caFile)');
305
306 if ($this->x509Certificate === null) {
307 throw new \Exception('Key used to sign the message was not an X509 certificate.');
308 }
309
310 self::validateCertificate($this->x509Certificate, $caFile);
311 }
static validateCertificate($certificate, $caFile)
Validate the certificate used to sign the XML against a CA file.
Definition: Validator.php:418

References SimpleSAML\XML\Validator\validateCertificate().

+ Here is the call graph for this function:

◆ validateCABuiltIn()

static SimpleSAML\XML\Validator::validateCABuiltIn (   $certificate,
  $caFile 
)
staticprivate

Validate a certificate against a CA file, by using the builtin openssl_x509_checkpurpose function.

Parameters
string$certificateThe certificate, in PEM format.
string$caFileFile with trusted certificates, in PEM-format.
Returns
boolean|string TRUE on success, or a string with error messages if it failed.
Deprecated:

Definition at line 322 of file Validator.php.

323 {
324 assert('is_string($certificate)');
325 assert('is_string($caFile)');
326
327 // Clear openssl errors
328 while (openssl_error_string() !== false);
329
330 $res = openssl_x509_checkpurpose($certificate, X509_PURPOSE_ANY, array($caFile));
331
332 $errors = '';
333 // Log errors
334 while (($error = openssl_error_string()) !== false) {
335 $errors .= ' [' . $error . ']';
336 }
337
338 if ($res !== true) {
339 return $errors;
340 }
341
342 return true;
343 }
$error
Definition: Error.php:17
$errors
Definition: index.php:6
foreach($_POST as $key=> $value) $res

References $certificate, $error, $errors, and $res.

Referenced by SimpleSAML\XML\Validator\validateCertificate().

+ Here is the caller graph for this function:

◆ validateCAExec()

static SimpleSAML\XML\Validator::validateCAExec (   $certificate,
  $caFile 
)
staticprivate

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.

Parameters
string$certificateThe certificate, in PEM format.
string$caFileFile with trusted certificates, in PEM-format.
Returns
bool|string TRUE on success, a string with error messages on failure.
Exceptions

Exception

Deprecated:

Definition at line 359 of file Validator.php.

360 {
361 assert('is_string($certificate)');
362 assert('is_string($caFile)');
363
364 $command = array(
365 'openssl', 'verify',
366 '-CAfile', $caFile,
367 '-purpose', 'any',
368 );
369
370 $cmdline = '';
371 foreach ($command as $c) {
372 $cmdline .= escapeshellarg($c) . ' ';
373 }
374
375 $cmdline .= '2>&1';
376 $descSpec = array(
377 0 => array('pipe', 'r'),
378 1 => array('pipe', 'w'),
379 );
380 $process = proc_open($cmdline, $descSpec, $pipes);
381 if (!is_resource($process)) {
382 throw new \Exception('Failed to execute verification command: ' . $cmdline);
383 }
384
385 if (fwrite($pipes[0], $certificate) === false) {
386 throw new \Exception('Failed to write certificate for verification.');
387 }
388 fclose($pipes[0]);
389
390 $out = '';
391 while (!feof($pipes[1])) {
392 $line = trim(fgets($pipes[1]));
393 if (strlen($line) > 0) {
394 $out .= ' [' . $line . ']';
395 }
396 }
397 fclose($pipes[1]);
398
399 $status = proc_close($process);
400 if ($status !== 0 || $out !== ' [stdin: OK]') {
401 return $out;
402 }
403
404 return true;
405 }

References $certificate, and $out.

Referenced by SimpleSAML\XML\Validator\validateCertificate().

+ Here is the caller graph for this function:

◆ validateCertificate()

static SimpleSAML\XML\Validator::validateCertificate (   $certificate,
  $caFile 
)
static

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.

Parameters
string$certificateThe certificate, in PEM format.
string$caFileFile with trusted certificates, in PEM-format.
Exceptions

Exception

Deprecated:

Definition at line 418 of file Validator.php.

419 {
420 assert('is_string($certificate)');
421 assert('is_string($caFile)');
422
423 if (!file_exists($caFile)) {
424 throw new \Exception('Could not load CA file: ' . $caFile);
425 }
426
427 Logger::debug('Validating certificate against CA file: ' . var_export($caFile, true));
428
429 $resBuiltin = self::validateCABuiltIn($certificate, $caFile);
430 if ($resBuiltin !== true) {
431 Logger::debug('Failed to validate with internal function: ' . var_export($resBuiltin, true));
432
433 $resExternal = self::validateCAExec($certificate, $caFile);
434 if ($resExternal !== true) {
435 Logger::debug('Failed to validate with external function: ' . var_export($resExternal, true));
436 throw new \Exception('Could not verify certificate against CA file "'
437 . $caFile . '". Internal result:' . $resBuiltin .
438 ' External result:' . $resExternal);
439 }
440 }
441
442 Logger::debug('Successfully validated certificate.');
443 }
static debug($string)
Definition: Logger.php:213
static validateCAExec($certificate, $caFile)
Validate the certificate used to sign the XML against a CA file, by using the "openssl verify" comman...
Definition: Validator.php:359
static validateCABuiltIn($certificate, $caFile)
Validate a certificate against a CA file, by using the builtin openssl_x509_checkpurpose function.
Definition: Validator.php:322

References $certificate, SimpleSAML\Logger\debug(), SimpleSAML\XML\Validator\validateCABuiltIn(), and SimpleSAML\XML\Validator\validateCAExec().

Referenced by SimpleSAML\XML\Validator\validateCA(), and SimpleSAML_Utilities\validateCA().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ validateCertificateFingerprint()

static SimpleSAML\XML\Validator::validateCertificateFingerprint (   $certificate,
  $fingerprints 
)
staticprivate

Helper function for validating the fingerprint.

Checks the fingerprint of a certificate against an array of valid fingerprints. Will throw an exception if none of the fingerprints matches.

Parameters
string$certificateThe X509 certificate we should validate.
array$fingerprintsThe valid fingerprints.
Exceptions

Exception

Definition at line 206 of file Validator.php.

207 {
208 assert('is_string($certificate)');
209 assert('is_array($fingerprints)');
210
212 if ($certFingerprint === null) {
213 // Couldn't calculate fingerprint from X509 certificate. Should not happen.
214 throw new \Exception('Unable to calculate fingerprint from X509' .
215 ' certificate. Maybe it isn\'t an X509 certificate?');
216 }
217
218 foreach ($fingerprints as $fp) {
219 assert('is_string($fp)');
220
221 if ($fp === $certFingerprint) {
222 // The fingerprints matched
223 return;
224 }
225 }
226
227 // None of the fingerprints matched. Throw an exception describing the error.
228 throw new \Exception('Invalid fingerprint of certificate. Expected one of [' .
229 implode('], [', $fingerprints) . '], but got [' . $certFingerprint . ']');
230 }
static calculateX509Fingerprint($x509cert)
Calculates the fingerprint of an X509 certificate.
Definition: Validator.php:163

References $certificate, and SimpleSAML\XML\Validator\calculateX509Fingerprint().

Referenced by SimpleSAML\XML\Validator\__construct(), and SimpleSAML\XML\Validator\validateFingerprint().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ validateFingerprint()

SimpleSAML\XML\Validator::validateFingerprint (   $fingerprints)

Validate the fingerprint of the certificate which was used to sign this document.

This function accepts either a string, or an array of strings as a parameter. If this is an array, then any string (certificate) in the array can match. If this is a string, then that string must match,

Parameters
string | array$fingerprintsThe fingerprints which should match. This can be a single string, or an array of fingerprints.
Exceptions

Exception

Definition at line 244 of file Validator.php.

245 {
246 assert('is_string($fingerprints) || is_array($fingerprints)');
247
248 if ($this->x509Certificate === null) {
249 throw new \Exception('Key used to sign the message was not an X509 certificate.');
250 }
251
252 if (!is_array($fingerprints)) {
253 $fingerprints = array($fingerprints);
254 }
255
256 // Normalize the fingerprints
257 foreach ($fingerprints as &$fp) {
258 assert('is_string($fp)');
259
260 // Make sure that the fingerprint is in the correct format
261 $fp = strtolower(str_replace(":", "", $fp));
262 }
263
264 self::validateCertificateFingerprint($this->x509Certificate, $fingerprints);
265 }

References SimpleSAML\XML\Validator\validateCertificateFingerprint().

+ Here is the call graph for this function:

Field Documentation

◆ $validNodes

SimpleSAML\XML\Validator::$validNodes = null
private

Definition at line 28 of file Validator.php.

◆ $x509Certificate

SimpleSAML\XML\Validator::$x509Certificate
private

Definition at line 23 of file Validator.php.

Referenced by SimpleSAML\XML\Validator\getX509Certificate().


The documentation for this class was generated from the following file: