mirror of
https://github.com/nicolabs/ciform.git
synced 2026-04-11 00:14:41 +02:00
# huge php refactoring to OOP (not yet working)
This commit is contained in:
parent
317aee4844
commit
f80a92aa10
|
|
@ -1,159 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* This is the PHP server side library for Ciform
|
||||
* @package ciform
|
||||
*/
|
||||
|
||||
// constants exportable to included scripts
|
||||
define("CIFORM_SESSION","CIFORM");
|
||||
define("CIFORM_PROTOCOL_VERSION",0);
|
||||
define("CIFORM_REQUEST_PREFIX","ciform:");
|
||||
define("CIFORM_SESSION_KEYPAIR","KEYPAIR"); // TODO : move to ciform_rsa.php
|
||||
if ( ! defined("CIFORM_DEBUG") ) define("CIFORM_DEBUG",FALSE);
|
||||
|
||||
require_once("ciform_rsa.php");
|
||||
|
||||
// private constants
|
||||
define("CIFORM_REQUEST_PROTOCOL","protocol");
|
||||
define("CIFORM_KEYTYPE",CIFORM_RSA_KEYTYPE); // choose the desired encryption module here
|
||||
if ( ! defined("CIFORM_AUTODECRYPT") ) define("CIFORM_AUTODECRYPT", TRUE );
|
||||
|
||||
|
||||
|
||||
// TODO : embed the key in the data (e.g. ciform:rsa:keyId:0x12345:0xdd33be2b17813b396d63dd1be9c72e9756bbd8ae5d5555b93a7f4b4fd5a8c80d:salt24325234)
|
||||
// TODO : use the responsibility chain to rewrite this function
|
||||
function ciform_decode( $data, $keyPair, $base=1 )
|
||||
{
|
||||
if ( CIFORM_DEBUG ) echo "ciform_decrypt($data,keyPair,$base)<br>";
|
||||
|
||||
// $newData is going to be decoded by one of the following filters
|
||||
// then, it'll be encoded to the destination base
|
||||
$newData = $data;
|
||||
|
||||
// this flag means this parameter is handled by this library
|
||||
if ( eregi('^'.CIFORM_REQUEST_PREFIX.'(.*)$',$data,$matches) > 0 )
|
||||
{
|
||||
$newData = ciform_decode($matches[1],$keyPair);
|
||||
}
|
||||
|
||||
// this is just salt that adds randomness to the string : it can be removed safely
|
||||
else if ( eregi('^salt[^:]*:(.*)$',$data,$matches) > 0 )
|
||||
{
|
||||
$newData = ciform_decode($matches[1],$keyPair);
|
||||
}
|
||||
|
||||
// this is an hexadecimal string
|
||||
else if ( eregi('^(hex:|0x)(.*)$',$data,$matches) > 0 )
|
||||
{
|
||||
$tmpData = ciform_decode($matches[2],$keyPair);
|
||||
$newData = pack("H*",$tmpData);
|
||||
}
|
||||
|
||||
// this a base64 encoded string
|
||||
else if ( eregi('^(base64|b64):(.*)$',$data,$matches) > 0 )
|
||||
{
|
||||
$tmpData = ciform_decode($matches[2],$keyPair);
|
||||
if ( $base == 64 )
|
||||
{
|
||||
// we're already in the right radix, don't go further
|
||||
// (same can be done with other bases too, but right now we only need this one)
|
||||
return $tmpData;
|
||||
}
|
||||
$newData = base64_decode($tmpData);
|
||||
}
|
||||
|
||||
// this is an encrypted message
|
||||
else if ( eregi('^'.CIFORM_KEYTYPE.':(.*)(:.+)?$',$data,$matches) > 0 )
|
||||
{
|
||||
$tmpData = ciform_decode($matches[1],$keyPair,64);
|
||||
|
||||
// decrypts the data using the configured module
|
||||
$func = "ciform_".CIFORM_KEYTYPE."_decrypt";
|
||||
$newData = ciform_decode( $func($tmpData,$keyPair), $keyPair );
|
||||
}
|
||||
|
||||
// FIXME : do better recursion : each case should return ciform_decode($tmpData) except if no encoding is detected (which then ends the recursion)
|
||||
// FIXME : put each case in a different 'decoder' class
|
||||
|
||||
// encodes the data into the desired base
|
||||
switch( $base )
|
||||
{
|
||||
case 64:
|
||||
return base64_encode($newData);
|
||||
default:
|
||||
return $newData;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ciform_decryptParam( $data, $keyPair )
|
||||
{
|
||||
if ( gettype($data) == "string" && eregi('^'.CIFORM_REQUEST_PREFIX.'(.*)$',$data,$matches) > 0 )
|
||||
{
|
||||
return ciform_decode($matches[1],$keyPair);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ciform_decryptParams( $request, $keyPair )
|
||||
{
|
||||
$decoded = array();
|
||||
|
||||
// accepts encrypted data from the client
|
||||
foreach ( $request as $key => $value )
|
||||
{
|
||||
$newValue = ciform_decryptParam($value,$keyPair);
|
||||
$decoded[$key] = $newValue;
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// returns the protocol of this script
|
||||
if ( isset($_REQUEST[CIFORM_REQUEST_PROTOCOL]) )
|
||||
{
|
||||
$func = "ciform_".CIFORM_KEYTYPE."_getProtocol";
|
||||
$name = $_REQUEST[CIFORM_REQUEST_PROTOCOL];
|
||||
header("Content-type: text/plain");
|
||||
// if a name was given, use it to name the variable :
|
||||
// the result may be used as a full (java)script
|
||||
if ( trim($name) != "" ) {
|
||||
echo "var $name = " . $func() . ";";
|
||||
}
|
||||
// if no name was given, just print the JSON value :
|
||||
// the result may be used as an Ajax response
|
||||
else {
|
||||
echo $func();
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// makes sure the key is accessible
|
||||
// TODO : instanciate the given crypto class,
|
||||
// which stores itself the key and all other specific data
|
||||
// then, move the following code to the correct sub-script
|
||||
if ( !isset($_SESSION[CIFORM_SESSION]) )
|
||||
{
|
||||
$_SESSION[CIFORM_SESSION] = array();
|
||||
}
|
||||
if ( !isset($_SESSION[CIFORM_SESSION][CIFORM_SESSION_KEYPAIR]) )
|
||||
{
|
||||
// the encryption module's name is given by the defined key type
|
||||
$func = "ciform_".CIFORM_KEYTYPE."_getKeyPair";
|
||||
$_SESSION[CIFORM_SESSION][CIFORM_SESSION_KEYPAIR] = $func();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ( CIFORM_AUTODECRYPT )
|
||||
{
|
||||
$_REQUEST = ciform_decryptParams($_REQUEST,$_SESSION[CIFORM_SESSION][CIFORM_SESSION_KEYPAIR]);
|
||||
}
|
||||
?>
|
||||
176
ciform/trunk/src/ciform/ciform.php
Normal file
176
ciform/trunk/src/ciform/ciform.php
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
<?php
|
||||
//
|
||||
// Ciform
|
||||
//
|
||||
// Copyright © 2008 Nicolas BONARDELLE <http://nicobo.net/contact>
|
||||
//
|
||||
|
||||
/**
|
||||
* This is the PHP server side library for Ciform
|
||||
* @package ciform
|
||||
*/
|
||||
|
||||
|
||||
// TODO : load all files in ciform/schemes
|
||||
require_once "ciform/schemes/core.php";
|
||||
require_once "ciform/schemes/rsa.php";
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CONSTANTS DEFINITIONS
|
||||
//
|
||||
|
||||
|
||||
// Comment out the following line to enable debug traces from this script
|
||||
//define("CIFORM_DEBUG",TRUE);
|
||||
|
||||
/** Prefix for the session variables for this library */
|
||||
define("CIFORM_SESSION","CIFORM");
|
||||
|
||||
/**
|
||||
* Version number of the Ciform protocol implemented here
|
||||
* @type string
|
||||
*/
|
||||
define("CIFORM_PROTOCOL_VERSION","0");
|
||||
|
||||
/** If the request contains a parameter with this name, this script will print out the Ciform protocol rather than doing decryption */
|
||||
define("CIFORM_REQUEST_PROTOCOL","protocol");
|
||||
|
||||
if ( ! defined("CIFORM_AUTODECRYPT") )
|
||||
/** Define this constant to TRUE in caller script to enable transparent decryption of the request */
|
||||
define("CIFORM_AUTODECRYPT", TRUE );
|
||||
|
||||
/**
|
||||
* List of the schemes taken in account for auto decryption.<br>
|
||||
*
|
||||
* Comment out the schemes you don't use in the following list.<br>
|
||||
* Add each (custom) scheme you want to the list to handle more schemes.<br>
|
||||
*/
|
||||
define("CIFORM_SCHEMES_DEFAULT",array(
|
||||
new Ciform_schemes_Ciform(),
|
||||
new Ciform_schemes_Base16(),
|
||||
new Ciform_schemes_Base64(),
|
||||
new Ciform_schemes_RSA()
|
||||
);
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CLASS 'ciform_Server'
|
||||
//
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class handles everything about Ciform on the server side.
|
||||
*/
|
||||
class ciform_Server
|
||||
{
|
||||
/**
|
||||
* @var Ciform_CipherChain Holds the decoders to use on the request parameters
|
||||
* @access private
|
||||
*/
|
||||
var $codec;
|
||||
|
||||
|
||||
function ciform_Server( $schemes )
|
||||
{
|
||||
// registers all known schemes into a decoder chain
|
||||
$this->codec = new Ciform_CipherChain($schemes);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Decrypts all recognized parameters from the given request
|
||||
*
|
||||
* @param $request An associative array containing the request parameters (use $_REQUEST)
|
||||
* @return array A copy of the input array, with values for all handled parameters decrypted
|
||||
*/
|
||||
function decodeParams( $request )
|
||||
{
|
||||
$decoded = array();
|
||||
|
||||
// accepts encrypted data from the client
|
||||
foreach ( $request as $key => $value )
|
||||
{
|
||||
$decoded[$key] = $this->codec->decode($value);
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return array the current Ciform protocol
|
||||
*/
|
||||
function getProtocol()
|
||||
{
|
||||
// FIXME : serverURL must be absolute, so scripts can call it from other servers
|
||||
$serverURL = $_SERVER['PHP_SELF'];
|
||||
|
||||
$schemes = array();
|
||||
foreach ( $this->codec->ciphers as $cipher )
|
||||
{
|
||||
$schemes[$cipher->getName()] = $cipher->getParameters();
|
||||
}
|
||||
|
||||
$protocol = array(
|
||||
'VERSION' => CIFORM_PROTOCOL_VERSION,
|
||||
'PACKET_PREFIX' => CIFORM_REQUEST_PREFIX,
|
||||
'serverURL' => str_replace("'","\\'",$serverURL),
|
||||
'schemes' => $schemes
|
||||
);
|
||||
|
||||
if ( CIFORM_DEBUG ) echo "ciform_rsa_getProtocol() = ".print_r($protocol,TRUE)."<br>";
|
||||
|
||||
return $protocol;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CASE 'PROTOCOL' : Called with the CIFORM_REQUEST_PROTOCOL parameter,
|
||||
// this script is used to print the Ciform protocol parameters
|
||||
//
|
||||
if ( isset($_REQUEST[CIFORM_REQUEST_PROTOCOL]) )
|
||||
{
|
||||
header("Content-type: text/plain");
|
||||
|
||||
// instanciates a default Ciform server handler
|
||||
$ciform = new ciform_Server(CIFORM_SCHEMES_DEFAULT);
|
||||
|
||||
// if a name was given, use it to name the variable :
|
||||
// the result may be used as a full (java)script
|
||||
if ( trim($name) != "" ) {
|
||||
echo "var $name = " . json_encode($ciform->getProtocol()) . ";";
|
||||
}
|
||||
// if no name was given, just print the JSON value :
|
||||
// the result may be used as an Ajax response
|
||||
else {
|
||||
echo json_encode($ciform->getProtocol());
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// CASE 'AUTODECRYPT' : If set, this script will try to automatically decrypt all parameters of the current $_REQUEST,
|
||||
// so the decryption phase is transparent to the next server scripts
|
||||
//
|
||||
if ( CIFORM_AUTODECRYPT )
|
||||
{
|
||||
// instanciates a default Ciform server handler
|
||||
$ciform = new ciform_Server(CIFORM_SCHEMES_DEFAULT);
|
||||
|
||||
// and replaces the request with the unencrypted one
|
||||
$_REQUEST = $ciform->decryptParams($_REQUEST);
|
||||
}
|
||||
|
||||
?>
|
||||
411
ciform/trunk/src/ciform/schemes/core.php
Normal file
411
ciform/trunk/src/ciform/schemes/core.php
Normal file
|
|
@ -0,0 +1,411 @@
|
|||
<?php
|
||||
//
|
||||
// Ciform
|
||||
//
|
||||
// Copyright © 2008 Nicolas BONARDELLE <http://nicobo.net/contact>
|
||||
//
|
||||
|
||||
/**
|
||||
* Core decoders/encoders classes for ciform messages.<br>
|
||||
*
|
||||
* <p>NOTE : In order to keep compatibility with PHP 4, only the basic object oriented features of PHP
|
||||
* are used in this script. This may lead programmers familiar with OOP to misunderstand the classes tree sometimes.
|
||||
* In particular, some classes are meant to be interfaces, but since there's only one possible extend per class,
|
||||
* they were made real classes, and then the tree does not conform exactly to what it would be if multiple
|
||||
* inheritance was allowed.</p>
|
||||
*
|
||||
* @package ciform
|
||||
* @subpackage ciphers
|
||||
* @link http://plugnauth.sourceforge.net/ciform
|
||||
* @author Nicolas BONARDELLE <http://nicobo.net/contact>
|
||||
*/
|
||||
|
||||
require_once "crypto/ciphers/core.php";
|
||||
|
||||
// Comment out the following line to enable debug traces from this script
|
||||
//define("CIFORM_DEBUG",TRUE);
|
||||
/** The prefix to any Ciform packet */
|
||||
define("CIFORM_SCHEME_NAME","ciform");
|
||||
/** The regular expression that extracts the body from any Ciform packet */
|
||||
define("CIFORM_SCHEME_EXTRACT_BODY",'^'.CIFORM_SCHEME_NAME.':(.*)$');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class specifies the interface of a scheme handler in the Ciform protocol.<br>
|
||||
* @abstract
|
||||
*/
|
||||
class Ciform_Scheme extends crypto_Cipher
|
||||
{
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
var $name;
|
||||
|
||||
Ciform_Scheme( $name )
|
||||
{
|
||||
if ( defined($name) ) {
|
||||
$this->name = $name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to identify this scheme.
|
||||
*/
|
||||
function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a packet with full scheme from a message.
|
||||
* @param string $packet The message to pack
|
||||
* @abstract
|
||||
*/
|
||||
function pack( $packet ) { throw new Exception("This method is not implemented."); }
|
||||
|
||||
/**
|
||||
* @param string $packet A 'ciphertext', including the full scheme
|
||||
* @return array|FALSE FALSE if this does not matches this scheme.
|
||||
* Otherwise, an array containing unpacked informations,
|
||||
* with at least the body of the given packet indexed on the key <kbd>body</kbd>.
|
||||
* For instance,<kbd>rsa:0x21372A02302FD83242A723</kbd> would return array("body"=><kbd>0x21372A02302FD83242A723</kbd>)
|
||||
* if this class handles <kbd>rsa:</kbd> prefixed packets.
|
||||
* @abstract
|
||||
*/
|
||||
function unpack( $packet ) { throw new Exception("This method is not implemented."); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This pseudo-cipher handles the recursive aspects of Ciform's scheme by holding a list of ciphers to use for enc/decoding.<br>
|
||||
*
|
||||
* <p>As a decoder, it acts like a <b>chain of responsibility</b>, invoking each of its internal decoders
|
||||
* in turn until one of them can decode the message.</p>
|
||||
*
|
||||
* <p>NOTE : The encoder part is not implemented.</p>
|
||||
*/
|
||||
class Ciform_CipherChain extends Ciform_Scheme
|
||||
{
|
||||
/**
|
||||
* @var array<crypto_Cipher>
|
||||
* @access private
|
||||
*/
|
||||
var $ciphers;
|
||||
|
||||
/**
|
||||
* @param array $ciphers The list of the internal {@link crypto_Cipher}s in this chain
|
||||
*/
|
||||
function Ciform_CipherChain( $ciphers, $name="schemes" )
|
||||
{
|
||||
parent::Ciform_Scheme($name);
|
||||
$this->ciphers = $ciphers;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Does one loop in the chain : tries each cipher in turn (lowest index first) on the given ciphertext.<br>
|
||||
*
|
||||
* @return string The first result not FALSE, or FALSE if no cipher matched
|
||||
* @access private
|
||||
*/
|
||||
function chainDecode( $packet )
|
||||
{
|
||||
$message = $ciphertext;
|
||||
|
||||
foreach ( $this->ciphers as $decoder )
|
||||
{
|
||||
// The first decoder accepting the ciphertext is the good one, we don't need to go further.
|
||||
if ( $message = $decoder->decode($message,$this) )
|
||||
{
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
|
||||
// no decoder has accepted the ciphertext
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return string The result of the call to the {@link crypto_Cipher#decode} method
|
||||
* of the first decoder in the chain that accepted the ciphertext,
|
||||
* or the original message if none was found (never returns FALSE)
|
||||
*/
|
||||
function decode( $packet )
|
||||
{
|
||||
// this outer loop tells to continue while the message is still encoded and handled by one of the decoders
|
||||
for ( $message1 = $packet ; $message2 = $this->chainDecode($message1) ; $message1 = $message2 );
|
||||
|
||||
return $message1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class defines a skeleton to write a Ciform enc/decoder.
|
||||
* @abstract
|
||||
*/
|
||||
class Ciform_Codec extends Ciform_Scheme
|
||||
{
|
||||
/**
|
||||
* @var Ciform_Scheme Used as a default cipher chain
|
||||
* @access private
|
||||
* @see #decode
|
||||
*/
|
||||
var $chain;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
* @access private
|
||||
*/
|
||||
var $unpackOnly;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param boolean $unpackOnly If TRUE, this codec will not do the final decoding on the packet,
|
||||
* but will rather return the body as is.
|
||||
*/
|
||||
function Ciform_Codec( $name, $unpackOnly=FALSE )
|
||||
{
|
||||
parent::Ciform_Scheme($name);
|
||||
$this->unpackOnly = $unpackOnly;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return crypto_Cipher|FALSE A cipher able to decode the body of the given packet,
|
||||
* or FALSE if this scheme does not handle this kind of packet.<br>
|
||||
* <br>
|
||||
* Note that the prefered way to check if a codec does handle some packet
|
||||
* is not to call this method, but rather to compare the result of the {@link unpack} method with FALSE.
|
||||
* @access protected
|
||||
* @abstract
|
||||
*/
|
||||
function getDecoder( $packet ) { throw new Exception("This method is not implemented."); }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @todo Describe this method
|
||||
*/
|
||||
function encode( $text ) { throw new Exception("This method is not implemented."); }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Decrypts and unpack in chain a Ciform packet.<br>
|
||||
*
|
||||
* <p>There can be several levels of encoding in one ciphertext.<br>
|
||||
* For instance, a message could first be encoded into hexadecimal form, then through RSA.<br>
|
||||
* The decryption would then take place in two steps : first, decoding the RSA message will give the hexadecimal form;
|
||||
* then, transcoding this message to the original charset (e.g. ASCII) will give back the original text.<br>
|
||||
* An object implementing this class is used for each step in this <b>decoding chain</b>.</p>
|
||||
*
|
||||
* @param string $ciphertext The message to decode
|
||||
* @param Ciform_CipherChain $chain A decoder that may be used to decrypt inner parts of the ciphertext.<br>
|
||||
* It should be a {@link Ciform_CipherChain}, but all that is required is that it respects the {@link Ciform_Scheme} interface.<br>
|
||||
* It may be used to decode some part of the message, e.g. when the decoder allows the body of the message itself to be encoded.<br>
|
||||
* For instance : with <kbd>rsa:hex:0x1232423248</kbd>, a {@link Ciform_ciphers_RSADecoder} will call the chain on <kbd>hex:0x1232423248</kbd>
|
||||
* in order to get the raw value to decrypt with a RSA private key.
|
||||
* @return string|FALSE The decoded message or FALSE if this class cannot decode the given ciphertext.
|
||||
*/
|
||||
function decode( $packet, $chain=FALSE )
|
||||
{
|
||||
if ( CIFORM_DEBUG ) { echo print_r($this,TRUE),"->decode($packet,",print_r($chain,TRUE),")"."\n"; }
|
||||
|
||||
// uses the internal chain (if any) if the chain was not given as an argument
|
||||
$myChain = $chain ? $chain : ($this->chain ? $this->chain : FALSE);
|
||||
|
||||
if ( CIFORM_DEBUG ) { echo "myChain=",print_r($myChain,TRUE)."\n"; }
|
||||
|
||||
// 1. First extract the body from the packet
|
||||
if ( ($unpacked = $this->unpack($packet)) && isset($unpacked['body']) )
|
||||
{
|
||||
if ( CIFORM_DEBUG ) { echo "unpacked=$unpacked"."\n"; }
|
||||
|
||||
$body = $unpacked['body'];
|
||||
|
||||
// 2. and resursively decode the body if it is itself a packet
|
||||
if ( $myChain && $cleartext = $myChain->decode($body) )
|
||||
{
|
||||
if ( CIFORM_DEBUG ) { echo "cleartext=$cleartext"."\n"; }
|
||||
|
||||
$body = $cleartext;
|
||||
}
|
||||
|
||||
// 3. finally decode the body using the decoder of this cipher
|
||||
if ( $this->unpackOnly )
|
||||
{
|
||||
return $body;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 3.a get a decoder on the given packet
|
||||
$decoder = $this->getDecoder($packet);
|
||||
|
||||
if ( CIFORM_DEBUG ) { echo "decoder=".print_r($decoder,TRUE)."\n"; }
|
||||
|
||||
// 3.b then use the decoder to return a decoded text
|
||||
return $decoder->decode($body);
|
||||
}
|
||||
}
|
||||
|
||||
if ( CIFORM_DEBUG ) { echo "unpacked=".print_r($this->unpack($packet),TRUE)."\n"; }
|
||||
|
||||
// if no decoder was found, this object does not handle this scheme
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A simple scheme packer/unpacker based on a regular expression.<br>
|
||||
*
|
||||
* <p>Such a simple scheme unpacker could be used "as is" if the operation only consist to remove a part of the packet (a prefix for instance).<br>
|
||||
* This is sometimes usefull to unmark a packet or remove unused information from a message.</p>
|
||||
*
|
||||
* <p>NOTE : The unpacker part is not implemented.</p>
|
||||
*/
|
||||
class Ciform_SimpleScheme extends Ciform_Codec
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $regex;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param string $regex The regular expression to use to extract the message body from packets.
|
||||
* It will be passed as the first argument to {@link preg_match}.
|
||||
* It must isolate the message into its first capturing group (<kbd>$matches[1]</kbd>).
|
||||
* @param boolean $unpackOnly See Ciform_Codec#Ciform_Codec()
|
||||
*/
|
||||
function Ciform_SimpleScheme( $name, $regex, $unpackOnly=FALSE )
|
||||
{
|
||||
parent::Ciform_Codec($name,$unpackOnly);
|
||||
$this->regex = $regex;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Extracts the body of the message using its registered regular expression
|
||||
*/
|
||||
function unpack( $packet )
|
||||
{
|
||||
if ( CIFORM_DEBUG ) { echo print_r($this,TRUE)."->unpack($packet)"."\n"; }
|
||||
|
||||
if ( preg_match($this->regex,$packet,$matches) )
|
||||
{
|
||||
if ( CIFORM_DEBUG ) { echo "matches=".print_r($matches,TRUE)."\n"; }
|
||||
|
||||
return array( 'body' => $matches[1] );
|
||||
}
|
||||
|
||||
if ( CIFORM_DEBUG ) { echo "preg_match(".$this->regex.",$packet,$matches)=".preg_match($this->regex,$packet,$matches)."\n"; }
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A simple decoder that removes salt from a message.
|
||||
*
|
||||
* <p>Salt is used to add randomness to a message : it can be removed safely.</p>
|
||||
*/
|
||||
class Ciform_schemes_Salt extends Ciform_SimpleScheme
|
||||
{
|
||||
/**
|
||||
* Only this constructor needs to be defined, in order to pass the superclass
|
||||
* the right regex to extract the salt from the message.
|
||||
*/
|
||||
function Ciform_schemes_Salt()
|
||||
{
|
||||
parent::Ciform_SimpleScheme("salt",'/^salt[^:]*:(.*)$/i');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This decoder transforms an hexadecimal string into its binary representation.
|
||||
*/
|
||||
class Ciform_schemes_Base16 extends Ciform_SimpleScheme
|
||||
{
|
||||
/**
|
||||
* @param boolean $unpackOnly If FALSE, the {@link decode()} method will not decode the ciphertext,
|
||||
* but just return the hexadecimal encoded value without the <kbd>hex:</kbd> preamble
|
||||
*/
|
||||
function Ciform_schemes_Base16( $unpackOnly=FALSE )
|
||||
{
|
||||
parent::Ciform_SimpleScheme("base16",'/^(?:hex:|0x)(.*)$/i',$unpackOnly);
|
||||
}
|
||||
|
||||
function getDecoder( $packet )
|
||||
{
|
||||
if ( CIFORM_DEBUG ) { echo print_r($this,TRUE)."->getDecoder($packet)"."\n"; }
|
||||
|
||||
if ( $this->unpack($packet) )
|
||||
{
|
||||
return new crypto_ciphers_Base16();
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Decodes base64 encoded texts
|
||||
*/
|
||||
class Ciform_schemes_Base64 extends Ciform_SimpleScheme
|
||||
{
|
||||
/**
|
||||
* @param boolean $unpackOnly If FALSE, the {@link #decode} method will not decode the ciphertext,
|
||||
* but just return the base64 encoded value without the <kbd>base64:</kbd> preamble
|
||||
*/
|
||||
function Ciform_schemes_Base64( $unpackOnly=FALSE )
|
||||
{
|
||||
parent::Ciform_SimpleScheme("base64",'/^(?:base64|b64):(.*)$/',$unpackOnly);
|
||||
}
|
||||
|
||||
function getDecoder( $packet )
|
||||
{
|
||||
if ( CIFORM_DEBUG ) { echo print_r($this,TRUE)."->getDecoder($packet)"."\n"; }
|
||||
|
||||
if ( $this->unpack($packet) )
|
||||
{
|
||||
return new crypto_ciphers_Base64();
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Simply unpacks a ciform packet
|
||||
*/
|
||||
class Ciform_schemes_Ciform extends Ciform_SimpleScheme
|
||||
{
|
||||
function Ciform_schemes_Ciform()
|
||||
{
|
||||
parent::Ciform_SimpleScheme(CIFORM_SCHEME_NAME,CIFORM_SCHEME_EXTRACT_BODY,TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -1,422 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Core decoders for ciform messages
|
||||
*
|
||||
* @package ciform
|
||||
* @subpackage ciphers
|
||||
*/
|
||||
|
||||
// constants exportable to included scripts
|
||||
define("CIFORM_SESSION","CIFORM");
|
||||
define("CIFORM_PROTOCOL_VERSION",0);
|
||||
/**
|
||||
* This prefix just means that the corresponding message can be handled by this library.
|
||||
* @see {@link Depacketizer}
|
||||
* @static
|
||||
* @final
|
||||
*/
|
||||
define("CIFORM_REQUEST_PREFIX","ciform:");
|
||||
define("CIFORM_PACKET_EXTRACT_MESSAGE",'^'.CIFORM_REQUEST_PREFIX.'(.*)$');
|
||||
define("CIFORM_SESSION_KEYPAIR","KEYPAIR"); // TODO : move to ciform_rsa.php
|
||||
if ( ! defined("CIFORM_DEBUG") ) define("CIFORM_DEBUG",FALSE);
|
||||
|
||||
require_once("ciform_rsa.php");
|
||||
|
||||
// private constants
|
||||
define("CIFORM_REQUEST_PROTOCOL","protocol");
|
||||
define("CIFORM_KEYTYPE",CIFORM_RSA_KEYTYPE); // choose the desired encryption module here
|
||||
if ( ! defined("CIFORM_AUTODECRYPT") ) define("CIFORM_AUTODECRYPT", TRUE );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class defines the interface of a scheme in the Ciform protocol.<br>
|
||||
*/
|
||||
class Scheme
|
||||
{
|
||||
/**
|
||||
* @return the body of the given packet, or FALSE if this does not matches this scheme.
|
||||
* For instance,<code>rsa:0x21372A02302FD83242A723</code> would return <code>0x21372A02302FD83242A723</code>
|
||||
* if this class handles <code>rsa:</code> prefixed packets.
|
||||
*/
|
||||
function getBody( $packet ) { return FALSE; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class defines the interface decoders have to implement in order to decrypt in chain Ciform messages.<br>
|
||||
*
|
||||
* <p>There can be several levels of encoding in one ciphertext.<br>
|
||||
* For instance, a message could first be encoded into hexadecimal form, then through RSA.<br>
|
||||
* The decryption would then take place in two steps : first, decoding the RSA message will give the hexadecimal form;
|
||||
* then, transcoding this message to the original charset (e.g. ASCII) will give back the original text.<br>
|
||||
*
|
||||
* An object implementing this class is used for each step in this <em>decoding chain</em>.</p>
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
class ChainDecoder extends Scheme
|
||||
{
|
||||
// /**
|
||||
// * @param string $ciphertext The message to decode
|
||||
// * @return boolean TRUE if this decoder can handle the given message, FALSE if not.
|
||||
// * @abstract
|
||||
// */
|
||||
// function canDecode( $ciphertext ) { return FALSE };
|
||||
|
||||
/**
|
||||
* {@link ::canDecode()} must be called before to call this method.
|
||||
*
|
||||
* @param string $ciphertext The message to decode
|
||||
* @param ChainDecoder $chain The chain decoder to invoke next.<br>
|
||||
* It must <b>not</b> be used when the decoder cannot handle the ciphertext (in this case, it must return FALSE).<br>
|
||||
* It may be used to decode the rest of the message, when the decoder allows the body of the message to be encoded itself.<br>
|
||||
* For instance : with <code>rsa:hex:0x1232423248</code>, a {@link RSADecoder} will call the chain on <code>hex:0x1232423248</code>
|
||||
* in order to get the raw value to decrypt with a RSA private key.
|
||||
* @return string|FALSE The decoded message or FALSE if an error happened.
|
||||
* @abstract
|
||||
*/
|
||||
function decode( $ciphertext, $chain ) { return FALSE; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This decoder acts like a <em>chain of responsibility</em> : it invokes each of its internal decoders
|
||||
* in turn until one of them can decode the message.<br>
|
||||
*
|
||||
* <p>Its role is not to be a single link in the chain, but to make the chain start.
|
||||
* However, it respects the {@link ChainDecoder} interface.</p>
|
||||
*/
|
||||
class ChainDecoderChain extends ChainDecoder
|
||||
{
|
||||
/** @access private */
|
||||
var $decoders;
|
||||
|
||||
/**
|
||||
* @param array $decoders The list of the internal decoders of this chain
|
||||
*/
|
||||
function ChainDecoderChain( $decoders )
|
||||
{
|
||||
$this->$decoders = $decoders;
|
||||
}
|
||||
|
||||
function canDecode( $ciphertext )
|
||||
{
|
||||
foreach ( $this->$decoders as $decoder )
|
||||
{
|
||||
if ( $decoder->canDecode($ciphertext) ) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE : the $chain parameter is not used here
|
||||
* @return TRUE if at least one decoder in the chain could decode some part of the ciphertext, FALSE else
|
||||
*/
|
||||
function decode( $ciphertext, $chain )
|
||||
{
|
||||
if ( ! $this->canDecode($ciphertext) ) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$message = $ciphertext;
|
||||
|
||||
// this outer loop tells to continue while the message is still encoded and handled by one of the decoders
|
||||
while ( $this->canDecode($message) )
|
||||
{
|
||||
// this inner loop tells to try each decoder in turn
|
||||
foreach ( $this->$decoders as $decoder )
|
||||
{
|
||||
if ( $decoder->canDecode($message) ) {
|
||||
$message = $decoder->decode($message,$this);
|
||||
// The first decoder accepting the ciphertext is the good one, we don't need to go further.
|
||||
// This break is not necessary since there is no real priority order in the chain,
|
||||
// but it helps to show the logic of the loop.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A simple de-packetizer of (for instance) "ciform:" prepended messages.<br>
|
||||
*
|
||||
* <p>Such a simple decoder could exist just to unmark a packet or remove unused information from a message.</p>
|
||||
*/
|
||||
class Depacketizer extends ChainDecoder
|
||||
{
|
||||
/**
|
||||
* @var array Matches of the last message passed to {@link ::canDecode()}
|
||||
* @access private
|
||||
*/
|
||||
var $matches;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $regex;
|
||||
|
||||
/**
|
||||
* @param string $regex The regular expression to use to extract core the message from packets.
|
||||
* It will be passed as the first argument to {@link eregi}.
|
||||
* It must isolate the message into its first capturing group (<code>$matches[1]</code>).
|
||||
* Defaults to {@link CIFORM_PACKET_EXTRACT_MESSAGE}
|
||||
*/
|
||||
function Depacketizer( $regex=CIFORM_PACKET_EXTRACT_MESSAGE )
|
||||
{
|
||||
$this->$regex = $regex;
|
||||
}
|
||||
|
||||
/** @return TRUE if the the ciphertext matches the regular expression, giving at least one result */
|
||||
function canDecode( $ciphertext )
|
||||
{
|
||||
return eregi($this->$regex,$message,$this->$matches) > 0;
|
||||
}
|
||||
|
||||
/** Extracts the core message using its regular expression, and calls the chain to return a totally decoded message */
|
||||
function decode( $ciphertext, $chain )
|
||||
{
|
||||
if ( defined($this->$matches) )
|
||||
{
|
||||
$cleartext = $chain->decode($matches[1]);
|
||||
delete $this->$matches;
|
||||
return $cleartext;
|
||||
}
|
||||
|
||||
// canDecode() *must* be called before decode()
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A simple decoder that removes salt from a message.
|
||||
* Salt is used to add randomness to a message : it can be removed safely
|
||||
*/
|
||||
class Desalter extends Depacketizer
|
||||
{
|
||||
/**
|
||||
* Only this constructor needs to be defined, in order to pass the superclass
|
||||
* the right regex to extract the salt from the message.
|
||||
*/
|
||||
function Desalter()
|
||||
{
|
||||
parent::Depacketizer('^salt[^:]*:(.*)$');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This decoder transforms an hexadecimal string into its binary representation
|
||||
*/
|
||||
class HexDecoder extends Depacketizer
|
||||
{
|
||||
function HexDecoder()
|
||||
{
|
||||
parent::Depacketizer('^(?:hex:|0x)(.*)$');
|
||||
}
|
||||
|
||||
function decode( $ciphertext, $chain )
|
||||
{
|
||||
// first step : let the base class extract the wanted message
|
||||
$message = parent::decode($ciphertext,$chain);
|
||||
|
||||
if ( $message )
|
||||
{
|
||||
// second step : do hexadecimal-to-text conversion
|
||||
return pack("H*",$message);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Decodes base64 encoded texts
|
||||
*/
|
||||
class Base64Decoder extends Depacketizer
|
||||
{
|
||||
function Base64Decoder()
|
||||
{
|
||||
parent::Depacketizer('^(?:base64|b64):(.*)$');
|
||||
}
|
||||
|
||||
function decode( $ciphertext, $chain )
|
||||
{
|
||||
// first step : let the base class extract the wanted message
|
||||
$message = parent::decode($ciphertext,$chain);
|
||||
|
||||
if ( $message )
|
||||
{
|
||||
// second step : pass the message to the available decoders to get the raw value to work on
|
||||
$cleartext = $chain->decode($message);
|
||||
|
||||
// final step : do hexadecimal-to-text conversion
|
||||
return pack("H*",$cleartext);
|
||||
if ( $base == 64 )
|
||||
{
|
||||
// we're already in the right radix, don't go further
|
||||
// (same can be done with other bases too, but right now we only need this one)
|
||||
return $tmpData;
|
||||
}
|
||||
$newData = base64_decode($tmpData);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO : embed the key in the data (e.g. ciform:rsa:keyId:0x12345:0xdd33be2b17813b396d63dd1be9c72e9756bbd8ae5d5555b93a7f4b4fd5a8c80d:salt24325234)
|
||||
// TODO : use the responsibility chain to rewrite this function
|
||||
function ciform_decode( $data, $keyPair, $base=1 )
|
||||
{
|
||||
if ( CIFORM_DEBUG ) echo "ciform_decrypt($data,keyPair,$base)<br>";
|
||||
|
||||
// $newData is going to be decoded by one of the following filters
|
||||
// then, it'll be encoded to the destination base
|
||||
$newData = $data;
|
||||
|
||||
// this flag means this parameter is handled by this library
|
||||
if ( eregi('^'.CIFORM_REQUEST_PREFIX.'(.*)$',$data,$matches) > 0 )
|
||||
{
|
||||
$newData = ciform_decode($matches[1],$keyPair);
|
||||
}
|
||||
|
||||
// this is just salt that adds randomness to the string : it can be removed safely
|
||||
else if ( eregi('^salt[^:]*:(.*)$',$data,$matches) > 0 )
|
||||
{
|
||||
$newData = ciform_decode($matches[1],$keyPair);
|
||||
}
|
||||
|
||||
// this is an hexadecimal string
|
||||
else if ( eregi('^(hex:|0x)(.*)$',$data,$matches) > 0 )
|
||||
{
|
||||
$tmpData = ciform_decode($matches[2],$keyPair);
|
||||
$newData = pack("H*",$tmpData);
|
||||
}
|
||||
|
||||
// this a base64 encoded string
|
||||
else if ( eregi('^(base64|b64):(.*)$',$data,$matches) > 0 )
|
||||
{
|
||||
$tmpData = ciform_decode($matches[2],$keyPair);
|
||||
if ( $base == 64 )
|
||||
{
|
||||
// we're already in the right radix, don't go further
|
||||
// (same can be done with other bases too, but right now we only need this one)
|
||||
return $tmpData;
|
||||
}
|
||||
$newData = base64_decode($tmpData);
|
||||
}
|
||||
|
||||
// this is an encrypted message
|
||||
else if ( eregi('^'.CIFORM_KEYTYPE.':(.*)(:.+)?$',$data,$matches) > 0 )
|
||||
{
|
||||
$tmpData = ciform_decode($matches[1],$keyPair,64);
|
||||
|
||||
// decrypts the data using the configured module
|
||||
$func = "ciform_".CIFORM_KEYTYPE."_decrypt";
|
||||
$newData = ciform_decode( $func($tmpData,$keyPair), $keyPair );
|
||||
}
|
||||
|
||||
// FIXME : do better recursion : each case should return ciform_decode($tmpData) except if no encoding is detected (which then ends the recursion)
|
||||
// FIXME : put each case in a different 'decoder' class
|
||||
|
||||
// encodes the data into the desired base
|
||||
switch( $base )
|
||||
{
|
||||
case 64:
|
||||
return base64_encode($newData);
|
||||
default:
|
||||
return $newData;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ciform_decryptParam( $data, $keyPair )
|
||||
{
|
||||
if ( gettype($data) == "string" && eregi('^'.CIFORM_REQUEST_PREFIX.'(.*)$',$data,$matches) > 0 )
|
||||
{
|
||||
return ciform_decode($matches[1],$keyPair);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function ciform_decryptParams( $request, $keyPair )
|
||||
{
|
||||
$decoded = array();
|
||||
|
||||
// accepts encrypted data from the client
|
||||
foreach ( $request as $key => $value )
|
||||
{
|
||||
$newValue = ciform_decryptParam($value,$keyPair);
|
||||
$decoded[$key] = $newValue;
|
||||
}
|
||||
|
||||
return $decoded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// returns the protocol of this script
|
||||
if ( isset($_REQUEST[CIFORM_REQUEST_PROTOCOL]) )
|
||||
{
|
||||
$func = "ciform_".CIFORM_KEYTYPE."_getProtocol";
|
||||
$name = $_REQUEST[CIFORM_REQUEST_PROTOCOL];
|
||||
header("Content-type: text/plain");
|
||||
// if a name was given, use it to name the variable :
|
||||
// the result may be used as a full (java)script
|
||||
if ( trim($name) != "" ) {
|
||||
echo "var $name = " . $func() . ";";
|
||||
}
|
||||
// if no name was given, just print the JSON value :
|
||||
// the result may be used as an Ajax response
|
||||
else {
|
||||
echo $func();
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// makes sure the key is accessible
|
||||
// TODO : instanciate the given crypto class,
|
||||
// which stores itself the key and all other specific data
|
||||
// then, move the following code to the correct sub-script
|
||||
if ( !isset($_SESSION[CIFORM_SESSION]) )
|
||||
{
|
||||
$_SESSION[CIFORM_SESSION] = array();
|
||||
}
|
||||
if ( !isset($_SESSION[CIFORM_SESSION][CIFORM_SESSION_KEYPAIR]) )
|
||||
{
|
||||
// the encryption module's name is given by the defined key type
|
||||
$func = "ciform_".CIFORM_KEYTYPE."_getKeyPair";
|
||||
$_SESSION[CIFORM_SESSION][CIFORM_SESSION_KEYPAIR] = $func();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ( CIFORM_AUTODECRYPT )
|
||||
{
|
||||
$_REQUEST = ciform_decryptParams($_REQUEST,$_SESSION[CIFORM_SESSION][CIFORM_SESSION_KEYPAIR]);
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,230 +0,0 @@
|
|||
<?php
|
||||
require_once("Crypt/RSA.php");
|
||||
|
||||
define("CIFORM_RSA_KEYTYPE","rsa");
|
||||
define("CIFORM_RSA_KEYSIZE",768);
|
||||
define("CIFORM_RSA_KEYSTORE","keys");
|
||||
define("CIFORM_RSA_KEYFILE_PEM",CIFORM_RSA_KEYSTORE."/protected/key-rsa.pem");
|
||||
define("CIFORM_RSA_KEYFILE_JS",CIFORM_RSA_KEYSTORE."/key-rsa.pub.json");
|
||||
define("CIFORM_RSA_REQUEST_GENKEY","ciform-genkey");
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class extends Crypt_RSA_KeyPair by adding conversion functions to Javascript and to the Ciform protocol
|
||||
*/
|
||||
class Ciform_RSA_KeyPair extends Crypt_RSA_KeyPair
|
||||
{
|
||||
/**
|
||||
* Transforms a big integer value into a JSON array of 28 bits integers
|
||||
*
|
||||
* @param string $binValue The raw, binary string value of the big integer
|
||||
* @param Crypt_RSA_Math_* $math Optional math wrapper to use to manipulate large integers. Will use the current one if not specified.
|
||||
* @see Crypt_RSA_KeyPair::$_math_obj
|
||||
* @return string The number as a JSON structure
|
||||
* @access private
|
||||
*/
|
||||
function bigInt2Json( $binValue, $math=$this->_math_obj )
|
||||
{
|
||||
$json = "[";
|
||||
|
||||
$intValue = $math->bin2int($binValue);
|
||||
$szBits = $math->bitLen($intValue); // total length, in bits
|
||||
|
||||
for ( $b=0 ; $b<$szBits ; )
|
||||
{
|
||||
$l = min(28,$szBits-$b);
|
||||
$json .= $math->subint($intValue, $b, $l);
|
||||
$b += $l;
|
||||
if ( $b<$szBits )
|
||||
{
|
||||
$json .= ",";
|
||||
}
|
||||
}
|
||||
|
||||
return $json."]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Transforms an RSA public key into a JSON structure
|
||||
*
|
||||
* @param Crypt_RSA_KeyPair $keyPair Optional RSA key pair holding the public key (use this if called from the class context).
|
||||
* @return string The public key as a JSON structure
|
||||
* @access private
|
||||
*/
|
||||
function pubKey2Json( $keyPair=$this )
|
||||
{
|
||||
$pubKey = $keyPair->getPublicKey();
|
||||
$math = $keyPair->_math_obj;
|
||||
$p = Ciform_RSA_KeyPair::bigInt2Json($keyPair->_attrs['p'],$math);
|
||||
$q = Ciform_RSA_KeyPair::bigInt2Json($keyPair->_attrs['q'],$math);
|
||||
$e = Ciform_RSA_KeyPair::bigInt2Json($pubKey->getExponent(),$math);
|
||||
$pq = Ciform_RSA_KeyPair::bigInt2Json($pubKey->getModulus(),$math);
|
||||
//$mpi = base64_encode($math->bin2int($pubKey->getModulus())+$math->bin2int($pubKey->getExponent()));
|
||||
$json = "{"
|
||||
."'type':'".CIFORM_RSA_KEYTYPE."',"
|
||||
."'size':".$pubKey->getKeyLength()."," // size of the key, in bits
|
||||
."'p':$p," // prime factor p, as an array of 28 bits integers
|
||||
."'q':$q," // prime factor q, as an array of 28 bits integers
|
||||
."'e':$e," // public exponent as an array of 28 bits integers
|
||||
."'pq':$pq}"; // modulus, as an array of 28 bits integers
|
||||
//."'mpi':'$mpi'" // e + modulus, encoded into a base64 MPI string
|
||||
return $json;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clones an existing key pair by copying its intrisinc fields into this one,
|
||||
*
|
||||
* @param Crypt_RSA_KeyPair $keyPair The key pair to copy
|
||||
* @return $this
|
||||
* @todo This implementation depends totally on the version of the superclass :
|
||||
* if a field is added or removed, this method can very possibly fail to do its job
|
||||
* @private
|
||||
*/
|
||||
function copy( $keyPair )
|
||||
{
|
||||
$this->$_math_obj = $keyPair->$_math_obj;
|
||||
$this->$_key_len = $keyPair->$_key_len;
|
||||
$this->$_public_key = $keyPair->$_public_key;
|
||||
$this->$_private_key = $keyPair->$_private_key;
|
||||
$this->$_random_generator = $keyPair->$_random_generator;
|
||||
$this->$_attrs = $keyPair->$_attrs;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This method is overriden to instanciate an object from the same class as the current object
|
||||
* @see Crypt_RSA_KeyPair::fromPEMString
|
||||
* @todo This should be done in the superclass : it should dynamically return a new instance of the current class
|
||||
*/
|
||||
function &fromPEMString($str, $wrapper_name = 'default', $error_handler = '')
|
||||
{
|
||||
$keyPair1 = parent::fromPEMString($str,$wrapper_name,$error_handler);
|
||||
$keyPair2 = new Crypt_RSA_KeyPair();
|
||||
$keyPair2->copy($keyPair1);
|
||||
return $keyPair2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Uses an existing key pair stored in a file or generates a new one.
|
||||
*
|
||||
* If the PEM file exist, the key pair will be read from it. If it doesn't, the key pair will be generated.<br>
|
||||
* Upon generation of a new key pair, both a PEM and a Javascript file will be created if they don't exist already.
|
||||
*
|
||||
* @param int $keySize Size of the key to generate, in bits
|
||||
* @param string $pemFilename Name of the file where a PEM formated keypair may be found / stored
|
||||
* @param string $jsFilename Name of the file where to store the key upon generation as a Javascript script
|
||||
* @param boolean $force Forces generation of both the PEM and the Javascript file. If false, the files will not be overwritten if they exist already.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function genKeyPair( $keySize, $pemFilename, $jsFilename, $force=FALSE )
|
||||
{
|
||||
// if the key has been stored to a file, get it from there
|
||||
if ( $contents = @file_get_contents($pemFilename) )
|
||||
{
|
||||
return Ciform_RSA_KeyPair::fromPEMString($contents);
|
||||
}
|
||||
|
||||
// else, generate a new key and try to store it to a file
|
||||
else
|
||||
{
|
||||
// generates the key
|
||||
$keyPair = new Ciform_RSA_KeyPair($keySize);
|
||||
|
||||
// stores as PEM
|
||||
if ( $force || !@file_exists($pemFilename) )
|
||||
{
|
||||
@mkdir(dirname($pemFilename),0777,TRUE);
|
||||
@file_put_contents($pemFilename,$keyPair->toPEMString());
|
||||
}
|
||||
|
||||
// store some Javascript variables, including the public key
|
||||
// FIXME : if file_put_contents fails, no notification but the file is never written
|
||||
if ( $force || !@file_exists($jsFilename) )
|
||||
{
|
||||
@mkdir(dirname($jsFilename),0777,TRUE);
|
||||
// FIXME : serverURL must be absolute, so scripts can call it from other servers
|
||||
//$serverURL = $_SERVER['PHP_SELF'];
|
||||
$pubKey = $keyPair->pubKey2Json();
|
||||
//$jsContents = "\nvar CIFORM = {'serverURL':'".str_replace("'","\\'",$serverURL)."', 'pubKey':$pubKey};";
|
||||
@file_put_contents($jsFilename,$pubKey);
|
||||
}
|
||||
|
||||
// returns the newly created key
|
||||
return $keyPair;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Ciform handler using the RSA cipher
|
||||
*/
|
||||
class Ciform_RSA
|
||||
{
|
||||
/**
|
||||
* @return Ciform_RSA_KeyPair the current key pair (or a new one if none defined)
|
||||
*/
|
||||
function getKeyPair()
|
||||
{
|
||||
if ( CIFORM_DEBUG ) echo "ciform_rsa_getKeyPair() = ";
|
||||
$keyPair = Ciform_RSA_KeyPair::genKeyPair(CIFORM_RSA_KEYSIZE, CIFORM_RSA_KEYFILE_PEM, CIFORM_RSA_KEYFILE_JS);
|
||||
if ( CIFORM_DEBUG ) print_r($keyPair);
|
||||
return $keyPair;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return string the current Ciform protocol
|
||||
*/
|
||||
function getProtocol()
|
||||
{
|
||||
if ( CIFORM_DEBUG ) echo "ciform_rsa_getProtocol() = ";
|
||||
// FIXME : serverURL must be absolute, so scripts can call it from other servers
|
||||
$serverURL = $_SERVER['PHP_SELF'];
|
||||
$keyPair = Ciform_RSA::getKeyPair();
|
||||
$protocol = "{
|
||||
'VERSION':".CIFORM_PROTOCOL_VERSION.",
|
||||
'PACKET_PREFIX':'".CIFORM_REQUEST_PREFIX."',
|
||||
'serverURL':'".str_replace("'","\\'",$serverURL)."',
|
||||
'pubKey':".$keyPair->pubKey2Json()
|
||||
."}";
|
||||
if ( CIFORM_DEBUG ) print_r($protocol);
|
||||
return $protocol;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function decrypt( $data, $keyPair )
|
||||
{
|
||||
if ( CIFORM_DEBUG ) echo "ciform_rsa_decrypt($data,keyPair)<br>";
|
||||
$privateKey = $keyPair->getPrivateKey();
|
||||
// TODO make the math object configurable, because there are big differences between them and to offer better compatibility
|
||||
$rsa = new Crypt_RSA($privateKey->getKeyLength(),'BCMath');
|
||||
return $rsa->decrypt($data,$privateKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// keypair generation is forced if this parameter is set
|
||||
if ( isset($_SESSION[CIFORM_RSA_REQUEST_GENKEY]) )
|
||||
{
|
||||
$_SESSION[CIFORM_SESSION][CIFORM_SESSION_KEYPAIR] = Ciform_RSA_KeyPair::genKeyPair(CIFORM_RSA_KEYSIZE, CIFORM_RSA_KEYFILE_PEM, CIFORM_RSA_KEYFILE_JS, TRUE);
|
||||
}
|
||||
|
||||
?>
|
||||
49
ciform/trunk/src/crypto/Cipher.class.php
Normal file
49
ciform/trunk/src/crypto/Cipher.class.php
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
//
|
||||
// Ciform
|
||||
//
|
||||
// Copyright © 2008 Nicolas BONARDELLE <http://nicobo.net/contact>
|
||||
//
|
||||
|
||||
/**
|
||||
* Core ciphers for ciform messages.<br>
|
||||
*
|
||||
* COPYRIGHT NOTICE :<pre>
|
||||
*
|
||||
* Copyright © 2008 Nicolas BONARDELLE <http://nicobo.net/contact>
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
* <p>Most of the ciphers here are only partially implemented, since this server-side library doesn't use encryption yet.</p>
|
||||
*
|
||||
* @package ciform
|
||||
* @subpackage ciphers
|
||||
* @link http://plugnauth.sourceforge.net/ciform
|
||||
* @author Nicolas BONARDELLE <http://nicobo.net/contact>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class specifies the interface of a cipher : both the encoding and the decoding parts.<br>
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
class crypto_Cipher
|
||||
{
|
||||
/**
|
||||
* @param string $cleartext The message to encode
|
||||
* @return string The encoded message (= ciphertext)
|
||||
* @abstract
|
||||
*/
|
||||
function encode( $cleartext ) { throw new Exception("This method is not implemented."); }
|
||||
|
||||
/**
|
||||
* @param string $ciphertext The encoded message to decode
|
||||
* @return string|FALSE The decoded message or FALSE if this object cannot decode the given ciphertext
|
||||
* @abstract
|
||||
*/
|
||||
function decode( $ciphertext ) { throw new Exception("This method is not implemented."); }
|
||||
}
|
||||
|
||||
?>
|
||||
60
ciform/trunk/src/crypto/ciphers/core.php
Normal file
60
ciform/trunk/src/crypto/ciphers/core.php
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
//
|
||||
// Ciform
|
||||
//
|
||||
// Copyright © 2008 Nicolas BONARDELLE <http://nicobo.net/contact>
|
||||
//
|
||||
|
||||
/**
|
||||
* A few common ciphers.<br>
|
||||
*
|
||||
* COPYRIGHT NOTICE :<pre>
|
||||
*
|
||||
* Copyright © 2008 Nicolas BONARDELLE <http://nicobo.net/contact>
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
* <p>Most of the ciphers here are only partially implemented, since this server-side library doesn't use encryption yet.</p>
|
||||
*
|
||||
* @package crypto
|
||||
* @subpackage ciphers
|
||||
* @link http://plugnauth.sourceforge.net/ciform
|
||||
* @author Nicolas BONARDELLE <http://nicobo.net/contact>
|
||||
*/
|
||||
|
||||
require_once "crypto/Cipher.class.php";
|
||||
|
||||
// Comment out the following line to enable debug traces from this script
|
||||
//define("CRYPTO_DEBUG",TRUE);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This cipher transforms an text into its hexadecimal representation
|
||||
*/
|
||||
class crypto_ciphers_Base16 extends crypto_Cipher
|
||||
{
|
||||
function decode( $base16msg )
|
||||
{
|
||||
if ( CRYPTO_DEBUG) { echo print_r($this,TRUE)."->decode($base16msg)"."\n"; }
|
||||
|
||||
return pack("H*",$base16msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Encodes/decodes text into/from a base64 string
|
||||
*/
|
||||
class crypto_ciphers_Base64 extends crypto_Cipher
|
||||
{
|
||||
function decode( $base64msg )
|
||||
{
|
||||
if ( CRYPTO_DEBUG) { echo print_r($this,TRUE)."->decode($base64msg)"."\n"; }
|
||||
|
||||
return base64_decode($base64msg);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
308
ciform/trunk/src/crypto/ciphers/rsa.php
Normal file
308
ciform/trunk/src/crypto/ciphers/rsa.php
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
<?php
|
||||
//
|
||||
// Ciform
|
||||
//
|
||||
// Copyright © 2008 Nicolas BONARDELLE <http://nicobo.net/contact>
|
||||
//
|
||||
|
||||
require_once "crypto/ciphers/core.php";
|
||||
require_once("Crypt/RSA.php");
|
||||
|
||||
define("CIFORM_RSA_KEYTYPE","rsa");
|
||||
define("CIFORM_RSA_KEYSIZE",768);
|
||||
define("CIFORM_RSA_KEYSTORE","keys");
|
||||
define("CIFORM_RSA_KEYFILE_PEM",CIFORM_RSA_KEYSTORE."/protected/key-rsa.pem");
|
||||
define("CIFORM_RSA_KEYFILE_JS",CIFORM_RSA_KEYSTORE."/key-rsa.pub.json");
|
||||
define("CIFORM_RSA_REQUEST_GENKEY","ciform-genkey");
|
||||
define("CIFORM_SESSION_KEYPAIR","KEYPAIR"); // TODO : move to ciform_rsa.php
|
||||
/** */
|
||||
define("CIFORM_KEYTYPE",CIFORM_RSA_KEYTYPE); // choose the desired encryption module here
|
||||
|
||||
|
||||
// TODO : embed the key in the data (e.g. ciform:rsa:keyId:0x12345:0xdd33be2b17813b396d63dd1be9c72e9756bbd8ae5d5555b93a7f4b4fd5a8c80d:salt24325234)
|
||||
|
||||
|
||||
//
|
||||
// RSA SPECIAL HANDLING : Since this is the default encryption,
|
||||
// the script will retrieve the keys or generated them if not found.
|
||||
//
|
||||
// TODO : instanciate the given crypto class,
|
||||
// which stores itself the key and all other specific data
|
||||
// then, move the following code to the correct sub-script
|
||||
if ( !isset($_SESSION[CIFORM_SESSION]) )
|
||||
{
|
||||
$_SESSION[CIFORM_SESSION] = array();
|
||||
}
|
||||
if ( !isset($_SESSION[CIFORM_SESSION][CIFORM_SESSION_KEYPAIR]) )
|
||||
{
|
||||
// the encryption module's name is given by the defined key type
|
||||
$func = "ciform_".CIFORM_KEYTYPE."_getKeyPair";
|
||||
$_SESSION[CIFORM_SESSION][CIFORM_SESSION_KEYPAIR] = $func();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class extends Crypt_RSA_KeyPair by adding conversion functions to Javascript and to the Ciform protocol
|
||||
*/
|
||||
class Ciform_ciphers_rsa_KeyPair extends Crypt_RSA_KeyPair
|
||||
{
|
||||
/**
|
||||
* Transforms a big integer value into a JSON array of 28 bits integers
|
||||
*
|
||||
* @param string $binValue The raw, binary string value of the big integer
|
||||
* @param Crypt_RSA_Math_* $math Optional math wrapper to use to manipulate large integers. Will use the current one if not specified.
|
||||
* @see Crypt_RSA_KeyPair::$_math_obj
|
||||
* @return string The number as a JSON structure
|
||||
* @access private
|
||||
*/
|
||||
function bigInt2Json( $binValue, $math=$this->_math_obj )
|
||||
{
|
||||
$json = "[";
|
||||
|
||||
$intValue = $math->bin2int($binValue);
|
||||
$szBits = $math->bitLen($intValue); // total length, in bits
|
||||
|
||||
for ( $b=0 ; $b<$szBits ; )
|
||||
{
|
||||
$l = min(28,$szBits-$b);
|
||||
$json .= $math->subint($intValue, $b, $l);
|
||||
$b += $l;
|
||||
if ( $b<$szBits )
|
||||
{
|
||||
$json .= ",";
|
||||
}
|
||||
}
|
||||
|
||||
return $json."]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Exports a RSA public key into an associative array, ready for JSON transformation
|
||||
*
|
||||
* @param Crypt_RSA_KeyPair $keyPair Optional RSA key pair holding the public key (use this if called from the class context).
|
||||
* @return array The public key as an associative array
|
||||
* @access private
|
||||
*/
|
||||
function exportPubKey( $keyPair=$this )
|
||||
{
|
||||
$pubKey = $keyPair->getPublicKey();
|
||||
$math = $keyPair->_math_obj;
|
||||
$p = Ciform_RSA_KeyPair::bigInt2Json($keyPair->_attrs['p'],$math);
|
||||
$q = Ciform_RSA_KeyPair::bigInt2Json($keyPair->_attrs['q'],$math);
|
||||
$e = Ciform_RSA_KeyPair::bigInt2Json($pubKey->getExponent(),$math);
|
||||
$pq = Ciform_RSA_KeyPair::bigInt2Json($pubKey->getModulus(),$math);
|
||||
//$mpi = base64_encode($math->bin2int($pubKey->getModulus())+$math->bin2int($pubKey->getExponent()));
|
||||
|
||||
$export = array(
|
||||
'type' => CIFORM_RSA_KEYTYPE,
|
||||
'size' => $pubKey->getKeyLength(), // size of the key, in bits
|
||||
'p' => $p, // prime factor p, as an array of 28 bits integers
|
||||
'q' => $q, // prime factor q, as an array of 28 bits integers
|
||||
'e' => $e, // public exponent as an array of 28 bits integers
|
||||
'pq' => $pq; // modulus, as an array of 28 bits integers
|
||||
//'mpi' => $mpi // e + modulus, encoded into a base64 MPI string
|
||||
);
|
||||
|
||||
return $export;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clones an existing key pair by copying its intrisinc fields into this one,
|
||||
*
|
||||
* @param Crypt_RSA_KeyPair $keyPair The key pair to copy
|
||||
* @return $this
|
||||
* @todo This implementation depends totally on the version of the superclass :
|
||||
* if a field is added or removed, this method can very possibly fail to do its job
|
||||
* @private
|
||||
*/
|
||||
function copy( $keyPair )
|
||||
{
|
||||
$this->$_math_obj = $keyPair->$_math_obj;
|
||||
$this->$_key_len = $keyPair->$_key_len;
|
||||
$this->$_public_key = $keyPair->$_public_key;
|
||||
$this->$_private_key = $keyPair->$_private_key;
|
||||
$this->$_random_generator = $keyPair->$_random_generator;
|
||||
$this->$_attrs = $keyPair->$_attrs;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This method is overriden to instanciate an object from the same class as the current object
|
||||
* @see Crypt_RSA_KeyPair::fromPEMString
|
||||
* @todo This should be done in the superclass : it should dynamically return a new instance of the current class
|
||||
*/
|
||||
function &fromPEMString($str, $wrapper_name = 'default', $error_handler = '')
|
||||
{
|
||||
$keyPair1 = parent::fromPEMString($str,$wrapper_name,$error_handler);
|
||||
$keyPair2 = new Crypt_RSA_KeyPair();
|
||||
$keyPair2->copy($keyPair1);
|
||||
return $keyPair2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Uses an existing key pair stored in a file or generates a new one.
|
||||
*
|
||||
* If the PEM file exist, the key pair will be read from it. If it doesn't, the key pair will be generated.<br>
|
||||
* Upon generation of a new key pair, both a PEM and a Javascript file will be created if they don't exist already.
|
||||
*
|
||||
* @param int $keySize Size of the key to generate, in bits
|
||||
* @param string $pemFilename Name of the file where a PEM formated keypair may be found / stored
|
||||
* @param string $jsFilename Name of the file where to store the key upon generation as a Javascript script
|
||||
* @param boolean $force Forces generation of both the PEM and the Javascript file. If false, the files will not be overwritten if they exist already.
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
function genKeyPair( $keySize, $pemFilename, $jsFilename, $force=FALSE )
|
||||
{
|
||||
// if the key has been stored to a file, get it from there
|
||||
if ( $contents = @file_get_contents($pemFilename) )
|
||||
{
|
||||
return Ciform_RSA_KeyPair::fromPEMString($contents);
|
||||
}
|
||||
|
||||
// else, generate a new key and try to store it to a file
|
||||
else
|
||||
{
|
||||
// generates the key
|
||||
$keyPair = new Ciform_RSA_KeyPair($keySize);
|
||||
|
||||
// stores as PEM
|
||||
if ( $force || !@file_exists($pemFilename) )
|
||||
{
|
||||
@mkdir(dirname($pemFilename),0777,TRUE);
|
||||
@file_put_contents($pemFilename,$keyPair->toPEMString());
|
||||
}
|
||||
|
||||
// store some Javascript variables, including the public key
|
||||
// FIXME : if file_put_contents fails, no notification but the file is never written
|
||||
if ( $force || !@file_exists($jsFilename) )
|
||||
{
|
||||
@mkdir(dirname($jsFilename),0777,TRUE);
|
||||
// FIXME : serverURL must be absolute, so scripts can call it from other servers
|
||||
//$serverURL = $_SERVER['PHP_SELF'];
|
||||
$pubKey = $keyPair->pubKey2Json();
|
||||
//$jsContents = "\nvar CIFORM = {'serverURL':'".str_replace("'","\\'",$serverURL)."', 'pubKey':$pubKey};";
|
||||
@file_put_contents($jsFilename,$pubKey);
|
||||
}
|
||||
|
||||
// returns the newly created key
|
||||
return $keyPair;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Ciform handler using the RSA cipher
|
||||
*/
|
||||
class Ciform_RSA extends Ciform_
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @return Ciform_RSA_KeyPair the current key pair (or a new one if none defined)
|
||||
*/
|
||||
function getKeyPair()
|
||||
{
|
||||
if ( CIFORM_DEBUG ) echo "ciform_rsa_getKeyPair() = ";
|
||||
$keyPair = Ciform_RSA_KeyPair::genKeyPair(CIFORM_RSA_KEYSIZE, CIFORM_RSA_KEYFILE_PEM, CIFORM_RSA_KEYFILE_JS);
|
||||
if ( CIFORM_DEBUG ) print_r($keyPair);
|
||||
return $keyPair;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return string the current Ciform protocol
|
||||
*/
|
||||
function getProtocol()
|
||||
{
|
||||
'pubKey' => $keyPair->exportPubKey(),
|
||||
|
||||
if ( CIFORM_DEBUG ) echo "ciform_rsa_getProtocol() = ";
|
||||
// FIXME : serverURL must be absolute, so scripts can call it from other servers
|
||||
$serverURL = $_SERVER['PHP_SELF'];
|
||||
$keyPair = Ciform_RSA::getKeyPair();
|
||||
$protocol = "{
|
||||
'VERSION':".CIFORM_PROTOCOL_VERSION.",
|
||||
'PACKET_PREFIX':'".CIFORM_REQUEST_PREFIX."',
|
||||
'serverURL':'".str_replace("'","\\'",$serverURL)."',
|
||||
'pubKey':".$keyPair->pubKey2Json()
|
||||
."}";
|
||||
if ( CIFORM_DEBUG ) print_r($protocol);
|
||||
return $protocol;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function decrypt( $data, $keyPair )
|
||||
{
|
||||
if ( CIFORM_DEBUG ) echo "ciform_rsa_decrypt($data,keyPair)<br>";
|
||||
$privateKey = $keyPair->getPrivateKey();
|
||||
// TODO make the math object configurable, because there are big differences between them and to offer better compatibility
|
||||
$rsa = new Crypt_RSA($privateKey->getKeyLength(),'BCMath');
|
||||
return $rsa->decrypt($data,$privateKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Ciform_schemes_RSA extends Ciform_SimpleScheme
|
||||
{
|
||||
function Ciform_schemes_RSA()
|
||||
{
|
||||
parent::Ciform_SimpleScheme("rsa",'/^rsa:(.*)(:.+)?$/i');
|
||||
}
|
||||
|
||||
function export()
|
||||
{
|
||||
return array( 'pubKey' => $keyPair->exportPubKey() );
|
||||
}
|
||||
|
||||
function getDecoder( $packet )
|
||||
{
|
||||
if ( CIFORM_DEBUG ) { echo print_r($this,TRUE)."->getDecoder($packet)"."\n"; }
|
||||
|
||||
if ( $this->unpack($packet) )
|
||||
{
|
||||
return new crypto_ciphers_Base64();
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// keypair generation is forced if this parameter is set
|
||||
if ( isset($_SESSION[CIFORM_RSA_REQUEST_GENKEY]) )
|
||||
{
|
||||
$_SESSION[CIFORM_SESSION][CIFORM_SESSION_KEYPAIR] = Ciform_RSA_KeyPair::genKeyPair(CIFORM_RSA_KEYSIZE, CIFORM_RSA_KEYFILE_PEM, CIFORM_RSA_KEYFILE_JS, TRUE);
|
||||
}
|
||||
|
||||
?>
|
||||
Loading…
Reference in a new issue