Completed
Push — master ( 4df167...f708ed )
by Florent
02:36
created

RSA::getRsaObject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 10
rs 9.4285
cc 1
eloc 7
nc 1
nop 0
1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2016 Spomky-Labs
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license.  See the LICENSE file for details.
10
 */
11
12
namespace Jose\Algorithm\Signature;
13
14
use Assert\Assertion;
15
use Jose\Algorithm\SignatureAlgorithmInterface;
16
use Jose\KeyConverter\RSAKey;
17
use Jose\Object\JWKInterface;
18
use phpseclib\Crypt\RSA as PHPSecLibRSA;
19
20
/**
21
 * Class RSA.
22
 */
23
abstract class RSA implements SignatureAlgorithmInterface
24
{
25
    /**
26
     * Probabilistic Signature Scheme
27
     */
28
    const SIGNATURE_PSS = 1;
29
30
    /**
31
     * Use the PKCS#1
32
     */
33
    const SIGNATURE_PKCS1 = 2;
34
35
    /**
36
     * @return mixed
37
     */
38
    abstract protected function getAlgorithm();
39
40
    /**
41
     * @return mixed
42
     */
43
    abstract protected function getSignatureMethod();
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function verify(JWKInterface $key, $input, $signature)
49
    {
50
        $this->checkKey($key);
51
52
        $pem = RSAKey::toPublic(new RSAKey($key))->toPEM();
53
54
        if ($this->getSignatureMethod() === self::SIGNATURE_PSS) {
55
            $rsa = $this->getRsaObject();
56
            $rsa->loadKey($pem, PHPSecLibRSA::PRIVATE_FORMAT_PKCS1);
57
58
            return $rsa->verify($input, $signature);
59
        } else {
60
            return 1 === openssl_verify($input, $signature, $pem, $this->getAlgorithm());
61
        }
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67
    public function sign(JWKInterface $key, $input)
68
    {
69
        $this->checkKey($key);
70
        Assertion::true($key->has('d'), 'The key is not a private key');
71
72
        $pem = (new RSAKey($key))->toPEM();
73
74
        if ($this->getSignatureMethod() === self::SIGNATURE_PSS) {
75
            $rsa = $this->getRsaObject();
76
            $rsa->loadKey($pem, PHPSecLibRSA::PRIVATE_FORMAT_PKCS1);
77
            $result = $rsa->sign($input);
78
            Assertion::string($result, 'An error occurred during the creation of the signature');
79
80
            return $result;
81
        } else {
82
            $result = openssl_sign($input, $signature, $pem, $this->getAlgorithm());
83
            Assertion::true($result, 'Unable to sign');
84
85
            return $signature;
86
        }
87
    }
88
89
    /**
90
     * @param JWKInterface $key
91
     */
92
    private function checkKey(JWKInterface $key)
93
    {
94
        Assertion::eq($key->get('kty'), 'RSA', 'Wrong key type.');
95
    }
96
97
    /**
98
     * @return \phpseclib\Crypt\RSA
99
     */
100
    private function getRsaObject()
101
    {
102
        $rsa = new PHPSecLibRSA();
103
        $rsa->setHash($this->getAlgorithm());
104
        $rsa->setMGFHash($this->getAlgorithm());
105
        $rsa->setSaltLength(0);
106
        $rsa->setSignatureMode(PHPSecLibRSA::SIGNATURE_PSS);
107
108
        return $rsa;
109
    }
110
}
111