-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathCertificate.php
138 lines (112 loc) · 3.71 KB
/
Certificate.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?php
/**
* Basic certificate handling.
* Before calling any methods on object instance, call either $o->loadString() or $o->loadFile()
*/
class Certificate
{
/** @var array Returned from openssl_pkcs12read */
private $raw_cert;
/**
* @var array Cached certificate data, so we dont have to call X509 repeatedly
* @see getCertData()
*/
private $certData;
/**
* @param string $filePath
* @param null|string $pass
* @return bool
* @throws Exception If file not found or not readable, or could not open/parse certificate
*/
public function loadFile($filePath, $pass = null) {
if (!is_file($filePath)) {
throw new Exception('File not found.', 123);
}
$text = file_get_contents($filePath);
if ($text === false) {
throw new Exception('Could not get file contents');
}
return $this->loadString($text, $pass);
}
/**
* @param string $certificate
* @param null|string $pass
* @return bool
* @throws Exception If could not open/parse certificate
*/
public function loadString($certificate, $pass = null) {
//unset cached certData
//TODO: think Maybe disable loading of different certificate with some magic
$this->certData = null;
openssl_pkcs12_read($certificate, $this->raw_cert, $pass);
if (!$this->raw_cert) {
throw new Exception('Could not open certificate!');
}
return true;
}
/**
* @return array x509 certificate. Result of "openssl_x509_parse()"
*/
public function getCertData() {
if (!$this->certData) {
$this->certData = openssl_x509_parse($this->raw_cert['cert']);
}
return $this->certData;
}
public function getPrivateKey() {
return $this->raw_cert['pkey'];
}
public function getX509Cert() {
/** @var string $pureCert */
$pureCert = $this->raw_cert['cert'];
$beginCertText = '-----BEGIN CERTIFICATE-----';
$endCertText = '-----END CERTIFICATE-----';
$pureCert = str_replace($beginCertText, '', $pureCert);
return str_replace($endCertText, '', $pureCert);
}
public function getSerialNumber() {
return $this->getCertData()['serialNumber'];
}
public function getIssuer() {
return $this->getCertData()['issuer'];
}
/**
* Default formatting is 'C=ZA,ST=Western Cape,L=Cape Town,O=Thawte Consulting cc'
* Default separator is comma WITHOUT spaces
* @param string $assignmentString
* @param string $separator Glue between valid properties. Defaults to
* @return string
*/
public function getIssuerAsString($separator = ',', $assignmentString = '=') {
$issuer = $this->getIssuer();
$temp = array();
foreach ($issuer as $key => $val) {
$temp[] = $key . $assignmentString . $val;
}
return implode($separator, $temp);
}
/**
* @param $string
* @return mixed
* @throws Exception If there are problem with signing.
*/
public function calculateSignature($string) {
if (!openssl_sign($string, $signature, $this->getPrivateKey(), OPENSSL_ALGO_SHA1)) {
throw new Exception('Failed to calculate signature');
}
return $signature;
}
/*
*
* TODO: take heed about errors generated by other classes/scrips
* that may require adding error handling to most of methods,
* clear buffer at start, and check for errors later
*/
private function _getOpenSSL_Errors() {
$out = array();
while ($e = openssl_error_string()) {
$out[$e];
}
return $out;
}
}