forked from Automattic/fb-instant-articles
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclass-instant-articles-signer.php
88 lines (73 loc) · 2.49 KB
/
class-instant-articles-signer.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<?php
/**
* Facebook Instant Articles for WP.
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
*
* @package default
*/
/**
* Class responsible for handling the signature of graph rescrape calls
*
* @since 4.1
*/
class Instant_Articles_Signer {
const PUBLIC_KEY_OPTION = 'instant-articles-rescrape-public-key';
const PRIVATE_KEY_OPTION = 'instant-articles-rescrape-private-key';
const PUBLIC_KEY_PATH = '.well-known/graph-api/apikey.pub';
public static function init() {
add_action( 'wp', array( 'Instant_Articles_Signer', 'output_public_key' ) );
}
public static function output_public_key() {
global $wp;
if ( $wp->request == self::PUBLIC_KEY_PATH ) {
status_header(200);
echo self::get_public_key();
die();
}
}
public static function get_public_key() {
$public_key = get_option( self::PUBLIC_KEY_OPTION );
if ( ! $public_key ) {
self::gen_keys();
$public_key = get_option( self::PUBLIC_KEY_OPTION );
}
return $public_key;
}
public static function get_private_key() {
$private_key = get_option( self::PRIVATE_KEY_OPTION );
if ( ! $private_key ) {
self::gen_keys();
$private_key = get_option( self::PRIVATE_KEY_OPTION );
}
return $private_key;
}
private static function gen_keys( $force = false ) {
$public_key = get_option( self::PUBLIC_KEY_OPTION );
$private_key = get_option( self::PRIVATE_KEY_OPTION );
if ( !$force && $private_key && $public_key ) {
return;
}
// Create the private and public key
$result = openssl_pkey_new();
// Extract the private key from $result to $private_key
openssl_pkey_export( $result, $private_key );
// Extract the public key from $result to $public_key
$public_key = openssl_pkey_get_details( $result );
$public_key = $public_key["key"];
update_option( self::PRIVATE_KEY_OPTION, $private_key );
update_option( self::PUBLIC_KEY_OPTION, $public_key );
}
public static function get_signature( $data ) {
openssl_sign( $data, $signature, self::get_private_key(), OPENSSL_ALGO_SHA1 );
return urlencode( base64_encode( $signature ) );
}
public static function sign_request_path( $path ) {
$now = new DateTime();
$ts = $now->getTimestamp();
$path = add_query_arg( 'ts', $ts, $path );
$signature = self::get_signature( urldecode($path) );
$path = add_query_arg( 'hmac', $signature, $path );
return $path;
}
}