diff options
-rw-r--r-- | Auth/OpenID/Association.php | 118 | ||||
-rw-r--r-- | Auth/OpenID/Consumer.php | 286 | ||||
-rw-r--r-- | Auth/OpenID/DiffieHellman.php | 55 | ||||
-rw-r--r-- | Auth/OpenID/Server.php | 16 | ||||
-rw-r--r-- | Tests/Auth/OpenID/Consumer.php | 181 | ||||
-rw-r--r-- | Tests/Auth/OpenID/Server.php | 4 |
6 files changed, 358 insertions, 302 deletions
diff --git a/Auth/OpenID/Association.php b/Auth/OpenID/Association.php index ef7b734..9e7ac14 100644 --- a/Auth/OpenID/Association.php +++ b/Auth/OpenID/Association.php @@ -350,4 +350,122 @@ class Auth_OpenID_Association { } } +function Auth_OpenID_getSessionTypes($assoc_type) +{ + $assoc_to_session = array( + 'HMAC-SHA1' => array('DH-SHA1', 'no-encryption'), + 'HMAC-SHA256' => array('DH-SHA256', 'no-encryption')); + return Auth_OpenID::arrayGet($assoc_to_session, $assoc_type, array()); +} + +function Auth_OpenID_checkSessionType($assoc_type, $session_type) +{ + if (!in_array($session_type, + Auth_OpenID_getSessionTypes($assoc_type))) { + return false; + } + + return true; +} + +function Auth_OpenID_getDefaultAssociationOrder() +{ + return array( + array('HMAC-SHA1', 'DH-SHA1'), + array('HMAC-SHA1', 'no-encryption')); +} + +function Auth_OpenID_getOnlyEncryptedOrder() +{ + return array( + array('HMAC-SHA1', 'DH-SHA1')); +} + +function Auth_OpenID_getDefaultNegotiator() +{ + return new Auth_OpenID_SessionNegotiator( + Auth_OpenID_getDefaultAssociationOrder()); +} + +function Auth_OpenID_getEncryptedNegotiator() +{ + return new Auth_OpenID_SessionNegotiator( + Auth_OpenID_getOnlyEncryptedOrder()); +} + +class Auth_OpenID_SessionNegotiator { + function Auth_OpenID_SessionNegotiator($allowed_types) + { + $this->allowed_types = $allowed_types; + } + + // Set the allowed association types, checking to make sure each + // combination is valid. + function setAllowedTypes($allowed_types) + { + foreach ($allowed_types as $pair) { + list($assoc_type, $session_type) = $pair; + if (!Auth_OpenID_checkSessionType($assoc_type, $session_type)) { + return false; + } + } + + $this->allowed_types = $allowed_types; + return true; + } + + // Add an association type and session type to the allowed types + // list. The assocation/session pairs are tried in the order that + // they are added. + function addAllowedType($assoc_type, $session_type = null) + { + if ($this->allowed_types === null) { + $this->allowed_types = array(); + } + + if ($session_type === null) { + $available = Auth_OpenID_getSessionTypes($assoc_type); + + if (!$available) { + return false; + } + + foreach ($available as $session_type) { + $this->addAllowedType($assoc_type, $session_type); + } + } else { + if (Auth_OpenID_checkSessionType($assoc_type, $session_type)) { + $this->allowed_types[] = array($assoc_type, $session_type); + } else { + return false; + } + } + + return true; + } + + // Is this combination of association type and session type allowed? + function isAllowed($assoc_type, $session_type) + { + $assoc_good = in_array(array($assoc_type, $session_type), + $this->allowed_types); + + $matches = in_array($session_type, + Auth_OpenID_getSessionTypes($assoc_type)); + + return ($assoc_good && $matches); + } + + // Get a pair of assocation type and session type that are + // supported + function getAllowedType() + { + if (!$this->allowed_types) { + return array(null, null); + } + + return $this->allowed_types[0]; + } +} + ?>
\ No newline at end of file diff --git a/Auth/OpenID/Consumer.php b/Auth/OpenID/Consumer.php index ba3ffc9..3c8ccb6 100644 --- a/Auth/OpenID/Consumer.php +++ b/Auth/OpenID/Consumer.php @@ -402,10 +402,13 @@ class Auth_OpenID_Consumer { } } -class Auth_OpenID_DiffieHellmanConsumerSession { +class Auth_OpenID_DiffieHellmanSHA1ConsumerSession { var $session_type = 'DH-SHA1'; + var $hash_func = 'Auth_OpenID_SHA1'; + var $secret_size = 20; + var $allowed_assoc_types = array('HMAC-SHA1'); - function Auth_OpenID_DiffieHellmanConsumerSession($dh = null) + function Auth_OpenID_DiffieHellmanSHA1ConsumerSession($dh = null) { if ($dh === null) { $dh = new Auth_OpenID_DiffieHellman(); @@ -420,14 +423,14 @@ class Auth_OpenID_DiffieHellmanConsumerSession { $cpub = $math->longToBase64($this->dh->public); - $args = array('openid.dh_consumer_public' => $cpub); + $args = array('dh_consumer_public' => $cpub); if (!$this->dh->usingDefaultValues()) { $args = array_merge($args, array( - 'openid.dh_modulus' => + 'dh_modulus' => $math->longToBase64($this->dh->mod), - 'openid.dh_gen' => - $math->longToBase64($this->dh->gen))); + 'dh_gen' => + $math->longToBase64($this->dh->gen))); } return $args; @@ -446,17 +449,19 @@ class Auth_OpenID_DiffieHellmanConsumerSession { } $math =& Auth_OpenID_getMathLib(); + $spub = $math->base64ToLong($response->getArg(Auth_OpenID_OPENID_NS, 'dh_server_public')); $enc_mac_key = base64_decode($response->getArg(Auth_OpenID_OPENID_NS, 'enc_mac_key')); - return $this->dh->xorSecret($spub, $enc_mac_key); + return $this->dh->xorSecret($spub, $enc_mac_key, $this->hash_func); } } class Auth_OpenID_PlainTextConsumerSession { - var $session_type = null; + var $session_type = 'no-encryption'; + var $allowed_assoc_types = array('HMAC-SHA1'); function getRequest() { @@ -514,9 +519,16 @@ class Auth_OpenID_GenericConsumer { function Auth_OpenID_GenericConsumer(&$store) { $this->store =& $store; + $this->negotiator =& Auth_OpenID_getDefaultNegotiator(); $this->_use_assocs = !($this->store && $this->store->isDumb()); $this->fetcher = Services_Yadis_Yadis::getHTTPFetcher(); + + $this->session_types = array( + 'DH-SHA1' => 'Auth_OpenID_DiffieHellmanSHA1ConsumerSession', + // 'DH-SHA256' => 'Auth_OpenID_DiffieHellmanSHA256ConsumerSession', + 'no-encryption' => 'Auth_OpenID_PlainTextConsumerSession' + ); } function begin($service_endpoint) @@ -813,109 +825,241 @@ class Auth_OpenID_GenericConsumer { if (($assoc === null) || ($assoc->getExpiresIn() <= 0)) { - $parts = $this->_createAssociateRequest($endpoint->server_url); + $assoc = $this->_negotiateAssociation($endpoint); + if ($assoc !== null) { + $this->store->storeAssociation($endpoint->server_url, + $assoc); + } + } + + return $assoc; + } - if ($parts === null) { + function _negotiateAssociation($endpoint) + { + # Get our preferred session/association type from the negotiatior. + list($assoc_type, $session_type) = $this->negotiator->getAllowedType(); + + $assoc = $this->_requestAssociation( + $endpoint, $assoc_type, $session_type); + + if (is_a($assoc, 'Auth_OpenID_ServerError')) { + // Any error message whose code is not 'unsupported-type' + // should be considered a total failure. + if (($why->error_code != 'unsupported-type') || + ($why->message->isOpenID1())) { + // oidutil.log( + // 'Server error when requesting an association from %r: %s' + // % (endpoint.server_url, why.error_text)) return null; } - list($assoc_session, $message) = $parts; + // The server didn't like the association/session type + // that we sent, and it sent us back a message that + // might tell us how to handle it. + // oidutil.log( + // 'Unsupported association type %s: %s' % (assoc_type, + // why.error_text,)) - $response = $this->_makeKVPost($message, $endpoint->server_url); + // Extract the session_type and assoc_type from the + // error message + $assoc_type = $why->message->getArg(Auth_OpenID_OPENID_NS, + 'assoc_type'); - if ($response === null) { - $assoc = null; + $session_type = $why->message->getArg(Auth_OpenID_OPENID_NS, + 'session_type'); + + if (($assoc_type === null) || ($session_type === null)) { + // oidutil.log('Server responded with unsupported association ' + // 'session but did not supply a fallback.') + return null; + } else if (!$self->negotiator->isAllowed($assoc_type, + $session_type)) { + // fmt = ('Server sent unsupported session/association type: ' + // 'session_type=%s, assoc_type=%s') + // oidutil.log(fmt % (session_type, assoc_type)) + return null; } else { - $assoc = $this->_parseAssociation($response, $assoc_session, - $endpoint->server_url); + // Attempt to create an association from the assoc_type + // and session_type that the server told us it + // supported. + $assoc = $self->_requestAssociation( + $endpoint, $assoc_type, $session_type); + + if (is_a($assoc, 'Auth_OpenID_ServerError')) { + // Do not keep trying, since it rejected the + // association type that it told us to use. + // oidutil.log('Server %s refused its suggested association + // 'type: session_type=%s, assoc_type=%s' + // % (endpoint.server_url, session_type, + // assoc_type)) + return null; + } else { + return $assoc; + } } } return $assoc; } - function _createAssociateRequest($server_url) + function _requestAssociation($endpoint, $assoc_type, $session_type) { - $parts = parse_url($server_url); + list($assoc_session, $args) = $this->_createAssociateRequest( + $endpoint, $assoc_type, $session_type); - if ($parts === false) { - return null; - } + $response = $this->_makeKVPost($args, $endpoint->server_url); - if (array_key_exists('scheme', $parts)) { - $proto = $parts['scheme']; - } else { - $proto = 'http'; + if ($response === null) { + // oidutil.log('openid.associate request failed: %s' % (why[0],)) + return null; } - if ($proto == 'https' || defined('Auth_OpenID_NO_MATH_SUPPORT')) { - $assoc_session = new Auth_OpenID_PlainTextConsumerSession(); - } else { - $assoc_session = new Auth_OpenID_DiffieHellmanConsumerSession(); - } + return $this->_extractAssociation($response, $assoc_session); + } - $args = array( - 'openid.mode' => 'associate', - 'openid.assoc_type' => 'HMAC-SHA1'); + function _extractAssociation($assoc_response, $assoc_session) + { + // Extract the common fields from the response, raising an + // exception if they are not found + $assoc_type = $assoc_response->getArg( + Auth_OpenID_OPENID_NS, 'assoc_type', + Auth_OpenID_NO_DEFAULT); + + $assoc_handle = $assoc_response->getArg( + Auth_OpenID_OPENID_NS, 'assoc_handle', + Auth_OpenID_NO_DEFAULT); + + // expires_in is a base-10 string. The Python parsing will + // accept literals that have whitespace around them and will + // accept negative values. Neither of these are really in-spec, + // but we think it's OK to accept them. + $expires_in_str = $assoc_response->getArg( + Auth_OpenID_OPENID_NS, 'expires_in', + Auth_OpenID_NO_DEFAULT); - if ($assoc_session->session_type !== null) { - $args['openid.session_type'] = $assoc_session->session_type; + $expires_in = intval($expires_in_str); + if ($expires_in === false) { + // raise ProtocolError('Invalid expires_in field: %s' % (why[0],)) + return null; } - $args = array_merge($args, $assoc_session->getRequest()); - $msg = Auth_OpenID_Message::fromPostArgs($args); - - return array($assoc_session, $msg); - } + // OpenID 1 has funny association session behaviour. + if ($assoc_response->isOpenID1()) { + $session_type = $this->_getOpenID1SessionType($assoc_response); + } else { + $session_type = $assoc_response->getArg( + Auth_OpenID_OPENID2_NS, 'session_type', + Auth_OpenID_NO_DEFAULT); + } - /** - * @access private - */ - function _parseAssociation($results, $assoc_session, $server_url) - { - $required_keys = array('assoc_type', 'assoc_handle', - 'expires_in'); + // Session type mismatch + if ($assoc_session->session_type != $session_type) { + if ($assoc_response->isOpenID1() && + ($session_type == 'no-encryption')) { + // In OpenID 1, any association request can result in + // a 'no-encryption' association response. Setting + // assoc_session to a new no-encryption session should + // make the rest of this function work properly for + // that case. + $assoc_session = new Auth_OpenID_PlainTextConsumerSession(); + } else { + // Any other mismatch, regardless of protocol version + // results in the failure of the association session + // altogether. - foreach ($required_keys as $key) { - if (!$results->hasKey(Auth_OpenID_OPENID_NS, $key)) { + // fmt = 'Session type mismatch. Expected %r, got %r' + // message = fmt % (assoc_session.session_type, session_type) + // raise ProtocolError(message) return null; } } - $assoc_type = $results->getArg(Auth_OpenID_OPENID_NS, 'assoc_type'); - $assoc_handle = $results->getArg(Auth_OpenID_OPENID_NS, 'assoc_handle'); - $expires_in_str = $results->getArg(Auth_OpenID_OPENID_NS, 'expires_in'); - - if ($assoc_type != 'HMAC-SHA1') { + // Make sure assoc_type is valid for session_type + if (!in_array($assoc_type, $assoc_session->allowed_assoc_types)) { + // fmt = 'Unsupported assoc_type for session %s returned: %s' + // raise ProtocolError(fmt % (assoc_session.session_type, + // assoc_type)) return null; } - $expires_in = intval($expires_in_str); + // Delegate to the association session to extract the secret + // from the response, however is appropriate for that session + // type. + $secret = $assoc_session->extractSecret($assoc_response); - if ($expires_in <= 0) { + if ($secret === null) { + // fmt = 'Malformed response for %s session: %s' + // raise ProtocolError(fmt % (assoc_session.session_type, why[0])) return null; } - $session_type = $results->getArg(Auth_OpenID_OPENID_NS, 'session_type'); - if ($session_type != $assoc_session->session_type) { - if ($session_type === null) { - $assoc_session = new Auth_OpenID_PlainTextConsumerSession(); - } else { - return null; - } - } + return Auth_OpenID_Association::fromExpiresIn( + $expires_in, $assoc_handle, $secret, $assoc_type); + } - $secret = $assoc_session->extractSecret($results); + function _createAssociateRequest($endpoint, $assoc_type, $session_type) + { + $session_type_class = $this->session_types[$session_type]; + $assoc_session = new $session_type_class(); - if (!$secret) { - return null; + $args = array( + 'mode' => 'associate', + 'assoc_type' => $assoc_type); + + if (!$endpoint->compatibilityMode()) { + $args['ns'] = Auth_OpenID_OPENID2_NS; } - $assoc = Auth_OpenID_Association::fromExpiresIn( - $expires_in, $assoc_handle, $secret, $assoc_type); - $this->store->storeAssociation($server_url, $assoc); + // Leave out the session type if we're in compatibility mode + // *and* it's no-encryption. + if ((!$endpoint->compatibilityMode()) || + ($assoc_session->session_type != 'no-encryption')) { + $args['session_type'] = $assoc_session->session_type; + } - return $assoc; + $args = array_merge($args, $assoc_session->getRequest()); + $message = Auth_OpenID_Message::fromOpenIDArgs($args); + return array($assoc_session, $message); + } + + // Given an association response message, extract the OpenID 1.X + // session type. + // + // This function mostly takes care of the 'no-encryption' default + // behavior in OpenID 1. + // + // If the association type is plain-text, this function will + // return 'no-encryption' + // + // @returns: The association type for this message + // @rtype: str + // + // @raises: KeyError, if the session_type field is absent. + function _getOpenID1SessionType($assoc_response) + { + // If it's an OpenID 1 message, allow session_type to default + // to None (which signifies "no-encryption") + $session_type = $assoc_response->getArg(Auth_OpenID_OPENID1_NS, + 'session_type'); + + // Handle the differences between no-encryption association + // respones in OpenID 1 and 2: + + // no-encryption is not really a valid session type for OpenID + // 1, but we'll accept it anyway, while issuing a warning. + if ($session_type == 'no-encryption') { + // oidutil.log('WARNING: OpenID server sent "no-encryption"' + // 'for OpenID 1.X') + } else if (($session_type == '') || ($session_type === null)) { + // Missing or empty session type is the way to flag a + // 'no-encryption' response. Change the session type to + // 'no-encryption' so that it can be handled in the same + // way as OpenID 2 'no-encryption' respones. + $session_type = 'no-encryption'; + } + + return $session_type; } } diff --git a/Auth/OpenID/DiffieHellman.php b/Auth/OpenID/DiffieHellman.php index 2b845b7..0551390 100644 --- a/Auth/OpenID/DiffieHellman.php +++ b/Auth/OpenID/DiffieHellman.php @@ -116,64 +116,15 @@ class Auth_OpenID_DiffieHellman { $this->gen == Auth_OpenID_getDefaultGen()); } - /** - * Perform the server side of the OpenID Diffie-Hellman association - */ - function serverAssociate($consumer_args, $assoc_secret) - { - $lib =& Auth_OpenID_getMathLib(); - - if (isset($consumer_args['openid.dh_modulus'])) { - $mod = $lib->base64ToLong($consumer_args['openid.dh_modulus']); - } else { - $mod = null; - } - - if (isset($consumer_args['openid.dh_gen'])) { - $gen = $lib->base64ToLong($consumer_args['openid.dh_gen']); - } else { - $gen = null; - } - - $cpub64 = @$consumer_args['openid.dh_consumer_public']; - if (!isset($cpub64)) { - return false; - } - - $dh = new Auth_OpenID_DiffieHellman($mod, $gen); - $cpub = $lib->base64ToLong($cpub64); - $mac_key = $dh->xorSecret($cpub, $assoc_secret); - $enc_mac_key = base64_encode($mac_key); - $spub64 = $lib->longToBase64($dh->getPublicKey()); - - $server_args = array( - 'session_type' => 'DH-SHA1', - 'dh_server_public' => $spub64, - 'enc_mac_key' => $enc_mac_key - ); - - return $server_args; - } - - function consumerFinish($reply) - { - $spub = $this->lib->base64ToLong($reply['dh_server_public']); - if ($this->lib->cmp($spub, 0) <= 0) { - return false; - } - $enc_mac_key = base64_decode($reply['enc_mac_key']); - return $this->xorSecret($spub, $enc_mac_key); - } - - function xorSecret($composite, $secret) + function xorSecret($composite, $secret, $hash_func) { $dh_shared = $this->getSharedSecret($composite); $dh_shared_str = $this->lib->longToBinary($dh_shared); - $sha1_dh_shared = Auth_OpenID_SHA1($dh_shared_str); + $hash_dh_shared = $hash_func($dh_shared_str); $xsecret = ""; for ($i = 0; $i < strlen($secret); $i++) { - $xsecret .= chr(ord($secret[$i]) ^ ord($sha1_dh_shared[$i])); + $xsecret .= chr(ord($secret[$i]) ^ ord($hash_dh_shared[$i])); } return $xsecret; diff --git a/Auth/OpenID/Server.php b/Auth/OpenID/Server.php index 130f541..eb6c688 100644 --- a/Auth/OpenID/Server.php +++ b/Auth/OpenID/Server.php @@ -363,6 +363,7 @@ class Auth_OpenID_PlainTextServerSession { */ var $session_type = 'plaintext'; var $needs_math = false; + var $allowed_assoc_types = array('HMAC-SHA1'); function fromMessage($unused_request) { @@ -375,7 +376,7 @@ class Auth_OpenID_PlainTextServerSession { } } -class Auth_OpenID_DiffieHellmanServerSession { +class Auth_OpenID_DiffieHellmanSHA1ServerSession { /** * An object that knows how to handle association requests with * the Diffie-Hellman session type. @@ -383,8 +384,10 @@ class Auth_OpenID_DiffieHellmanServerSession { var $session_type = 'DH-SHA1'; var $needs_math = true; + var $allowed_assoc_types = array('HMAC-SHA1'); + var $hash_func = 'Auth_OpenID_SHA1'; - function Auth_OpenID_DiffieHellmanServerSession($dh, $consumer_pubkey) + function Auth_OpenID_DiffieHellmanSHA1ServerSession($dh, $consumer_pubkey) { $this->dh = $dh; $this->consumer_pubkey = $consumer_pubkey; @@ -441,14 +444,15 @@ class Auth_OpenID_DiffieHellmanServerSession { "dh_consumer_public is not base64"); } - return new Auth_OpenID_DiffieHellmanServerSession($dh, - $consumer_pubkey); + return new Auth_OpenID_DiffieHellmanSHA1ServerSession($dh, + $consumer_pubkey); } function answer($secret) { $lib =& Auth_OpenID_getMathLib(); - $mac_key = $this->dh->xorSecret($this->consumer_pubkey, $secret); + $mac_key = $this->dh->xorSecret($this->consumer_pubkey, $secret, + $this->hash_func); return array( 'dh_server_public' => $lib->longToBase64($this->dh->public), @@ -475,7 +479,7 @@ class Auth_OpenID_AssociateRequest extends Auth_OpenID_Request { function fromMessage($message) { $session_classes = array( - 'DH-SHA1' => 'Auth_OpenID_DiffieHellmanServerSession', + 'DH-SHA1' => 'Auth_OpenID_DiffieHellmanSHA1ServerSession', null => 'Auth_OpenID_PlainTextServerSession'); $session_type = $message->getArg(Auth_OpenID_OPENID_NS, diff --git a/Tests/Auth/OpenID/Consumer.php b/Tests/Auth/OpenID/Consumer.php index 650e6df..e6918b1 100644 --- a/Tests/Auth/OpenID/Consumer.php +++ b/Tests/Auth/OpenID/Consumer.php @@ -68,18 +68,20 @@ function Auth_OpenID_associate($qs, $assoc_secret, $assoc_handle) if (defined('Auth_OpenID_NO_MATH_SUPPORT')) { assert(count($query_data) == 2); - $reply_dict['mac_key'] = $assoc_secret; + $session = Auth_OpenID_PlainTextServerSession::fromQuery($query_data); } else { assert((count($query_data) == 6) || (count($query_data) == 4)); assert($query_data['openid.mode'] == 'associate'); assert($query_data['openid.session_type'] == 'DH-SHA1'); - $dh_args = Auth_OpenID_DiffieHellman:: - serverAssociate($query_data, $assoc_secret); - - $reply_dict = array_merge($reply_dict, $dh_args); + + $message = Auth_OpenID_Message::fromPostArgs($query_data); + + $session = Auth_OpenID_DiffieHellmanSHA1ServerSession::fromMessage($message); + $reply_dict['session_type'] = 'DH-SHA1'; } + $reply_dict = array_merge($reply_dict, $session->answer($assoc_secret)); return Auth_OpenID_KVForm::fromArray($reply_dict); } @@ -142,9 +144,9 @@ class Auth_OpenID_TestFetcher extends Services_Yadis_HTTPFetcher { return $this->response($url, $response); } elseif (strpos($body, 'openid.mode=check_authentication') !== false) { return $this->_checkAuth($url, $body); - } else { - return $this->response($url, null); } + + return $this->response($url, null); } } @@ -848,7 +850,7 @@ class Tests_Auth_OpenID_Consumer_TestFetchAssoc extends PHPUnit_TestCase { $endpoint->server_url = 'some://url'; // exception fetching returns no association - $this->assertEquals(@$this->consumer->_getAssociation($endpoint), + $this->assertEquals($this->consumer->_getAssociation($endpoint), null); $query = array('openid.signed' => ''); @@ -967,168 +969,6 @@ class Tests_Auth_OpenID_SuccessResponse extends PHPUnit_TestCase { } } -class Tests_Auth_OpenID_ParseAssociation extends _TestIdRes { - var $secret = ''; - - function setUp() - { - parent::setUp(); - $this->secret = str_repeat('x', 20); - } - - function test_missing() - { - // Missing required arguments - $message = Auth_OpenID_Message::fromPostArgs(array()); - $result = $this->consumer->_parseAssociation($message, null, 'server_url'); - $this->assertTrue($result === null); - } - - function _setUpDH() - { - list($sess, $message) = $this->consumer->_createAssociateRequest($this->server_url); - $server_sess = Auth_OpenID_DiffieHellmanServerSession::fromMessage($message); - $server_resp = $server_sess->answer($this->secret); - $server_resp['assoc_type'] = 'HMAC-SHA1'; - $server_resp['assoc_handle'] = 'handle'; - $server_resp['expires_in'] = '1000'; - $server_resp['session_type'] = 'DH-SHA1'; - return array($sess, $server_resp); - } - - function test_plainSuccess() - { - $sess = new Auth_OpenID_PlainTextConsumerSession(); - $server_resp = array('mac_key' => 'AAAAAAAAAAAAAAAAAAAAAAAAAAA=', - 'assoc_type' => 'HMAC-SHA1', - 'assoc_handle' => 'ahandle', - 'expires_in' => '1000' - ); - $message = Auth_OpenID_Message::fromOpenIDArgs($server_resp); - $ret = $this->consumer->_parseAssociation($message, $sess, - 'server_url'); - $this->assertEquals($ret->secret, - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" . - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"); - } - - function test_DHSuccess() - { - if (defined('Auth_OpenID_NO_MATH_SUPPORT')) { - print "No math support: not running test_DHSuccess\n"; - return; - } - list($sess, $server_resp) = $this->_setUpDH(); - $message = Auth_OpenID_Message::fromOpenIDArgs($server_resp); - $ret = $this->consumer->_parseAssociation($message, $sess, - 'server_url'); - $this->assertTrue($ret !== null); - $this->assertEquals($ret->assoc_type, 'HMAC-SHA1'); - $this->assertEquals($ret->secret, $this->secret); - $this->assertEquals($ret->handle, 'handle'); - $this->assertEquals($ret->lifetime, 1000); - } - - function test_badAssocType() - { - $sess = new Auth_OpenID_PlainTextConsumerSession(); - $server_resp = array('mac_key' => 'XXXXXXXXXXXXXXXXXXXX', - 'assoc_handle' => 'ahandle', - 'assoc_type' => 'Crazy Low Prices!!!', - 'expires_in' => '1000' - ); - $message = Auth_OpenID_Message::fromOpenIDArgs($server_resp); - - $ret = $this->consumer->_parseAssociation($message, $sess, - 'server_url'); - $this->assertTrue($ret === null); - } - - function test_badExpiresIn() - { - $sess = new Auth_OpenID_PlainTextConsumerSession(); - $server_resp = array('mac_key' => 'XXXXXXXXXXXXXXXXXXXX', - 'assoc_handle' => 'ahandle', - 'assoc_type' => 'HMAC-SHA1', - 'expires_in' => 'Crazy Low Prices!!!' - ); - $message = Auth_OpenID_Message::fromOpenIDArgs($server_resp); - $ret = $this->consumer->_parseAssociation($message, $sess, - 'server_url'); - $this->assertTrue($ret === null); - } - - function test_badSessionType() - { - $sess = new Auth_OpenID_PlainTextConsumerSession(); - $server_resp = array('mac_key' => 'XXXXXXXXXXXXXXXXXXXX', - 'assoc_handle' => 'ahandle', - 'assoc_type' => 'HMAC-SHA1', - 'expires_in' => '1000', - 'session_type' => '|/iA6rA' - ); - $message = Auth_OpenID_Message::fromOpenIDArgs($server_resp); - $ret = $this->consumer->_parseAssociation($message, $sess, - 'server_url'); - $this->assertTrue($ret === null); - } - - function test_plainFallback() - { - if (defined('Auth_OpenID_NO_MATH_SUPPORT')) { - print "No math support: not running test_plainFallback\n"; - return; - } - $sess = new Auth_OpenID_DiffieHellmanConsumerSession(); - $server_resp = array( - 'assoc_type' => 'HMAC-SHA1', - 'assoc_handle' => 'handle', - 'expires_in' => '1000', - 'mac_key' => base64_encode($this->secret)); - - $message = Auth_OpenID_Message::fromOpenIDArgs($server_resp); - $ret = $this->consumer->_parseAssociation($message, $sess, - 'server_url'); - $this->assertTrue($ret !== null); - $this->assertEquals($ret->assoc_type, 'HMAC-SHA1'); - $this->assertEquals($ret->secret, $this->secret); - $this->assertEquals($ret->handle, 'handle'); - $this->assertEquals($ret->lifetime, 1000); - } - - function test_plainFallbackFailure() - { - if (defined('Auth_OpenID_NO_MATH_SUPPORT')) { - print "No math support: not running test_plainFallbackFailure\n"; - return; - } - $sess = new Auth_OpenID_DiffieHellmanConsumerSession(); - // missing mac_key - $server_resp = array( - 'assoc_type' => 'HMAC-SHA1', - 'assoc_handle' => 'handle', - 'expires_in' => '1000'); - - $message = Auth_OpenID_Message::fromOpenIDArgs($server_resp); - $ret = $this->consumer->_parseAssociation($message, $sess, - 'server_url'); - $this->assertTrue($ret === null); - } - - function test_badDHValues() - { - if (defined('Auth_OpenID_NO_MATH_SUPPORT')) { - return; - } - list($sess, $server_resp) = $this->_setUpDH(); - $server_resp['enc_mac_key'] = "\x00\x00\x00"; - $message = Auth_OpenID_Message::fromOpenIDArgs($server_resp); - $ret = $this->consumer->_parseAssociation($message, $sess, - 'server_url'); - $this->assertTrue($ret === null); - } -} - class _StubConsumer { function _StubConsumer() { @@ -1338,7 +1178,6 @@ $Tests_Auth_OpenID_Consumer_other = array( new Tests_Auth_OpenID_SuccessResponse(), new Tests_Auth_OpenID_CheckAuthResponse(), new Tests_Auth_OpenID_FetchErrorInIdRes(), - new Tests_Auth_OpenID_ParseAssociation(), new Tests_Auth_OpenID_ConsumerTest2(), new Tests_Auth_OpenID_AuthRequest() ); diff --git a/Tests/Auth/OpenID/Server.php b/Tests/Auth/OpenID/Server.php index aa6464e..30325b4 100644 --- a/Tests/Auth/OpenID/Server.php +++ b/Tests/Auth/OpenID/Server.php @@ -935,7 +935,7 @@ class Tests_Auth_OpenID_Associate extends PHPUnit_TestCase { $ml =& Auth_OpenID_getMathLib(); $cpub = $dh->public; - $session = new Auth_OpenID_DiffieHellmanServerSession( + $session = new Auth_OpenID_DiffieHellmanSHA1ServerSession( new Auth_OpenID_DiffieHellman(), $cpub); @@ -971,7 +971,7 @@ class Tests_Auth_OpenID_Associate extends PHPUnit_TestCase { $response->fields->getArg(Auth_OpenID_OPENID_NS, "dh_server_public")); - $secret = $dh->xorSecret($spub, $enc_key); + $secret = $dh->xorSecret($spub, $enc_key, $session->hash_func); $this->assertEquals($secret, $this->assoc->secret); } |