1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace X509\CertificationRequest; |
4
|
|
|
|
5
|
|
|
use ASN1\Type\Constructed\Sequence; |
6
|
|
|
use CryptoUtil\ASN1\AlgorithmIdentifier; |
7
|
|
|
use CryptoUtil\ASN1\AlgorithmIdentifier\Feature\SignatureAlgorithmIdentifier; |
8
|
|
|
use CryptoUtil\Crypto\Crypto; |
9
|
|
|
use CryptoUtil\Crypto\Signature; |
10
|
|
|
use CryptoUtil\PEM\PEM; |
11
|
|
|
|
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Implements <i>CertificationRequest</i> ASN.1 type. |
15
|
|
|
* |
16
|
|
|
* @link https://tools.ietf.org/html/rfc2986#section-4 |
17
|
|
|
*/ |
18
|
|
View Code Duplication |
class CertificationRequest |
|
|
|
|
19
|
|
|
{ |
20
|
|
|
/** |
21
|
|
|
* Certification request info. |
22
|
|
|
* |
23
|
|
|
* @var CertificationRequestInfo $_certificationRequestInfo |
24
|
|
|
*/ |
25
|
|
|
protected $_certificationRequestInfo; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Signature algorithm. |
29
|
|
|
* |
30
|
|
|
* @var SignatureAlgorithmIdentifier $_signatureAlgorithm |
31
|
|
|
*/ |
32
|
|
|
protected $_signatureAlgorithm; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Signature. |
36
|
|
|
* |
37
|
|
|
* @var Signature $_signature |
38
|
|
|
*/ |
39
|
|
|
protected $_signature; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Constructor |
43
|
|
|
* |
44
|
|
|
* @param CertificationRequestInfo $info |
45
|
|
|
* @param SignatureAlgorithmIdentifier $algo |
46
|
|
|
* @param Signature $signature |
47
|
|
|
*/ |
48
|
6 |
|
public function __construct(CertificationRequestInfo $info, |
49
|
|
|
SignatureAlgorithmIdentifier $algo, Signature $signature) { |
50
|
6 |
|
$this->_certificationRequestInfo = $info; |
51
|
6 |
|
$this->_signatureAlgorithm = $algo; |
52
|
6 |
|
$this->_signature = $signature; |
53
|
6 |
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Initialize from ASN.1. |
57
|
|
|
* |
58
|
|
|
* @param Sequence $seq |
59
|
|
|
* @return self |
60
|
|
|
*/ |
61
|
4 |
|
public static function fromASN1(Sequence $seq) { |
62
|
4 |
|
$info = CertificationRequestInfo::fromASN1($seq->at(0)->asSequence()); |
63
|
4 |
|
$algo = AlgorithmIdentifier::fromASN1($seq->at(1)->asSequence()); |
64
|
4 |
|
if (!$algo instanceof SignatureAlgorithmIdentifier) { |
65
|
1 |
|
throw new \UnexpectedValueException( |
66
|
1 |
|
"Unsupported signature algorithm " . $algo->oid() . "."); |
67
|
|
|
} |
68
|
3 |
|
$signature = Signature::fromASN1($seq->at(2)->asBitString()); |
69
|
3 |
|
return new self($info, $algo, $signature); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Initialize from DER. |
74
|
|
|
* |
75
|
|
|
* @param string $data |
76
|
|
|
* @return self |
77
|
|
|
*/ |
78
|
2 |
|
public static function fromDER($data) { |
79
|
2 |
|
return self::fromASN1(Sequence::fromDER($data)); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Initialize from PEM. |
84
|
|
|
* |
85
|
|
|
* @param PEM $pem |
86
|
|
|
* @throws \UnexpectedValueException |
87
|
|
|
* @return self |
88
|
|
|
*/ |
89
|
3 |
|
public static function fromPEM(PEM $pem) { |
90
|
3 |
|
if ($pem->type() !== PEM::TYPE_CERTIFICATE_REQUEST) { |
91
|
1 |
|
throw new \UnexpectedValueException("Invalid PEM type."); |
92
|
|
|
} |
93
|
2 |
|
return self::fromDER($pem->data()); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* Get certification request info. |
98
|
|
|
* |
99
|
|
|
* @return CertificationRequestInfo |
100
|
|
|
*/ |
101
|
3 |
|
public function certificationRequestInfo() { |
102
|
3 |
|
return $this->_certificationRequestInfo; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* Get signature algorithm. |
107
|
|
|
* |
108
|
|
|
* @return SignatureAlgorithmIdentifier |
109
|
|
|
*/ |
110
|
2 |
|
public function signatureAlgorithm() { |
111
|
2 |
|
return $this->_signatureAlgorithm; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* Get signature. |
116
|
|
|
* |
117
|
|
|
* @return Signature |
118
|
|
|
*/ |
119
|
2 |
|
public function signature() { |
120
|
2 |
|
return $this->_signature; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Generate ASN.1 structure. |
125
|
|
|
* |
126
|
|
|
* @return Sequence |
127
|
|
|
*/ |
128
|
4 |
|
public function toASN1() { |
129
|
4 |
|
return new Sequence($this->_certificationRequestInfo->toASN1(), |
130
|
4 |
|
$this->_signatureAlgorithm->toASN1(), |
131
|
4 |
|
$this->_signature->toBitString()); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* Get certification request as a DER. |
136
|
|
|
* |
137
|
|
|
* @return string |
138
|
|
|
*/ |
139
|
2 |
|
public function toDER() { |
140
|
2 |
|
return $this->toASN1()->toDER(); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Get certification request as a PEM. |
145
|
|
|
* |
146
|
|
|
* @return PEM |
147
|
|
|
*/ |
148
|
2 |
|
public function toPEM() { |
149
|
2 |
|
return new PEM(PEM::TYPE_CERTIFICATE_REQUEST, $this->toDER()); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* Verify certification request signature. |
154
|
|
|
* |
155
|
|
|
* @param Crypto $crypto |
156
|
|
|
* @return bool True if signature matches |
157
|
|
|
*/ |
158
|
1 |
|
public function verify(Crypto $crypto) { |
159
|
1 |
|
$data = $this->_certificationRequestInfo->toASN1()->toDER(); |
160
|
1 |
|
$pk_info = $this->_certificationRequestInfo->subjectPKInfo(); |
161
|
1 |
|
return $crypto->verify($data, $this->_signature, $pk_info, |
162
|
1 |
|
$this->_signatureAlgorithm); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
/** |
166
|
|
|
* Get certification request as a PEM formatted string. |
167
|
|
|
* |
168
|
|
|
* @return string |
169
|
|
|
*/ |
170
|
1 |
|
public function __toString() { |
171
|
1 |
|
return $this->toPEM()->string(); |
172
|
|
|
} |
173
|
|
|
} |
174
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.