class_certificate.inc 6.86 KB
Newer Older
1
2
3
4
<?php
/*
  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
  Copyright (C) 2003-2010  Cajus Pollmeier
5
  Copyright (C) 2011-2015  FusionDirectory
6
7
8
9
10
11
12
13
14
15
16
17
18

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
19
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20
21
*/

22
23
24
25
26
/*!
 * \file class_certificate.inc
 * Source code for class certificate
 */

27
/* certificates */
28
29
define("PEM", "pem");
define("DER", "der");
30

31
/*!
32
 * \brief This class contains all the function needed to import certificates
Benoit Mortier's avatar
Benoit Mortier committed
33
 */
34
class certificate
35
36
37
38
39
40
{
  /* vars */
  var $data;
  var $type;
  var $error;

41
  /*
42
   * \brief Certificate constructor (initialize all vars)
43
   */
44
45
  function certificate()
  {
46
47
48
49
    $this->data   = "";
    $this->type   = FALSE;
    $this->error  = "";
    $this->info   = array();
50
  }
51

52
  /*
53
   * \brief Reads specified Certfile/string and convert it to PEM
54
   *
55
   * \param string $data
56
   *
57
   * \param boolean $type FALSE
58
   */
59
  function import($data, $type = FALSE)
60
61
  {
    /* if is file read from file, else use string as it is*/
62
63
64
    if (is_file($data)) {
      $fp   = fopen($data, "r+");
      $str  = "";
65

66
      if (!$fp) {
67
        $this->certificate();
68
69
70
        $this->error = msgPool::cannotReadFile($data);
        return FALSE;
      } else {
71
        /* Reading data*/
72
73
        while (!feof($fp)) {
          $str .= fgets($fp, 1024);
74
75
76
77
78
79
80
81
82
83
        }
      }
      /* Filename given, so we use the data from the file */
      $this->data = $str;
    } else {
      /* Cert as String, use this string */
      $this->data = $data;
    }

    /* Data can't be empty */
84
    if ($data = "") {
85
      $this->certificate();
86
      $this->error = _("Certificate is empty!");
87
      return FALSE;
88
89
90
    }

    /* Prefer specified certtype*/
91
    if ($type) {
92
      $this->type = $type;
93
    } else {
94
      /* Detect certtype, cause there is none specified */
95

Benoit Mortier's avatar
Benoit Mortier committed
96
      /* PEM always starts with ----BEGIN CERTIFICATE-----*/
97
98
      if (strstr($this->data, "CERTIFICATE"))  {
        $this->type = PEM;
99
100
      } else {
        /* We test DER now, on fail abort */
101
        $this->type = DER;
102
103
104
      }
    }

105
    /* Convert to PEM to give $this->info the ability to read the cert */
106
    if ($this->type == DER) {
107
108
109
110
      $this->derTOpem();
    }

    /* If cert is loaded correctly and is PEM now, we could read some data out of it */
111
    if (count($this->info()) <= 1) {
112
113
114
      $this->certificate();
      $this->error = _("Cannot load certificate - only PEM/DER is supported!");
      /* Reset*/
115
      return FALSE;
116
117
    }

118
    $this->info(FALSE);
119
120

    /* Loaded a readable cert */
121
    return TRUE;
122
123
  }

124
  /*
125
   * \brief Get all data of a certificate
126
   *
127
   * \param boolean $ret true
128
129
   *
   * \return Array with all containing data
130
   */
131
  function info($ret = TRUE)
132
  {
133
    if ($this->type != PEM) {
134
      $this->error = _("Cannot extract information for non PEM certificates!");
135
      return FALSE;
136
137
    } else {
      /* return an array with all given information */
138
      $this->info = openssl_x509_parse($this->data);
139

140
141
142
      if ($ret) {
        return $this->info;
      }
143
144
145
146
147
148
    }
  }

  /* Return Functions */
  function getvalidto_date()
  {
149
    return $this->_genericGet1('validTo_time_t');
150
  }
151
152
153

  function getvalidfrom_date()
  {
154
    return $this->_genericGet1('validFrom_time_t');
155
  }
156

157
158
  /*!
   * \brief Get the name of the certificate
159
   *
160
   * \return String with the name, but return FALSE if not found
161
   */
162
163
  function getname()
  {
164
    return $this->_genericGet1('name');
165
  }
166

167
168
  /*!
   * \brief Get the CN of the certificate
169
   *
170
   * \return String with the CN, but return FALSE if not found
171
   */
172
173
  function getCN()
  {
174
    return $this->_genericGet2('CN');
175
176
177
178
  }

  function getO()
  {
179
    return $this->_genericGet2('O');
180
181
182
183
  }

  function getOU()
  {
184
    return $this->_genericGet2('OU');
185
  }
186
187
  /*!
   * \brief Get the serial number of the certificate
188
   *
189
   * \return Integer number, but return FALSE if not found
190
   */
191
192
  function getSerialNumber()
  {
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
    return $this->_genericGet1('serialNumber');
  }

  protected function _genericGet1($key)
  {
    if (isset($this->info[$key])) {
      return $this->info[$key];
    } else {
      return FALSE;
    }
  }

  protected function _genericGet2($key)
  {
    if (isset($this->info['subject'][$key])) {
      return $this->info['subject'][$key];
    } else {
      return FALSE;
211
212
213
    }
  }

214
215
  /*
   * \brief Check if the certificate is valid
216
217
218
   *    Is valide if the length of array > 1
   *    and type is true
   */
219
220
  function isvalid()
  {
221
    return (($this->type != FALSE) && (count($this->info) > 1));
222
223
  }

224
225

  /*
226
   * \brief Export Certificate to specified file, with specified method
227
   *
228
   * \param boolean $type
229
   *
230
231
   * \param string $filename Initialized at 'temp'
   */
232
  function export($type, $filename = "temp")
233
234
  {
    /* Check if valid cert is loaded*/
235
    if ($this->type != FALSE) {
236
      /* Check if we must convert the cert */
237
      if ($this->type != $type) {
238
239
        $strConv = $this->type."TO".$type;
        $this->$strConv();
240
      }
241
242

      /* open file for writing */
243
      $fp = fopen($filename, "w+");
244

245
246
247
248
249
      if (!$fp) {
        $this->error = msgPool::cannotWriteFile($filename);
        return FALSE;
      } else {
        fwrite($fp, $this->data, strlen($this->data));
250
      }
251
252
253
254
      return TRUE;
    } else {
      $this->error = _("No valid certificate loaded!");
      return FALSE;
255
    }
256
    return FALSE;
257
  }
258
259


260
  /*
261
262
   * \brief Convert der to pem Certificate
   */
263
264
265
  function derTOpem()
  {
    /* if type is DER start convert */
266
    if ($this->type == DER) {
267
      /* converting */
268
269
      $this->type = PEM;

270
271
272
273
274
      $str = base64_encode($this->data);
      $len = strlen($str);

      $end = "";

275
276
277
278
279
      while ($len > 0 ) {
        $len  = $len - 64;
        $str1 = substr($str, 0, 64)."\n";
        $str  = substr($str, 64, $len);
        $end  .= $str1;
280
281
282
283
284
285
      }

      $strend = "-----BEGIN CERTIFICATE-----\n".$end;
      $strend .= "-----END CERTIFICATE-----";

      $this->data     = $strend;
286
      return TRUE;
287
    }
288
    return FALSE;
289
290
  }

291
  /*
292
   * Convert pem to der Certificate
293
   */
294
295
  function pemTOder()
  {
296
297
    if ($this->type == PEM) {
      $this->type = DER;
298
299
300

      $str = $this->data;

301
302
      $str = str_replace("-----BEGIN CERTIFICATE-----", "", $str);
      $str = str_replace("-----END CERTIFICATE-----", "", $str);
303
304
305
306

      $str = base64_decode($str);

      $this->data = $str;
307
      return TRUE;
308
    }
309
    return FALSE;
310
311
312
313
  }
}

?>