summaryrefslogtreecommitdiffstats
path: root/Auth/OpenID/DiffieHellman.php
blob: 9b999096aa38034faebc6618aa3976ea0533fd49 (plain)
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php

/**
 * The OpenID library's Diffie-Hellman implementation.
 *
 * PHP versions 4 and 5
 *
 * LICENSE: See the COPYING file included in this distribution.
 *
 * @access private
 * @package OpenID
 * @author JanRain, Inc. <openid@janrain.com>
 * @copyright 2005 Janrain, Inc.
 * @license http://www.gnu.org/copyleft/lesser.html LGPL
 */

require_once 'Auth/OpenID.php';
require_once 'Auth/OpenID/BigMath.php';
require_once 'Auth/OpenID/HMACSHA1.php';

function Auth_OpenID_getDefaultMod()
{
    return '155172898181473697471232257763715539915724801'.
        '966915404479707795314057629378541917580651227423'.
        '698188993727816152646631438561595825688188889951'.
        '272158842675419950341258706556549803580104870537'.
        '681476726513255747040765857479291291572334510643'.
        '245094715007229621094194349783925984760375594985'.
        '848253359305585439638443';
}

function Auth_OpenID_getDefaultGen()
{
    return '2';
}

/**
 * The Diffie-Hellman key exchange class.  This class relies on
 * {@link Auth_OpenID_MathLibrary} to perform large number operations.
 *
 * @access private
 * @package OpenID
 */
class Auth_OpenID_DiffieHellman {

    var $mod;
    var $gen;
    var $private;
    var $lib = null;

    function Auth_OpenID_DiffieHellman($mod = null, $gen = null,
                                       $private = null, $lib = null)
    {
        if ($lib === null) {
            $this->lib =& Auth_OpenID_getMathLib();
        } else {
            $this->lib =& $lib;
        }

        if ($mod === null) {
            $this->mod = $this->lib->init(Auth_OpenID_getDefaultMod());
        } else {
            $this->mod = $mod;
        }

        if ($gen === null) {
            $this->gen = $this->lib->init(Auth_OpenID_getDefaultGen());
        } else {
            $this->gen = $gen;
        }

        if ($private === null) {
            $r = $this->lib->rand($this->mod);
            $this->private = $this->lib->add($r, 1);
        } else {
            $this->private = $private;
        }

        $this->public = $this->lib->powmod($this->gen, $this->private,
                                           $this->mod);
    }

    function getSharedSecret($composite)
    {
        return $this->lib->powmod($composite, $this->private, $this->mod);
    }

    function getPublicKey()
    {
        return $this->public;
    }

    /**
     * Generate the arguments for an OpenID Diffie-Hellman association
     * request
     */
    function getAssocArgs()
    {
        $cpub = $this->lib->longToBase64($this->getPublicKey());
        $args = array(
                      'openid.dh_consumer_public' => $cpub,
                      'openid.session_type' => 'DH-SHA1'
                      );

        if ($this->lib->cmp($this->mod, Auth_OpenID_getDefaultMod()) ||
            $this->lib->cmp($this->gen, Auth_OpenID_getDefaultGen())) {
            $args['openid.dh_modulus'] = $this->lib->longToBase64($this->mod);
            $args['openid.dh_gen'] = $this->lib->longToBase64($this->gen);
        }

        return $args;
    }

    function usingDefaultValues()
    {
        return ($this->mod == Auth_OpenID_getDefaultMod() &&
                $this->gen == Auth_OpenID_getDefaultGen());
    }

    function xorSecret($composite, $secret, $hash_func)
    {
        $dh_shared = $this->getSharedSecret($composite);
        $dh_shared_str = $this->lib->longToBinary($dh_shared);
        $hash_dh_shared = $hash_func($dh_shared_str);

        $xsecret = "";
        for ($i = 0; $i < Auth_OpenID::bytes($secret); $i++) {
            $xsecret .= chr(ord($secret[$i]) ^ ord($hash_dh_shared[$i]));
        }

        return $xsecret;
    }
}