119 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?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";
 | |
| 	}
 | |
| }
 |