ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
Signer.php
Go to the documentation of this file.
1 <?php
2 
12 namespace SimpleSAML\XML;
13 
17 
18 class 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 
220  public function setIDAttribute($idAttrName)
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),
299  $options
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 }
__construct($options=array())
Constructor for the metadata signer.
Definition: Signer.php:60
loadPublicKeyArray($publickey)
Set the public key / certificate we should include in the signature.
Definition: Signer.php:167
loadPrivateKey($file, $pass=null, $full_path=false)
Set the private key.
Definition: Signer.php:130
setIDAttribute($idAttrName)
Set the attribute name for the ID value.
Definition: Signer.php:220
loadCertificate($file, $full_path=false)
Set the certificate we should include in the signature.
Definition: Signer.php:193
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
loadPrivateKeyArray($privatekey)
Set the private key from an array.
Definition: Signer.php:104
Create styles array
The data for the language used.
static getCertPath($path)
Resolves a path that may be relative to the cert-directory.
Definition: Config.php:22
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
if(!isset($_REQUEST['ReturnTo'])) if(!isset($_REQUEST['AuthId'])) $options
Definition: as_login.php:20