forked from Automattic/wordpress-activitypub
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclass-signature.php
118 lines (91 loc) · 2.77 KB
/
class-signature.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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
namespace Activitypub;
/**
* ActivityPub Signature Class
*
* @author Matthias Pfefferle
*/
class Signature {
/**
* @param int $user_id
*
* @return mixed
*/
public static function get_public_key( $user_id, $force = false ) {
$key = \get_user_meta( $user_id, 'magic_sig_public_key' );
if ( $key && ! $force ) {
return $key[0];
}
self::generate_key_pair( $user_id );
$key = \get_user_meta( $user_id, 'magic_sig_public_key' );
return $key[0];
}
/**
* @param int $user_id
*
* @return mixed
*/
public static function get_private_key( $user_id, $force = false ) {
$key = \get_user_meta( $user_id, 'magic_sig_private_key' );
if ( $key && ! $force ) {
return $key[0];
}
self::generate_key_pair( $user_id );
$key = \get_user_meta( $user_id, 'magic_sig_private_key' );
return $key[0];
}
/**
* Generates the pair keys
*
* @param int $user_id
*/
public static function generate_key_pair( $user_id ) {
$config = array(
'digest_alg' => 'sha512',
'private_key_bits' => 2048,
'private_key_type' => \OPENSSL_KEYTYPE_RSA,
);
$key = \openssl_pkey_new( $config );
$priv_key = null;
\openssl_pkey_export( $key, $priv_key );
// private key
\update_user_meta( $user_id, 'magic_sig_private_key', $priv_key );
$detail = \openssl_pkey_get_details( $key );
// public key
\update_user_meta( $user_id, 'magic_sig_public_key', $detail['key'] );
}
public static function generate_signature( $user_id, $url, $date, $digest = null ) {
$key = self::get_private_key( $user_id );
$url_parts = \wp_parse_url( $url );
$host = $url_parts['host'];
$path = '/';
// add path
if ( ! empty( $url_parts['path'] ) ) {
$path = $url_parts['path'];
}
// add query
if ( ! empty( $url_parts['query'] ) ) {
$path .= '?' . $url_parts['query'];
}
if ( ! empty( $digest ) ) {
$signed_string = "(request-target): post $path\nhost: $host\ndate: $date\ndigest: SHA-256=$digest";
} else {
$signed_string = "(request-target): post $path\nhost: $host\ndate: $date";
}
$signature = null;
\openssl_sign( $signed_string, $signature, $key, \OPENSSL_ALGO_SHA256 );
$signature = \base64_encode( $signature ); // phpcs:ignore
$key_id = \get_author_posts_url( $user_id ) . '#main-key';
if ( ! empty( $digest ) ) {
return \sprintf( 'keyId="%s",algorithm="rsa-sha256",headers="(request-target) host date digest",signature="%s"', $key_id, $signature );
} else {
return \sprintf( 'keyId="%s",algorithm="rsa-sha256",headers="(request-target) host date",signature="%s"', $key_id, $signature );
}
}
public static function verify_signature( $headers, $signature ) {
}
public static function generate_digest( $body ) {
$digest = \base64_encode( \hash( 'sha256', $body, true ) ); // phpcs:ignore
return "$digest";
}
}