diff --git a/ciform/trunk/src/ciform/ciform.php b/ciform/trunk/src/ciform/ciform.php
index 93050cc..6fef7f9 100644
--- a/ciform/trunk/src/ciform/ciform.php
+++ b/ciform/trunk/src/ciform/ciform.php
@@ -35,7 +35,7 @@ define("CIFORM_SESSION","CIFORM");
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");
+define("CIFORM_REQUEST_PROTOCOL","ciform-protocol");
if ( ! defined("CIFORM_AUTODECRYPT") )
/** Define this constant to TRUE in caller script to enable transparent decryption of the request */
@@ -106,7 +106,7 @@ class ciform_Server
/**
* @return array the current Ciform protocol
*/
- function getProtocol()
+ function export()
{
// FIXME : serverURL must be absolute, so scripts can call it from other servers
$serverURL = $_SERVER['PHP_SELF'];
@@ -114,7 +114,7 @@ class ciform_Server
$schemes = array();
foreach ( $this->codec->ciphers as $cipher )
{
- $schemes[$cipher->getName()] = $cipher->getParameters();
+ $schemes[$cipher->getName()] = $cipher->export();
}
$protocol = array(
@@ -147,12 +147,12 @@ if ( isset($_REQUEST[CIFORM_REQUEST_PROTOCOL]) )
// 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()) . ";";
+ echo "var $name = " . json_encode($ciform->export()) . ";";
}
// 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());
+ echo json_encode($ciform->export());
}
exit;
diff --git a/ciform/trunk/src/ciform/schemes/core.php b/ciform/trunk/src/ciform/schemes/core.php
index a96c3ee..6a55d8a 100644
--- a/ciform/trunk/src/ciform/schemes/core.php
+++ b/ciform/trunk/src/ciform/schemes/core.php
@@ -42,7 +42,7 @@ class Ciform_Scheme extends crypto_Cipher
*/
var $name;
- Ciform_Scheme( $name )
+ function Ciform_Scheme( $name )
{
if ( defined($name) ) {
$this->name = $name;
@@ -57,6 +57,21 @@ class Ciform_Scheme extends crypto_Cipher
return $this->name;
}
+ /**
+ * This method provides a representation of this object to send to the client.
+ *
+ *
The clients will be provided this representation, which must contain all information
+ * necessary to the correct transmission of encrypted informations to (and from) this server.
+ *
+ * Since it is carried by each scheme, different implementations of the same scheme must return the same kind of data.
+ *
+ * @return array The crucial properties of this object in an array. Defaults to an empty array.
+ */
+ function export()
+ {
+ return array();
+ }
+
/**
* Builds a packet with full scheme from a message.
* @param string $packet The message to pack
@@ -94,12 +109,13 @@ class Ciform_CipherChain extends Ciform_Scheme
*/
var $ciphers;
+
/**
* @param array $ciphers The list of the internal {@link crypto_Cipher}s in this chain
*/
- function Ciform_CipherChain( $ciphers, $name="schemes" )
+ function Ciform_CipherChain( $ciphers )
{
- parent::Ciform_Scheme($name);
+ parent::Ciform_Scheme(NULL);
$this->ciphers = $ciphers;
}
@@ -113,14 +129,12 @@ class Ciform_CipherChain extends Ciform_Scheme
*/
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) )
+ if ( $cleartext = $decoder->decode($packet,$this) )
{
- return $message;
+ return $cleartext;
}
}
@@ -137,6 +151,8 @@ class Ciform_CipherChain extends Ciform_Scheme
*/
function decode( $packet )
{
+ if ( CIFORM_DEBUG ) echo print_r($this,TRUE)."->decode($packet)"."\n";
+
// 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 );
@@ -218,7 +234,7 @@ class Ciform_Codec extends Ciform_Scheme
*/
function decode( $packet, $chain=FALSE )
{
- if ( CIFORM_DEBUG ) { echo print_r($this,TRUE),"->decode($packet,",print_r($chain,TRUE),")"."\n"; }
+ if ( CIFORM_DEBUG ) { echo print_r($this,TRUE),"->decode($packet,)"."\n"; }
// uses the internal chain (if any) if the chain was not given as an argument
$myChain = $chain ? $chain : ($this->chain ? $this->chain : FALSE);
@@ -257,7 +273,7 @@ class Ciform_Codec extends Ciform_Scheme
}
}
- if ( CIFORM_DEBUG ) { echo "unpacked=".print_r($this->unpack($packet),TRUE)."\n"; }
+ if ( CIFORM_DEBUG ) { echo "unpacked=$unpacked"."\n"; }
// if no decoder was found, this object does not handle this scheme
return FALSE;
@@ -379,7 +395,7 @@ class Ciform_schemes_Base64 extends Ciform_SimpleScheme
*/
function Ciform_schemes_Base64( $unpackOnly=FALSE )
{
- parent::Ciform_SimpleScheme("base64",'/^(?:base64|b64):(.*)$/',$unpackOnly);
+ parent::Ciform_SimpleScheme("base64",'/^(?:base64|b64):(.*)$/i',$unpackOnly);
}
function getDecoder( $packet )
diff --git a/ciform/trunk/src/crypto/ciphers/rsa.php b/ciform/trunk/src/crypto/ciphers/rsa.php
index d1a2987..353deda 100644
--- a/ciform/trunk/src/crypto/ciphers/rsa.php
+++ b/ciform/trunk/src/crypto/ciphers/rsa.php
@@ -8,27 +8,19 @@
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
+
+/** Name of the entry in $_SESSION that will hold the current RSA key pairs */
+define("CIFORM_RSA_SESSION_KEYRING","CIFORM_RSA_SESSION_KEYRING");
+/** Default size, in bits, of the keys to generate */
+define("CIFORM_RSA_DEFAULT_KEYSIZE",768);
+/** Path to the .PEM file containing the default key pair */
+define("CIFORM_RSA_DEFAULT_PEMFILE","keys/protected/key-rsa.pem");
+/** Path to the .json file containing the default public key */
+define("CIFORM_RSA_DEFAULT_JSFILE","keys/key-rsa.pub.json");
// 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();
@@ -43,22 +35,26 @@ if ( !isset($_SESSION[CIFORM_SESSION][CIFORM_SESSION_KEYPAIR]) )
/**
- * This class extends Crypt_RSA_KeyPair by adding conversion functions to Javascript and to the Ciform protocol
+ * This class extends Crypt_RSA_KeyPair by adding conversion functions in order to conform to the Ciform protocol
+ *
+ * @package ciform
+ * @subpackage schemes.rsa
*/
-class Ciform_ciphers_rsa_KeyPair extends Crypt_RSA_KeyPair
+class crypto_ciphers_rsa_KeyPair extends Crypt_RSA_KeyPair
{
/**
- * Transforms a big integer value into a JSON array of 28 bits integers
+ * Transforms a big integer value into an 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
+ * @return array The number as an array of 28 bits integers
* @access private
+ * @static
*/
- function bigInt2Json( $binValue, $math=$this->_math_obj )
+ function bigInt2Array( $binValue, $math=$this->_math_obj )
{
- $json = "[";
+ $export = array();
$intValue = $math->bin2int($binValue);
$szBits = $math->bitLen($intValue); // total length, in bits
@@ -66,15 +62,11 @@ class Ciform_ciphers_rsa_KeyPair extends Crypt_RSA_KeyPair
for ( $b=0 ; $b<$szBits ; )
{
$l = min(28,$szBits-$b);
- $json .= $math->subint($intValue, $b, $l);
+ $export[$b] = $math->subint($intValue, $b, $l);
$b += $l;
- if ( $b<$szBits )
- {
- $json .= ",";
- }
}
- return $json."]";
+ return $export;
}
@@ -86,18 +78,18 @@ class Ciform_ciphers_rsa_KeyPair extends Crypt_RSA_KeyPair
* @return array The public key as an associative array
* @access private
*/
- function exportPubKey( $keyPair=$this )
+ function pubKey2Array( $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);
+ $p = crypto_ciphers_rsa_KeyPair::bigInt2Array($keyPair->_attrs['p'],$math);
+ $q = crypto_ciphers_rsa_KeyPair::bigInt2Array($keyPair->_attrs['q'],$math);
+ $e = crypto_ciphers_rsa_KeyPair::bigInt2Array($pubKey->getExponent(),$math);
+ $pq = crypto_ciphers_rsa_KeyPair::bigInt2Array($pubKey->getModulus(),$math);
//$mpi = base64_encode($math->bin2int($pubKey->getModulus())+$math->bin2int($pubKey->getExponent()));
$export = array(
- 'type' => CIFORM_RSA_KEYTYPE,
+ 'type' => "rsa",
'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
@@ -116,7 +108,7 @@ class Ciform_ciphers_rsa_KeyPair extends Crypt_RSA_KeyPair
*
* @param Crypt_RSA_KeyPair $keyPair The key pair to copy
* @return $this
- * @todo This implementation depends totally on the version of the superclass :
+ * FIXME This implementation totally depends on private parts of the superclass :
* if a field is added or removed, this method can very possibly fail to do its job
* @private
*/
@@ -161,12 +153,18 @@ class Ciform_ciphers_rsa_KeyPair extends Crypt_RSA_KeyPair
* @access private
* @static
*/
- function genKeyPair( $keySize, $pemFilename, $jsFilename, $force=FALSE )
+ function getInstance( $keyId, $keySize, $pemFilename, $jsFilename, $force=FALSE )
{
- // if the key has been stored to a file, get it from there
+ // first of all, if the key is in the current session, retrieve it
+ if ( isset($keyId) && isset($_SESSION[CIFORM_RSA_SESSION_KEYRING][$keyId]) )
+ {
+ return $_SESSION[CIFORM_RSA_SESSION_KEYRING][$keyId];
+ }
+
+ // second chance : 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);
+ return crypto_ciphers_rsa_KeyPair::fromPEMString($contents);
}
// else, generate a new key and try to store it to a file
@@ -202,107 +200,81 @@ class Ciform_ciphers_rsa_KeyPair extends Crypt_RSA_KeyPair
-/**
- * Ciform handler using the RSA cipher
- */
-class Ciform_RSA extends Ciform_
+class crypto_ciphers_RSA extends crypto_Cipher
{
-
+ var $keyPair;
+ var $cipher;
- /**
- * @return Ciform_RSA_KeyPair the current key pair (or a new one if none defined)
- */
- function getKeyPair()
+
+ function crypto_ciphers_RSA( $keyPair )
{
- 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;
- }
+ if ( CIFORM_DEBUG ) echo "new crypto_ciphers_RSA()
";
+ $this->keyPair = $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)
";
- $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);
+ $this->cipher = new Crypt_RSA($this->getPrivateKey->getKeyLength(),'BCMath');
+
+ if ( CIFORM_DEBUG ) echo "keyPair=".print_r($keyPair,TRUE)."
";
+ }
+
+
+ function &getInstance( $keyId, $keySize=CIFORM_RSA_KEYSIZE, $pemFile=CIFORM_RSA_KEYFILE_PEM, $jsFile=CIFORM_RSA_KEYFILE_JS, $forceGen=FALSE )
+ {
+ return new crypto_ciphers_RSA( crypto_ciphers_rsa_KeyPair::getInstance($keyId,$keySize,$pemFile,$jsFile,$forceGen) );
+ }
+
+
+ function decode( $ciphertext )
+ {
+ if ( CIFORM_DEBUG ) echo print_r($this,TRUE)."->decode($ciphertext)
";
+
+ return $rsa->decrypt( $ciphertext, $keyPair->getPrivateKey() );
}
}
-
-
-
-
-
+/**
+ * Ciform handler using the RSA cipher
+ */
class Ciform_schemes_RSA extends Ciform_SimpleScheme
{
- function Ciform_schemes_RSA()
+ var $keyId;
+ var $keySize;
+ var $pemFile;
+ var $jsFile;
+ var $forceGen;
+
+
+ function Ciform_schemes_RSA( $keyId=NULL, $keySize=CIFORM_RSA_KEYSIZE, $pemFile=CIFORM_RSA_KEYFILE_PEM, $jsFile=CIFORM_RSA_KEYFILE_JS, $forceGen=FALSE )
{
parent::Ciform_SimpleScheme("rsa",'/^rsa:(.*)(:.+)?$/i');
+ $this->keyId = $keyId;
+ $this->keySize = $keySize;
+ $this->pemFile = $pemFile;
+ $this->jsFile = $jsFile;
+ $this->forceGen = $forceGen;
}
+
function export()
{
- return array( 'pubKey' => $keyPair->exportPubKey() );
+ return array( 'pubKey' => $this->getKeyPair()->pubKey2Array() );
}
+
function getDecoder( $packet )
{
if ( CIFORM_DEBUG ) { echo print_r($this,TRUE)."->getDecoder($packet)"."\n"; }
if ( $this->unpack($packet) )
{
- return new crypto_ciphers_Base64();
+ return crypto_ciphers_RSA::getInstance( $this->keyId, $this->keySize, $this->pemFile, $this->jsFile, $this->forceGen );
}
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);
-}
-
?>
\ No newline at end of file