streams/Code/Lib/LDSignatures.php

99 lines
2.5 KiB
PHP
Raw Normal View History

<?php
2022-02-16 04:08:28 +00:00
namespace Code\Lib;
2021-12-02 22:33:36 +00:00
use Exception;
2021-01-23 00:59:56 +00:00
require_once('library/jsonld/jsonld.php');
2021-12-02 23:02:31 +00:00
class LDSignatures
{
2022-08-23 11:01:09 +00:00
public static function verify($data, $pubkey): bool
2021-12-02 23:02:31 +00:00
{
$ohash = self::hash(self::signable_options($data['signature']));
$dhash = self::hash(self::signable_data($data));
$x = Crypto::verify($ohash . $dhash, base64_decode($data['signature']['signatureValue']), $pubkey);
logger('LD-verify: ' . intval($x));
return $x;
}
2022-08-23 11:01:09 +00:00
public static function sign($data, $channel): array
2021-12-02 23:02:31 +00:00
{
$options = [
'type' => 'RsaSignature2017',
2022-08-23 11:01:09 +00:00
'nonce' => random_string(),
2022-01-25 01:26:12 +00:00
'creator' => Channel::url($channel),
2021-12-02 23:02:31 +00:00
'created' => datetime_convert('UTC', 'UTC', 'now', 'Y-m-d\TH:i:s\Z')
];
$ohash = self::hash(self::signable_options($options));
$dhash = self::hash(self::signable_data($data));
$options['signatureValue'] = base64_encode(Crypto::sign($ohash . $dhash, $channel['channel_prvkey']));
return $options;
}
2022-08-23 11:01:09 +00:00
public static function signable_data($data): bool|string
2021-12-02 23:02:31 +00:00
{
$newdata = [];
if ($data) {
foreach ($data as $k => $v) {
2022-08-23 11:01:09 +00:00
if ($k != 'signature') {
2021-12-02 23:02:31 +00:00
$newdata[$k] = $v;
}
}
}
return json_encode($newdata, JSON_UNESCAPED_SLASHES);
}
2022-08-23 11:01:09 +00:00
public static function signable_options($options): bool|string
2021-12-02 23:02:31 +00:00
{
$newopts = ['@context' => 'https://w3id.org/identity/v1'];
if ($options) {
foreach ($options as $k => $v) {
if (!in_array($k, ['type', 'id', 'signatureValue'])) {
$newopts[$k] = $v;
}
}
}
return json_encode($newopts, JSON_UNESCAPED_SLASHES);
}
2022-08-23 11:01:09 +00:00
public static function hash($obj): string
2021-12-02 23:02:31 +00:00
{
return hash('sha256', self::normalise($obj));
}
public static function normalise($data)
{
if (is_string($data)) {
$data = json_decode($data);
}
2021-12-03 03:01:39 +00:00
if (!is_object($data)) {
2021-12-02 23:02:31 +00:00
return '';
2021-12-03 03:01:39 +00:00
}
2022-08-23 11:01:09 +00:00
$d = '';
2021-12-02 23:02:31 +00:00
jsonld_set_document_loader('jsonld_document_loader');
try {
$d = jsonld_normalize($data, ['algorithm' => 'URDNA2015', 'format' => 'application/nquads']);
} catch (Exception $e) {
// Don't log the exception - this can exhaust memory
// logger('normalise error:' . print_r($e,true));
logger('normalise error: ' . print_r($data, true));
}
return $d;
}
2021-12-03 03:01:39 +00:00
}