Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
RsaSha1
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
3 / 3
3
100.00% covered (success)
100.00%
1 / 1
 getName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fetchPublicCert
n/a
0 / 0
n/a
0 / 0
0
 fetchPrivateCert
n/a
0 / 0
n/a
0 / 0
0
 buildSignature
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 checkSignature
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * @section LICENSE
4 * Copyright (c) 2007 Andy Smith
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including without
9 * limitation the rights to use, copy, modify, merge, publish, distribute,
10 * sublicense, and/or sell copies of the Software, and to permit persons to
11 * whom the Software is furnished to do so, subject to the following
12 * conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 * @file
26 */
27
28namespace MediaWiki\OAuthClient\SignatureMethod;
29
30use MediaWiki\OAuthClient\Consumer;
31use MediaWiki\OAuthClient\Request;
32use MediaWiki\OAuthClient\SignatureMethod;
33use MediaWiki\OAuthClient\Token;
34
35/**
36 * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature
37 * algorithm as defined in [RFC3447] section 8.2 (more simply known as
38 * PKCS#1), using SHA-1 as the hash function for EMSA-PKCS1-v1_5. It is
39 * assumed that the Consumer has provided its RSA public key in a verified way
40 * to the Service Provider, in a manner which is beyond the scope of this
41 * specification.
42 *   - Chapter 9.3 ("RSA-SHA1")
43 */
44abstract class RsaSha1 extends SignatureMethod {
45
46    /**
47     * @return string
48     */
49    public function getName() {
50        return "RSA-SHA1";
51    }
52
53    /**
54     * Up to the SP to implement this lookup of keys. Possible ideas are:
55     * (1) do a lookup in a table of trusted certs keyed off of consumer
56     * (2) fetch via http using a url provided by the requester
57     * (3) some sort of specific discovery code based on request
58     * Either way should return a string representation of the certificate
59     * @param Request $request
60     */
61    abstract protected function fetchPublicCert( Request $request );
62
63    /**
64     * Up to the SP to implement this lookup of keys. Possible ideas are:
65     * (1) do a lookup in a table of trusted certs keyed off of consumer
66     * Either way should return a string representation of the certificate
67     * @param Request $request
68     */
69    abstract protected function fetchPrivateCert( Request $request );
70
71    /**
72     * @param Request $request
73     * @param Consumer $consumer
74     * @param Token|null $token
75     * @return string
76     */
77    public function buildSignature(
78        Request $request,
79        Consumer $consumer,
80        Token $token = null
81    ) {
82        $base_string = $request->getSignatureBaseString();
83        $request->base_string = $base_string;
84
85        // Fetch the private key cert based on the request
86        $cert = $this->fetchPrivateCert( $request );
87
88        // Pull the private key ID from the certificate
89        $privatekeyid = openssl_get_privatekey( $cert );
90
91        // Sign using the key
92        $ok = openssl_sign( $base_string, $signature, $privatekeyid );
93
94        // Release the key resource
95        openssl_free_key( $privatekeyid );
96
97        return base64_encode( $signature );
98    }
99
100    /**
101     * @param Request $request
102     * @param Consumer $consumer
103     * @param Token|null $token
104     * @param string $signature
105     * @return bool
106     */
107    public function checkSignature(
108        Request $request,
109        Consumer $consumer,
110        /*Token*/ $token,
111        $signature
112    ) {
113        $decoded_sig = base64_decode( $signature );
114
115        $base_string = $request->getSignatureBaseString();
116
117        // Fetch the public key cert based on the request
118        $cert = $this->fetchPublicCert( $request );
119
120        // Pull the public key ID from the certificate
121        $publickeyid = openssl_get_publickey( $cert );
122
123        // Check the computed signature against the one passed in the query
124        $ok = openssl_verify( $base_string, $decoded_sig, $publickeyid );
125
126        // Release the key resource
127        openssl_free_key( $publickeyid );
128
129        return $ok == 1;
130    }
131}