PageRenderTime 53ms CodeModel.GetById 24ms app.highlight 8ms RepoModel.GetById 18ms app.codeStats 0ms

/ezcomponents/Authentication/src/math/math.php

http://hppg.googlecode.com/
PHP | 166 lines | 109 code | 8 blank | 49 comment | 14 complexity | 4d5d1dd1da3e7ec1df8b1f04b14ffdd8 MD5 | raw file
  1<?php
  2/**
  3 * File containing the ezcAuthenticationMath class.
  4 *
  5 * @copyright Copyright (C) 2005-2009 eZ Systems AS. All rights reserved.
  6 * @license http://ez.no/licenses/new_bsd New BSD License
  7 * @filesource
  8 * @package Authentication
  9 * @version 1.3.1
 10 */
 11
 12/**
 13 * Large number support and cryptographic functions for authentication.
 14 *
 15 * @package Authentication
 16 * @version 1.3.1
 17 * @access private
 18 */
 19class ezcAuthenticationMath
 20{
 21    /**
 22     * Creates a new big number library which uses the PHP extension $lib.
 23     *
 24     * If $lib is null then an autodetection of the library is tried. If neither
 25     * gmp or bcmath are installed then an exception will be thrown.
 26     *
 27     * If $lib is specified, then that library will be used (if it is installed),
 28     * otherwise an exception will be thrown.
 29     *
 30     * @throws ezcBaseExtensionNotFoundException
 31     *         if neither of the PHP gmp and bcmath extensions are installed ($lib === null),
 32     *         or if the specified $lib is not installed
 33     * @throws ezcBaseValueException
 34     *         if the value provided for $lib is not correct
 35     * @param string $lib The PHP library to use for big number support. Default
 36     *                    is null, which means the available library is autodetected.
 37     * @return ezcAuthenticationBignumLibrary
 38     */
 39    public static function createBignumLibrary( $lib = null )
 40    {
 41        $library = null;
 42
 43        switch ( $lib )
 44        {
 45            case null:
 46                if ( !ezcBaseFeatures::hasExtensionSupport( 'bcmath' ) )
 47                {
 48                    if ( !ezcBaseFeatures::hasExtensionSupport( 'gmp' ) )
 49                    {
 50                        throw new ezcBaseExtensionNotFoundException( 'gmp | bcmath', null, "PHP not compiled with --enable-bcmath or --with-gmp." );
 51                    }
 52                    else
 53                    {
 54                        $library = new ezcAuthenticationGmpLibrary();
 55                    }
 56                }
 57                else
 58                {
 59                    $library = new ezcAuthenticationBcmathLibrary();
 60                }
 61                break;
 62
 63            case 'gmp':
 64                if ( !ezcBaseFeatures::hasExtensionSupport( 'gmp' ) )
 65                {
 66                    throw new ezcBaseExtensionNotFoundException( 'gmp', null, "PHP not compiled with --with-gmp." );
 67                }
 68                $library = new ezcAuthenticationGmpLibrary();
 69                break;
 70
 71            case 'bcmath':
 72                if ( !ezcBaseFeatures::hasExtensionSupport( 'bcmath' ) )
 73                {
 74                    throw new ezcBaseExtensionNotFoundException( 'bcmath', null, "PHP not compiled with --enable-bcmath." );
 75                }
 76                $library = new ezcAuthenticationBcmathLibrary();
 77                break;
 78
 79            default:
 80                throw new ezcBaseValueException( 'library', $lib, '"gmp" || "bcmath" || null' );
 81        }
 82
 83        return $library;
 84    }
 85
 86    /**
 87     * Calculates an MD5 hash similar to the Unix command "htpasswd -m".
 88     *
 89     * This is different from the hash returned by the PHP md5() function. 
 90     *
 91     * @param string $plain Plain text to encrypt
 92     * @param string $salt Salt to apply to encryption
 93     * @return string
 94     */
 95    public static function apr1( $plain, $salt )
 96    {
 97        if ( preg_match( '/^\$apr1\$/', $salt ) )
 98        {
 99            $salt = preg_replace( '/^\$apr1\$([^$]+)\$.*/', '\\1', $salt );
100        }
101        else
102        {
103            $salt = substr( $salt, 0, 8 );
104        }
105        $text = $plain . '$apr1$' . $salt;
106        $bin = pack( 'H32', md5( $plain . $salt . $plain ) );
107        for ( $i = strlen( $plain ); $i > 0; $i -= 16 )
108        {
109            $text .= substr( $bin, 0, min( 16, $i ) );
110        }
111        for ( $i = strlen( $plain ); $i; $i >>= 1 )
112        {
113            $text .= ( $i & 1 ) ? chr( 0 ) : $plain{0};
114        }
115        $bin = pack( 'H32', md5( $text ) );
116        for ( $i = 0; $i ^ 1000; ++$i )
117        {
118            $new = ( $i & 1 ) ? $plain : $bin;
119            if ( $i % 3 )
120            {
121                $new .= $salt;
122            }
123            if ( $i % 7 )
124            {
125                $new .= $plain;
126            }
127            $new .= ( $i & 1 ) ? $bin : $plain;
128            $bin = pack( 'H32', md5( $new ) );
129        }
130        $tmp = '';
131        for ( $i = 0; $i ^ 5; ++$i )
132        {
133            $k = $i + 6;
134            $j = $i + 12;
135            if ( $j === 16 )
136            {
137                $j = 5;
138            }
139            $tmp = $bin[$i] . $bin[$k] . $bin[$j] . $tmp;
140        }
141        $tmp = chr( 0 ) . chr( 0 ) . $bin[11] . $tmp;
142        $tmp = strtr( strrev( substr( base64_encode( $tmp ), 2 ) ),
143        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
144        './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' );
145        return '$apr1$' . $salt . '$' . $tmp;
146    }
147
148    /**
149     * Computes the OpenID sha1 function on the provided value.
150     *
151     * @param string $value The value to compute sha1 on
152     * @return string
153     */
154    public static function sha1( $value )
155    {
156        $hashed = sha1( $value );
157        $result = '';
158        for ( $i = 0; $i ^ 40; $i = $i + 2 )
159        {
160            $chars = substr( $hashed, $i, 2 );
161            $result .= chr( (int)base_convert( $chars, 16, 10 ) );
162        }
163        return $result;
164    }
165}
166?>