3 * @copyright Copyright (C) 2010-2022, the Friendica project
5 * @license GNU AGPL version 3 or any later version
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 namespace Friendica\Security\OAuth1\Signature;
24 use Friendica\Security\OAuth1\OAuthRequest;
27 * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
28 * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
29 * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
30 * verified way to the Service Provider, in a manner which is beyond the scope of this
32 * - Chapter 9.3 ("RSA-SHA1")
34 abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod
36 public function get_name()
41 // Up to the SP to implement this lookup of keys. Possible ideas are:
42 // (1) do a lookup in a table of trusted certs keyed off of consumer
43 // (2) fetch via http using a url provided by the requester
44 // (3) some sort of specific discovery code based on request
46 // Either way should return a string representation of the certificate
47 protected abstract function fetch_public_cert(&$request);
49 // Up to the SP to implement this lookup of keys. Possible ideas are:
50 // (1) do a lookup in a table of trusted certs keyed off of consumer
52 // Either way should return a string representation of the certificate
53 protected abstract function fetch_private_cert(&$request);
55 public function build_signature(OAuthRequest $request, \Friendica\Security\OAuth1\OAuthConsumer $consumer, \Friendica\Security\OAuth1\OAuthToken $token = null)
57 $base_string = $request->get_signature_base_string();
58 $request->base_string = $base_string;
60 // Fetch the private key cert based on the request
61 $cert = $this->fetch_private_cert($request);
63 // Pull the private key ID from the certificate
64 $privatekeyid = openssl_get_privatekey($cert);
67 openssl_sign($base_string, $signature, $privatekeyid);
69 // Release the key resource
70 openssl_free_key($privatekeyid);
72 return base64_encode($signature);
75 public function check_signature(OAuthRequest $request, \Friendica\Security\OAuth1\OAuthConsumer $consumer, $signature, \Friendica\Security\OAuth1\OAuthToken $token = null)
77 $decoded_sig = base64_decode($signature);
79 $base_string = $request->get_signature_base_string();
81 // Fetch the public key cert based on the request
82 $cert = $this->fetch_public_cert($request);
84 // Pull the public key ID from the certificate
85 $publickeyid = openssl_get_publickey($cert);
87 // Check the computed signature against the one passed in the query
88 $ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
90 // Release the key resource
91 openssl_free_key($publickeyid);