| [ PHPXref.com ] | [ Generated: Sun Jul 20 20:16:20 2008 ] | [ ShareToDo 1.0.0 ] |
| [ Index ] [ Variables ] [ Functions ] [ Classes ] [ Constants ] [ Statistics ] | ||
[Summary view] [Print] [Text view]
1 <?php 2 // Copyright (c) 2004 Daiji Hriata All Right Reserved. 3 // $Id: Auth_TypeKey.phps,v 1.3 2004/10/10 14:59:49 hirata Exp $ 4 // 5 // Auth_TypeKey Class 6 // 7 // Simple example: 8 // 9 // $tk = new Auth_TypeKey(); 10 // $tk->site_token('PUTYOURTYPEKEYTOKEN'); 11 // $tk->verifyTypeKey( $msg ); 12 // if (PEAR::isError($result)) { 13 // echo "INVALID"; 14 // } else { 15 // echo "VALID"; 16 // } 17 18 require_once 'PEAR.php'; 19 20 /** 21 * Error code 22 */ 23 define('AUTH_TYPEKEY_ERROR_INVALID', -1); 24 define('AUTH_TYPEKEY_ERROR_TIMEOUT', -2); 25 define('AUTH_TYPEKEY_ERROR_NOT_EXIST_BIGINT', -3); 26 define('AUTH_TYPEKEY_ERROR_NOT_RETRIEVE_PUBKEY', -4); 27 define('AUTH_TYPEKEY_ERROR_NOT_SET_SITE_TOKEN', -5); 28 define('AUTH_TYPEKEY_ERROR_NOT_EXIST_GMP', -6); 29 define('AUTH_TYPEKEY_ERROR_NOT_EXIST_BCMATH', -7); 30 31 class Auth_TypeKey extends PEAR 32 { 33 /** 34 * TypeKey Public_Key URLs 35 */ 36 var $AUTH_TYPEKEY_BASEURL = 'https://www.typekey.com/t/typekey/'; 37 var $AUTH_TYPEKEY_SIG_URL = 'http://www.typekey.com/extras/regkeys.txt'; 38 39 /** 40 * TypeKey version 41 */ 42 var $AUTH_TYPEKEY_VERSION = '1'; 43 44 /** 45 * TypeKey requires site_token 46 */ 47 var $AUTH_TYPEKEY_SITE_TOKEN = NULL; 48 49 50 /** 51 * time limitatino of TypeKey validation (sec) 52 */ 53 var $AUTH_TYPEKEY_TIMEOUT = 300; 54 55 /** 56 * function to compute BIGINT 57 */ 58 var $AUTH_TYPEKEY_BIGINT = ''; 59 60 /** 61 * Initialize. 62 * 63 * @param array $init parameters for initialize: 64 * 'version' : TypeKey version 65 * 'token' : TypeKey Site Token 66 * 67 * @return mixed true on success. PEAR_Error on failure. 68 * 69 * @access public 70 */ 71 function Auth_TypeKey ( $init = array() ) 72 { 73 $this->PEAR(); 74 if (!$this->_exist_bigint()) { 75 return PEAR::raiseError("BCMATH or GMP is required", 76 AUTH_TYPEKEY_ERROR_NOT_EXIST_BIGINT); 77 } 78 if (array_key_exists('version', $init)) { 79 $this->version($init['version']); 80 } 81 if (array_key_exists('token', $init)) { 82 $this->site_token($init['token']); 83 } 84 return true; 85 } 86 87 /** 88 * Set/show TypeKey version 89 * 90 * @param string $version TypeKey version to set. 91 * If nothing, just look. 92 * 93 * @return string Current setting of TypeKey version 94 * 95 * @access public 96 */ 97 function version($version = NULL) 98 { 99 if (!is_null($version)) { 100 $this->AUTH_TYPEKEY_VERSION = $version; 101 } 102 return $this->AUTH_TYPEKEY_VERSION; 103 } 104 105 106 /** 107 * Set/show TypeKey Site Token 108 * 109 * @param string $version TypeKey Site Token to set. 110 * if nothing, just look. 111 * 112 * @return mixed string Current setting of TypeKey Site Token 113 * if set. PEAR_Error if not set. 114 * 115 * @access public 116 */ 117 function site_token($token = NULL) 118 { 119 if (!is_null($token)) { 120 $this->AUTH_TYPEKEY_SITE_TOKEN = $token; 121 } 122 if (is_null($this->AUTH_TYPEKEY_SITE_TOKEN)) { 123 return PEAR::raiseError('SITE TOKEN is not set.', 124 AUTH_TYPEKEY_ERROR_NOT_SET_SITE_TOKEN); 125 } 126 return $this->AUTH_TYPEKEY_SITE_TOKEN; 127 } 128 129 /** 130 * Verify the TypeKey authentication requirement 131 * 132 * @param array $query TypeKey Site Token to set. if nothing, just look. 133 * @param array $key Public Keys of TypeKey service. if NULL, using preset URLs. 134 * 135 * @return mixed true on success. PEAR_Error on failure. 136 * 137 * @access public 138 */ 139 function verifyTypeKey ( $query, $key = NULL ) 140 { 141 // Retrieve key per each request. 142 if (is_null($key)) { 143 $key = $this->_fetch_key(''); 144 if ($key == false) { 145 return PEAR::raiseError('Cannot get pubkey.', 146 AUTH_TYPEKEY_ERROR_NOT_RETRIEVE_PUBKEY); 147 } 148 } 149 150 foreach ( array( 'email', 'name', 'nick', 'ts', 'sig') as $i ) { 151 $$i = $query[$i]; 152 } 153 154 // The nickname field is sent as url_encoded utf-8 data(like %xx%xx... ) 155 // from Tyepkey but signed before encoded. Usually all fields are 156 // decoded by PHP automatically, but it might cause invalid_error, 157 // especially using with mb_stirng. rawurlencoded strings is 158 // better for that case. It can be gotten from QUERY_STRING 159 $nick = rawurldecode($nick); 160 161 switch ($this->version()) { 162 case '1': 163 $message = implode('::', array( $email, $name, $nick, $ts)); 164 break; 165 case '1.1': 166 $token = $this->site_token(); 167 if (PEAR::isError($token)) { 168 return $token; 169 } 170 $message = implode('::', array( $email, $name, $nick, $ts, $token)); 171 break; 172 default: 173 // default is version '1' 174 $message = implode('::', array( $email, $name, $nick, $ts)); 175 break; 176 } 177 178 if( $this->_dsa_verify($message, $sig, $key) == true) { 179 if ( time() - $ts > $this->AUTH_TYPEKEY_TIMEOUT ) { 180 return PEAR::raiseError("Timestamp from TypeKey is too old", 181 AUTH_TYPEKEY_ERROR_TIMEOUT); 182 } 183 return true; 184 } else { 185 return PEAR::raiseError("Invalid signature", 186 AUTH_TYPEKEY_ERROR_INVALID); 187 } 188 } 189 190 /* Generate URL to link to Sign-In using TypeKey service 191 * 192 * @param string $return_url URL to be returned after authentication 193 * @param boolean $need_email if true, require email address of user. 194 * 195 * @return mixed string $url URL to link TypeKey Sign-In 196 * PEAR_Error on failure 197 * 198 * @access public 199 */ 200 201 function urlSignIn ($return_url, $need_email = false, $options = array ()) 202 { 203 $token = $this->site_token(); 204 if (PEAR::isError($token)) { 205 return $token; 206 } 207 208 $option_query = ''; 209 foreach ($options as $key => $value) { 210 $option_query .= '&' . $key . '=' . $value; 211 } 212 213 $url = $this->AUTH_TYPEKEY_BASEURL; 214 $url .= "login?t=" . $token; 215 $url .= (($need_email == 1) ? "&need_email=1" : ''); 216 $url .= (($this->version()) ? "&v=" . $this->version() : ''); 217 $url .= $option_query; 218 $url .= "&_return=" . rawurlencode($return_url); 219 return $url; 220 } 221 222 /* Generate URL to link to sign out 223 * 224 * @param string $return_url URL to be returned after authentication 225 * 226 * @return string $url URL to link TypeKey sign out. 227 * 228 * @access public 229 */ 230 function urlSignOut ( $return_url ) { 231 $url = $this->AUTH_TYPEKEY_BASEURL; 232 $url .= "logout?"; 233 $url .= "_return=" . rawurlencode($return_url); 234 return $url; 235 } 236 237 /* 238 * Fetch keys of TypeKey service 239 * 240 * @param string $url URL of TypeKey Public Keys 241 * 242 * @return mixed array of Public keys of TypeKey services 243 * false on error 244 * 245 * @access private 246 */ 247 function _fetch_key ( $url = '') 248 { 249 if ($url == '') { 250 $url = $this->AUTH_TYPEKEY_SIG_URL; 251 } 252 $lines = @file($url); 253 if ($lines == false) { 254 return false; 255 } 256 $key_raw = explode(" ", $lines[0]); 257 258 foreach ($key_raw as $e) { 259 list($key_index, $key_value) = explode("=", $e); 260 $key[$key_index] = trim($key_value); 261 } 262 return $key; 263 } 264 265 /* 266 * check existing bigint function 267 * 268 * @return boolean true if available bigint funciton gmp or bcmath 269 * false if not available. 270 * 271 * @access private 272 * 273 */ 274 function _exist_bigint () 275 { 276 $extension_bigint = array( 'bcmath', 'gmp' ); 277 $exist_bigint = false; 278 foreach ($extension_bigint as $ext) { 279 if (extension_loaded($ext)) { 280 $exist_bigint = true; 281 $this->AUTH_TYPEKEY_BIGINT = $ext; 282 } 283 } 284 return $exist_bigint; 285 } 286 287 /* 288 * dsa verification 289 * 290 * @param string $message Message to verify 291 * @param string @sig Sign for the message, two keys are 292 * included separeted by ':' (colon) 293 * @param array $key ublic keys for the signiture 294 * 295 * @access private 296 * 297 */ 298 function _dsa_verify ( $message, $sig, $key ) 299 { 300 $func = $this->AUTH_TYPEKEY_BIGINT; 301 $func = '_dsa_verify_' . $func; 302 return $this->$func( $message, $sig, $key ); 303 } 304 305 /* 306 * dsa verification using gmp 307 * 308 * @param string $message Message to verify 309 * @param string @sig Sign for the message, two keys are 310 * included separeted by ':' (colon) 311 * @param array $key ublic keys for the signiture 312 * 313 * @access private 314 * 315 */ 316 function _dsa_verify_gmp ( $message, $sig, $key ) 317 { 318 list( $r_sig, $s_sig ) = explode(":", $sig ); 319 $r_sig = base64_decode($r_sig); 320 $s_sig = base64_decode($s_sig); 321 322 foreach ($key as $i => $v) { 323 $key[$i] = gmp_init($v); 324 } 325 $s1 = gmp_init($this->_gmp_bindec($r_sig)); 326 $s2 = gmp_init($this->_gmp_bindec($s_sig)); 327 328 $w = gmp_invert($s2,$key['q']); 329 $hash_m = gmp_init('0x' . sha1($message)); 330 331 $u1 = gmp_mod(gmp_mul($hash_m,$w),$key['q']); 332 $u2 = gmp_mod(gmp_mul($s1,$w),$key['q']); 333 334 $v = gmp_mod( 335 gmp_mod( 336 gmp_mul( 337 gmp_powm($key['g'],$u1,$key['p']), 338 gmp_powm($key['pub_key'],$u2,$key['p'])), 339 $key['p']), 340 $key['q']); 341 if (gmp_cmp($v, $s1) == 0) { 342 return true; 343 } else { 344 return false; 345 } 346 } 347 348 /* 349 * gmp_bindec 350 * 351 * @param string $bin binary data 352 * 353 * @return gmp value of $bin 354 * 355 * @access private 356 */ 357 function _gmp_bindec ($bin) 358 { 359 $dec = gmp_init(0); 360 while (strlen($bin)) { 361 $i = ord(substr($bin, 0, 1)); 362 $dec = gmp_add(gmp_mul($dec,256),$i); 363 $bin = substr($bin, 1); 364 } 365 return gmp_strval($dec); 366 } 367 368 /* 369 * dsa verification using bcmath 370 * 371 * @param string $message Message to verify 372 * @param string @sig Sign for the message, two keys are 373 * included separeted by ':' (colon) 374 * @param array $key ublic keys for the signiture 375 * 376 * @access private 377 * 378 */ 379 function _dsa_verify_bcmath ( $message, $sig, $key ) 380 { 381 list( $r_sig, $s_sig ) = explode(":", $sig ); 382 383 $r_sig = base64_decode($r_sig); 384 $s_sig = base64_decode($s_sig); 385 386 $s1 = $this->_bc_bindec($r_sig); 387 $s2 = $this->_bc_bindec($s_sig); 388 389 $w = $this->_bc_invert($s2,$key['q']); 390 $hash_m = $this->_bc_hexdec(sha1($message)); 391 392 $u1 = bcmod(bcmul($hash_m,$w),$key['q']); 393 $u2 = bcmod(bcmul($s1,$w),$key['q']); 394 395 $v = bcmod( 396 bcmod( 397 bcmul( 398 bcmod($this->_bc_powmod($key['g'],$u1,$key['p']), $key['p']), 399 bcmod($this->_bc_powmod($key['pub_key'],$u2,$key['p']),$key['p'])), 400 $key['p']), 401 $key['q']); 402 403 if (bccomp($v, $s1) == 0) { 404 return true; 405 } else { 406 return false; 407 } 408 } 409 410 /* 411 * _bc_hexdec 412 * 413 * @param string $hex 414 * 415 * @return string dec converted from $hex 416 * 417 * @access private 418 */ 419 function _bc_hexdec ($hex) 420 { 421 $dec = "0"; 422 while (strlen($hex)) { 423 $i = HexDec(substr($hex, 0, 4)); 424 $dec = bcadd(bcmul($dec,65536),$i); 425 $hex = substr($hex, 4); 426 } 427 return $dec; 428 } 429 430 /* 431 * _bc_bindec 432 * 433 * @param string $bin 434 * 435 * @return string dec converted from $bin 436 * 437 * @access private 438 */ 439 function _bc_bindec ($bin) 440 { 441 $dec = "0"; 442 while (strlen($bin)) { 443 $i = ord(substr($bin, 0, 1)); 444 $dec = bcadd(bcmul($dec,256),$i); 445 $bin = substr($bin, 1); 446 } 447 return $dec; 448 } 449 450 /* 451 * _bc_invert 452 * 453 * @param string $x, $y 454 * 455 * @return string inverse $x and $y 456 * 457 * @access private 458 */ 459 function _bc_invert ($x, $y) 460 { 461 while (bccomp($x,0)<0) { 462 $x = bcadd($x,$y); 463 } 464 $r = $this->_bc_exgcd($x, $y); 465 if ($r[2] == 1) { 466 $a = $r[0]; 467 while (bccomp($a,0)<0) { 468 $a = bcadd($a,$y); 469 } 470 return $a; 471 } else { 472 return false; 473 } 474 } 475 476 /* 477 * _bc_exgcd 478 * 479 * @param string $x, $y 480 * 481 * @return string extended gcd of $x and $y 482 * 483 * @access private 484 */ 485 function _bc_exgcd ($x, $y) 486 { 487 $a0 = 1; $a1 = 0; 488 $b0 = 0; $b1 = 1; 489 $c = 0; 490 while($y > 0) { 491 $q = bcdiv($x, $y, 0); 492 $r = bcmod($x, $y); 493 $x = $y; $y = $r; 494 $a2 = bcsub($a0, bcmul($q,$a1)); 495 $b2 = bcsub($b0, bcmul($q,$b1)); 496 $a0 = $a1; $a1 = $a2; 497 $b0 = $b1; $b1 = $b2; 498 } 499 return (array($a0, $b0, $x)); 500 } 501 502 /* 503 * _bc_powmod 504 * 505 * @param string $x, $y, $mod 506 * 507 * @return string bcmod(bcpow($x, $y), $mod) 508 * 509 * @access private 510 */ 511 function _bc_powmod ($x, $y, $mod) 512 { 513 if (function_exists('bcpowmod')) { 514 return bcpowmod($x, $y, $mod); 515 } else { 516 if (bccomp($y,1) == 0) { 517 return bcmod($x, $mod); 518 } else if (bcmod($y,2) == 0) { 519 return bcmod(bcpow($this->_bc_powmod($x, bcdiv($y,2), $mod), 2), $mod); 520 } else { 521 return bcmod(bcmul($x, $this->_bc_powmod($x, bcsub($y,1), $mod)), $mod); 522 } 523 } 524 } 525 } 526 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| [ Powered by PHPXref - Served by Debian GNU/Linux ] |