ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
Signer.php
Go to the documentation of this file.
1<?php
2
12namespace SimpleSAML\XML;
13
17
18class Signer
19{
20
21
25 private $idAttrName;
26
30 private $privateKey;
31
35 private $certificate;
36
37
42
43
60 public function __construct($options = array())
61 {
62 assert('is_array($options)');
63
64 $this->idAttrName = false;
65 $this->privateKey = false;
66 $this->certificate = false;
67 $this->extraCertificates = array();
68
69 if (array_key_exists('privatekey', $options)) {
70 $pass = null;
71 if (array_key_exists('privatekey_pass', $options)) {
72 $pass = $options['privatekey_pass'];
73 }
74
75 $this->loadPrivateKey($options['privatekey'], $pass);
76 }
77
78 if (array_key_exists('certificate', $options)) {
79 $this->loadCertificate($options['certificate']);
80 }
81
82 if (array_key_exists('privatekey_array', $options)) {
83 $this->loadPrivateKeyArray($options['privatekey_array']);
84 }
85
86 if (array_key_exists('publickey_array', $options)) {
87 $this->loadPublicKeyArray($options['publickey_array']);
88 }
89
90 if (array_key_exists('id', $options)) {
91 $this->setIdAttribute($options['id']);
92 }
93 }
94
95
104 public function loadPrivateKeyArray($privatekey)
105 {
106 assert('is_array($privatekey)');
107 assert('array_key_exists("PEM", $privatekey)');
108
109 $this->privateKey = new XMLSecurityKey(XMLSecurityKey::RSA_SHA1, array('type' => 'private'));
110 if (array_key_exists('password', $privatekey)) {
111 $this->privateKey->passphrase = $privatekey['password'];
112 }
113 $this->privateKey->loadKey($privatekey['PEM'], false);
114 }
115
116
130 public function loadPrivateKey($file, $pass = null, $full_path = false)
131 {
132 assert('is_string($file)');
133 assert('is_string($pass) || is_null($pass)');
134 assert('is_bool($full_path)');
135
136 if (!$full_path) {
137 $keyFile = Config::getCertPath($file);
138 } else {
139 $keyFile = $file;
140 }
141
142 if (!file_exists($keyFile)) {
143 throw new \Exception('Could not find private key file "' . $keyFile . '".');
144 }
145 $keyData = file_get_contents($keyFile);
146 if ($keyData === false) {
147 throw new \Exception('Unable to read private key file "' . $keyFile . '".');
148 }
149
150 $privatekey = array('PEM' => $keyData);
151 if ($pass !== null) {
152 $privatekey['password'] = $pass;
153 }
154 $this->loadPrivateKeyArray($privatekey);
155 }
156
157
167 public function loadPublicKeyArray($publickey)
168 {
169 assert('is_array($publickey)');
170
171 if (!array_key_exists('PEM', $publickey)) {
172 // We have a public key with only a fingerprint
173 throw new \Exception('Tried to add a certificate fingerprint in a signature.');
174 }
175
176 // For now, we only assume that the public key is an X509 certificate
177 $this->certificate = $publickey['PEM'];
178 }
179
180
193 public function loadCertificate($file, $full_path = false)
194 {
195 assert('is_string($file)');
196 assert('is_bool($full_path)');
197
198 if (!$full_path) {
199 $certFile = Config::getCertPath($file);
200 } else {
201 $certFile = $file;
202 }
203
204 if (!file_exists($certFile)) {
205 throw new \Exception('Could not find certificate file "' . $certFile . '".');
206 }
207
208 $this->certificate = file_get_contents($certFile);
209 if ($this->certificate === false) {
210 throw new \Exception('Unable to read certificate file "' . $certFile . '".');
211 }
212 }
213
214
221 {
222 assert('is_string($idAttrName)');
223
224 $this->idAttrName = $idAttrName;
225 }
226
227
239 public function addCertificate($file, $full_path = false)
240 {
241 assert('is_string($file)');
242 assert('is_bool($full_path)');
243
244 if (!$full_path) {
245 $certFile = Config::getCertPath($file);
246 } else {
247 $certFile = $file;
248 }
249
250 if (!file_exists($certFile)) {
251 throw new \Exception('Could not find extra certificate file "' . $certFile . '".');
252 }
253
254 $certificate = file_get_contents($certFile);
255 if ($certificate === false) {
256 throw new \Exception('Unable to read extra certificate file "' . $certFile . '".');
257 }
258
259 $this->extraCertificates[] = $certificate;
260 }
261
262
275 public function sign($node, $insertInto, $insertBefore = null)
276 {
277 assert('$node instanceof DOMElement');
278 assert('$insertInto instanceof DOMElement');
279 assert('is_null($insertBefore) || $insertBefore instanceof DOMElement ' .
280 '|| $insertBefore instanceof DOMComment || $insertBefore instanceof DOMText');
281
282 if ($this->privateKey === false) {
283 throw new \Exception('Private key not set.');
284 }
285
286
287 $objXMLSecDSig = new XMLSecurityDSig();
288 $objXMLSecDSig->setCanonicalMethod(XMLSecurityDSig::EXC_C14N);
289
290 $options = array();
291 if ($this->idAttrName !== false) {
292 $options['id_name'] = $this->idAttrName;
293 }
294
295 $objXMLSecDSig->addReferenceList(
296 array($node),
298 array('http://www.w3.org/2000/09/xmldsig#enveloped-signature', XMLSecurityDSig::EXC_C14N),
300 );
301
302 $objXMLSecDSig->sign($this->privateKey);
303
304
305 if ($this->certificate !== false) {
306 // Add the certificate to the signature
307 $objXMLSecDSig->add509Cert($this->certificate, true);
308 }
309
310 // Add extra certificates
311 foreach ($this->extraCertificates as $certificate) {
312 $objXMLSecDSig->add509Cert($certificate, true);
313 }
314
315 $objXMLSecDSig->insertSignature($insertInto, $insertBefore);
316 }
317}
if(!isset( $_REQUEST[ 'ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
Definition: as_login.php:20
An exception for terminatinating execution or to throw for unit testing.
static getCertPath($path)
Resolves a path that may be relative to the cert-directory.
Definition: Config.php:22
loadPrivateKey($file, $pass=null, $full_path=false)
Set the private key.
Definition: Signer.php:130
__construct($options=array())
Constructor for the metadata signer.
Definition: Signer.php:60
addCertificate($file, $full_path=false)
Add an extra certificate to the certificate chain in the signature.
Definition: Signer.php:239
sign($node, $insertInto, $insertBefore=null)
Signs the given DOMElement and inserts the signature at the given position.
Definition: Signer.php:275
loadCertificate($file, $full_path=false)
Set the certificate we should include in the signature.
Definition: Signer.php:193
setIDAttribute($idAttrName)
Set the attribute name for the ID value.
Definition: Signer.php:220
loadPublicKeyArray($publickey)
Set the public key / certificate we should include in the signature.
Definition: Signer.php:167
loadPrivateKeyArray($privatekey)
Set the private key from an array.
Definition: Signer.php:104
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file