CertificationRequest   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 171
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 9

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 15
lcom 2
cbo 9
dl 0
loc 171
ccs 43
cts 43
cp 1
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A fromASN1() 0 14 2
A fromDER() 0 4 1
A fromPEM() 0 7 2
A certificationRequestInfo() 0 4 1
A signatureAlgorithm() 0 4 1
A signature() 0 4 1
A toASN1() 0 5 1
A toDER() 0 4 1
A toPEM() 0 4 1
A verify() 0 8 2
A __toString() 0 4 1
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace X509\CertificationRequest;
6
7
use ASN1\Type\UnspecifiedType;
8
use ASN1\Type\Constructed\Sequence;
9
use Sop\CryptoBridge\Crypto;
10
use Sop\CryptoEncoding\PEM;
11
use Sop\CryptoTypes\AlgorithmIdentifier\AlgorithmIdentifier;
12
use Sop\CryptoTypes\AlgorithmIdentifier\Feature\SignatureAlgorithmIdentifier;
13
use Sop\CryptoTypes\Signature\Signature;
14
15
/**
16
 * Implements <i>CertificationRequest</i> ASN.1 type.
17
 *
18
 * @link https://tools.ietf.org/html/rfc2986#section-4
19
 */
20
class CertificationRequest
21
{
22
    /**
23
     * Certification request info.
24
     *
25
     * @var CertificationRequestInfo $_certificationRequestInfo
26
     */
27
    protected $_certificationRequestInfo;
28
    
29
    /**
30
     * Signature algorithm.
31
     *
32
     * @var SignatureAlgorithmIdentifier $_signatureAlgorithm
33
     */
34
    protected $_signatureAlgorithm;
35
    
36
    /**
37
     * Signature.
38
     *
39
     * @var Signature $_signature
40
     */
41
    protected $_signature;
42
    
43
    /**
44
     * Constructor.
45
     *
46
     * @param CertificationRequestInfo $info
47
     * @param SignatureAlgorithmIdentifier $algo
48
     * @param Signature $signature
49
     */
50 6
    public function __construct(CertificationRequestInfo $info,
51
        SignatureAlgorithmIdentifier $algo, Signature $signature)
52
    {
53 6
        $this->_certificationRequestInfo = $info;
54 6
        $this->_signatureAlgorithm = $algo;
55 6
        $this->_signature = $signature;
56 6
    }
57
    
58
    /**
59
     * Initialize from ASN.1.
60
     *
61
     * @param Sequence $seq
62
     * @return self
63
     */
64 4
    public static function fromASN1(Sequence $seq): self
65
    {
66 4
        $info = CertificationRequestInfo::fromASN1($seq->at(0)->asSequence());
67 4
        $algo = AlgorithmIdentifier::fromASN1($seq->at(1)->asSequence());
68 4
        if (!$algo instanceof SignatureAlgorithmIdentifier) {
69 1
            throw new \UnexpectedValueException(
70 1
                "Unsupported signature algorithm " . $algo->oid() . ".");
71
        }
72 3
        $signature = Signature::fromSignatureData(
73 3
            $seq->at(2)
74 3
                ->asBitString()
75 3
                ->string(), $algo);
76 3
        return new self($info, $algo, $signature);
77
    }
78
    
79
    /**
80
     * Initialize from DER.
81
     *
82
     * @param string $data
83
     * @return self
84
     */
85 2
    public static function fromDER(string $data): self
86
    {
87 2
        return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence());
88
    }
89
    
90
    /**
91
     * Initialize from PEM.
92
     *
93
     * @param PEM $pem
94
     * @throws \UnexpectedValueException
95
     * @return self
96
     */
97 3
    public static function fromPEM(PEM $pem): self
98
    {
99 3
        if ($pem->type() !== PEM::TYPE_CERTIFICATE_REQUEST) {
100 1
            throw new \UnexpectedValueException("Invalid PEM type.");
101
        }
102 2
        return self::fromDER($pem->data());
103
    }
104
    
105
    /**
106
     * Get certification request info.
107
     *
108
     * @return CertificationRequestInfo
109
     */
110 3
    public function certificationRequestInfo(): CertificationRequestInfo
111
    {
112 3
        return $this->_certificationRequestInfo;
113
    }
114
    
115
    /**
116
     * Get signature algorithm.
117
     *
118
     * @return SignatureAlgorithmIdentifier
119
     */
120 2
    public function signatureAlgorithm(): SignatureAlgorithmIdentifier
121
    {
122 2
        return $this->_signatureAlgorithm;
123
    }
124
    
125
    /**
126
     * Get signature.
127
     *
128
     * @return Signature
129
     */
130 2
    public function signature(): Signature
131
    {
132 2
        return $this->_signature;
133
    }
134
    
135
    /**
136
     * Generate ASN.1 structure.
137
     *
138
     * @return Sequence
139
     */
140 4
    public function toASN1(): Sequence
141
    {
142 4
        return new Sequence($this->_certificationRequestInfo->toASN1(),
143 4
            $this->_signatureAlgorithm->toASN1(), $this->_signature->bitString());
144
    }
145
    
146
    /**
147
     * Get certification request as a DER.
148
     *
149
     * @return string
150
     */
151 2
    public function toDER(): string
152
    {
153 2
        return $this->toASN1()->toDER();
154
    }
155
    
156
    /**
157
     * Get certification request as a PEM.
158
     *
159
     * @return PEM
160
     */
161 2
    public function toPEM(): PEM
162
    {
163 2
        return new PEM(PEM::TYPE_CERTIFICATE_REQUEST, $this->toDER());
164
    }
165
    
166
    /**
167
     * Verify certification request signature.
168
     *
169
     * @param Crypto|null $crypto Crypto engine, use default if not set
170
     * @return bool True if signature matches
171
     */
172 1
    public function verify(Crypto $crypto = null): bool
173
    {
174 1
        $crypto = $crypto ?: Crypto::getDefault();
175 1
        $data = $this->_certificationRequestInfo->toASN1()->toDER();
176 1
        $pk_info = $this->_certificationRequestInfo->subjectPKInfo();
177 1
        return $crypto->verify($data, $this->_signature, $pk_info,
178 1
            $this->_signatureAlgorithm);
179
    }
180
    
181
    /**
182
     * Get certification request as a PEM formatted string.
183
     *
184
     * @return string
185
     */
186 1
    public function __toString()
187
    {
188 1
        return $this->toPEM()->string();
189
    }
190
}
191