Subversion Repositories oidplus

Rev

Rev 871 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
868 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
5
 * Copyright 2019 - 2022 Daniel Marschall, ViaThinkSoft
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
20
// Works with composer.json
21
// "sergeybrook/php-jws": "^1.0"
22
 
23
require_once __DIR__.'/vendor/aywan/php-json-canonicalization/src/Utils.php';
24
require_once __DIR__.'/vendor/aywan/php-json-canonicalization/src/JsonCanonicalizationInterface.php';
25
require_once __DIR__.'/vendor/aywan/php-json-canonicalization/src/JsonCanonicalizationFactory.php';
26
require_once __DIR__.'/vendor/aywan/php-json-canonicalization/src/Canonicalizator.php';
27
 
28
function oidplus_json_verify($json_content, $pubkey) {
29
        require_once __DIR__.'/vendor/autoload.php';
30
 
31
        $jws = new \SBrook\JWS\JwsRsa();
32
 
33
        // Load JSON
34
        $json = json_decode($json_content);
35
 
36
        // 1. Extract the contents of the "signature" key from the JSON.
37
        $signature = $json->signature;
38
 
39
        // 2. Remove the "signature" key from the JSON
40
        unset($json->signature);
41
 
42
        // 3. Canonize the JSON contents using RFC 8785
43
        $canonicalization = \aywan\JsonCanonicalization\JsonCanonicalizationFactory::getInstance();
44
        $canonical = $canonicalization->canonicalize($json);
45
        $actual_payload = $canonical;
46
 
47
        // 4. Compare the canonized JSON to the base64-encoded payload of the JSON Web Signature.
48
        $expected_payload = $jws->getPayload($signature);
49
        if ($actual_payload != $expected_payload) {
50
                // echo "Actual:\n\n$actual_payload\n\n";
51
                // echo "Expected:\n\n$expected_payload\n\n";
52
                throw new Exception("Signature verification failed (Payload different)");
53
        }
54
 
55
        // 5. Verify the JSON Web Signature according to RFC 7515
56
        $jws->setPublicKey($pubkey);
57
        $v = $jws->verify($signature);
58
        if (!$v) {
59
                throw new Exception("Signature verification failed!");
60
        }
61
}
62
 
63
function oidplus_json_sign($json_content, $privkey, $pubkey) {
64
        require_once __DIR__.'/vendor/autoload.php';
65
 
66
        $jws = new \SBrook\JWS\JwsRsa();
67
 
68
        // Load JSON
69
        $input = json_decode($json_content);
70
 
71
        // 1. Make sure that the JSON file has no signature (remove "signature" key if one exists).
72
        unset($input->signature);
73
 
74
        // 2. Canonize the JSON contents using RFC 8785
75
        $canonicalization = \aywan\JsonCanonicalization\JsonCanonicalizationFactory::getInstance();
76
        $canonical = $canonicalization->canonicalize($input);
77
 
78
        // 3. Sign the canonized JSON using a JSON Web Signature (JWS, RFC 7515)
79
 
80
        // For JWS registered header parameter names see (RFC 7515, Section 4.1)
81
        $header = [
82
                "typ" => "JSON",
83
                "cty" => "text/json"
84
        ];
85
        $payload = $canonical;
86
        $jws->setPrivateKey($privkey, '');
87
        $signature = $jws->sign($payload, $header);
88
 
89
        // 4. Add the key "signature" into the final JSON. Note that the final JSON does not need to be canonized. It can be pretty-printed.
90
        $output = $input;
91
        $output->signature = $signature;
92
 
93
        // Self-test and output
94
        $json_signed = json_encode($output);
95
        oidplus_json_verify($json_signed, $pubkey);
96
        return $json_signed;
97
}