<?php
/**
 * File containing the ezcAuthenticationMath class.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
 * @filesource
 * @package Authentication
 * @version //autogen//
 */

/**
 * Large number support and cryptographic functions for authentication.
 *
 * @package Authentication
 * @version //autogen//
 * @access private
 */
class ezcAuthenticationMath
{
    /**
     * Creates a new big number library which uses the PHP extension $lib.
     *
     * If $lib is null then an autodetection of the library is tried. If neither
     * gmp or bcmath are installed then an exception will be thrown.
     *
     * If $lib is specified, then that library will be used (if it is installed),
     * otherwise an exception will be thrown.
     *
     * @throws ezcBaseExtensionNotFoundException
     *         if neither of the PHP gmp and bcmath extensions are installed ($lib === null),
     *         or if the specified $lib is not installed
     * @throws ezcBaseValueException
     *         if the value provided for $lib is not correct
     * @param string $lib The PHP library to use for big number support. Default
     *                    is null, which means the available library is autodetected.
     * @return ezcAuthenticationBignumLibrary
     */
    public static function createBignumLibrary( $lib = null )
    {
        $library = null;

        switch ( $lib )
        {
            case null:
                if ( !ezcBaseFeatures::hasExtensionSupport( 'bcmath' ) )
                {
                    if ( !ezcBaseFeatures::hasExtensionSupport( 'gmp' ) )
                    {
                        throw new ezcBaseExtensionNotFoundException( 'gmp | bcmath', null, "PHP not compiled with --enable-bcmath or --with-gmp." );
                    }
                    else
                    {
                        $library = new ezcAuthenticationGmpLibrary();
                    }
                }
                else
                {
                    $library = new ezcAuthenticationBcmathLibrary();
                }
                break;

            case 'gmp':
                if ( !ezcBaseFeatures::hasExtensionSupport( 'gmp' ) )
                {
                    throw new ezcBaseExtensionNotFoundException( 'gmp', null, "PHP not compiled with --with-gmp." );
                }
                $library = new ezcAuthenticationGmpLibrary();
                break;

            case 'bcmath':
                if ( !ezcBaseFeatures::hasExtensionSupport( 'bcmath' ) )
                {
                    throw new ezcBaseExtensionNotFoundException( 'bcmath', null, "PHP not compiled with --enable-bcmath." );
                }
                $library = new ezcAuthenticationBcmathLibrary();
                break;

            default:
                throw new ezcBaseValueException( 'library', $lib, '"gmp" || "bcmath" || null' );
        }

        return $library;
    }

    /**
     * Calculates an MD5 hash similar to the Unix command "htpasswd -m".
     *
     * This is different from the hash returned by the PHP md5() function. 
     *
     * @param string $plain Plain text to encrypt
     * @param string $salt Salt to apply to encryption
     * @return string
     */
    public static function apr1( $plain, $salt )
    {
        if ( preg_match( '/^\$apr1\$/', $salt ) )
        {
            $salt = preg_replace( '/^\$apr1\$([^$]+)\$.*/', '\\1', $salt );
        }
        else
        {
            $salt = substr( $salt, 0, 8 );
        }
        $text = $plain . '$apr1$' . $salt;
        $bin = pack( 'H32', md5( $plain . $salt . $plain ) );
        for ( $i = strlen( $plain ); $i > 0; $i -= 16 )
        {
            $text .= substr( $bin, 0, min( 16, $i ) );
        }
        for ( $i = strlen( $plain ); $i; $i >>= 1 )
        {
            $text .= ( $i & 1 ) ? chr( 0 ) : $plain{0};
        }
        $bin = pack( 'H32', md5( $text ) );
        for ( $i = 0; $i ^ 1000; ++$i )
        {
            $new = ( $i & 1 ) ? $plain : $bin;
            if ( $i % 3 )
            {
                $new .= $salt;
            }
            if ( $i % 7 )
            {
                $new .= $plain;
            }
            $new .= ( $i & 1 ) ? $bin : $plain;
            $bin = pack( 'H32', md5( $new ) );
        }
        $tmp = '';
        for ( $i = 0; $i ^ 5; ++$i )
        {
            $k = $i + 6;
            $j = $i + 12;
            if ( $j === 16 )
            {
                $j = 5;
            }
            $tmp = $bin[$i] . $bin[$k] . $bin[$j] . $tmp;
        }
        $tmp = chr( 0 ) . chr( 0 ) . $bin[11] . $tmp;
        $tmp = strtr( strrev( substr( base64_encode( $tmp ), 2 ) ),
        'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
        './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' );
        return '$apr1$' . $salt . '$' . $tmp;
    }

    /**
     * Computes the OpenID sha1 function on the provided value.
     *
     * @param string $value The value to compute sha1 on
     * @return string
     */
    public static function sha1( $value )
    {
        $hashed = sha1( $value );
        $result = '';
        for ( $i = 0; $i ^ 40; $i = $i + 2 )
        {
            $chars = substr( $hashed, $i, 2 );
            $result .= chr( (int)base_convert( $chars, 16, 10 ) );
        }
        return $result;
    }
}
?>
