Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

We’re showing branches in this repository, but you can also compare across forks.

base fork: wepay/PHP-Encryption
base: 77a67b4f87
...
head fork: wepay/PHP-Encryption
compare: 9f70afdc33
  • 5 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
Commits on Feb 06, 2012
Eric Stern Move file storage to files/
Remove timezone setup
Decrypt (to disk for editing) returns plaintext file path on success
35e56fe
Commits on Feb 07, 2012
Eric Stern refactor bdbe5f7
Eric Stern scope tweaks for first version of cli c665d48
Eric Stern first version of cli tools e413d42
Eric Stern add files directory to gitignore 9f70afd
Showing with 157 additions and 12 deletions.
  1. +1 −0  .gitignore
  2. +96 −0 crypt
  3. +60 −12 encrypt.php
1  .gitignore
View
@@ -1,2 +1,3 @@
algorithm.php
files.php
+files
96 crypt
View
@@ -0,0 +1,96 @@
+#!/usr/bin/php
+<?php
+set_error_handler(function($a,$b,$c,$d){throw new ErrorException($b,0,$a,$c,$d);}, -1);
+require './encrypt.php';
+
+// Note: I just filed PHP bug #60997 for funky getopt optional argument handling. As a result, 'a' and 'v' must be treated as required, and if you omit a value when running this script they are parsed oddly. It was that or having "-a 'Author name'" not work right (it would have to be passed as "-a'Author name'")
+$opt = getopt('a:bdehrsv:', array('help'));
+$file = end($_SERVER['argv']);
+$version = isset($opt['v']) ? $opt['v'] : null;
+$author = isset($opt['a']) ? $opt['a'] : '';
+$bump = isset($opt['b']);
+$same = isset($opt['s']);
+// This order is specific: least chance of accidentally writing decrypted file in the event of CLI typo
+if (isset($opt['h']) || isset($opt['help'])) {
+ usage();
+}
+elseif (isset($opt['r'])) {
+ rotate($file, $author, $bump, $version);
+}
+elseif (isset($opt['e'])) {
+ encrypt($file, $author, $version);
+}
+elseif (isset($opt['d'])) {
+ decrypt($file, $same, $version);
+}
+else {
+ usage("Mode not specified");
+}
+
+
+function decrypt($file, $same, $version) {
+ $path = EncryptedData::decrypt($file, $version);
+ if ($same) {
+ echo "Saved to $path\n";
+ exit(0);
+ }
+ $newPath = EncryptedData::getPlaintextPathForVersion($file, EncryptedData::getNextVersion($file));
+ if (rename($path, $newPath)) {
+ echo "Saved to $newPath\n";
+ exit(0);
+ }
+ echo "Internal error";
+ exit(1);
+}
+function encrypt($file, $author, $version) {
+ if (!$author && !$version) {
+ usage("Author required to encrypt new version");
+ }
+ if (!$version) {
+ $version = EncryptedData::prepNextVersion($file, $author);
+ }
+ if (EncryptedData::encrypt($file, $version)) {
+ echo "Encryption successful.\n";
+ exit(0);
+ }
+ echo "Error encrypting file.\n";
+ exit(1);
+}
+function rotate($file, $author, $bump, $oldVersion) {
+ $newVersion = EncryptedData::rotate($file, $author, $bump, $oldVersion);
+ echo "Rotated '$file' to version $newVersion";
+ if ($bump) {
+ echo " and set as active";
+ }
+ echo ".\n";
+ exit(0);
+}
+
+
+function usage($msg = '') {
+ if ($msg) {
+ echo $msg, "\n\n";
+ }
+
+ echo <<<USAGE
+Usage:
+ crypt [-bv] -a "Name" -r file
+ crypt [-v] -a "Name" -e file
+ crypt [-sv] -d file
+ crypt -h
+
+Modes:
+ -r Rotate: re-encrypt file with new version number
+ -e Encrypt: read plaintext file and write encrypted for execution
+ -d Decrypt: read encrypted file and write plaintext for editing
+
+Options:
+ -h, --help Display this help screen and exit
+ -v number Modify file at version number
+ -a author Specify name of author (required for write operations)
+ -b Bump active version (only applies to -r)
+ -s Save to same version (only applies to -d)
+
+USAGE;
+ exit($msg ? 1 : 0);
+}
72 encrypt.php
View
@@ -1,5 +1,4 @@
<?php
-date_default_timezone_set('America/Los_Angeles');
class Encryption {
const Cipher = MCRYPT_RIJNDAEL_128;
@@ -25,10 +24,10 @@ public static function encrypt($plaintext, $key) {
}
}
-class EncryptedConfig {
+class EncryptedData {
const Suffix = '.plain.php';
const ConfigPath = './files.php';
- const SavePath = './configs/';
+ const SavePath = './files/';
private static $configs = null;
private static $algorithm;
@@ -59,7 +58,7 @@ public static function load($file, &$version = null) {
}
$version = self::$configs[$file]['active'];
}
- $infile = self::SavePath . "$file.$version.php";
+ $infile = self::getPathForVersion($file, $version);
if (!file_exists($infile)) {
throw new Exception("Config file not found ($file:$version)");
}
@@ -74,11 +73,17 @@ public static function load($file, &$version = null) {
}
/**
* Decrypt version and write to disk ($file.$version.plain.php) - used for editing files
+ * @see self::load()
+ * @return string Path on success
+ * @return false on failure
*/
static function decrypt($file, $version = null) {
$data = self::load($file, $version);
- $outfile = self::SavePath . basename($file) . ".$version" . self::Suffix;
- return (bool) file_put_contents($outfile, '<?php return ' . var_export($data, true) . ';');
+ $outfile = self::getPlaintextPathForVersion($file, $version);
+ if (file_put_contents($outfile, '<?php return ' . var_export($data, true) . ';') !== false) {
+ return $outfile;
+ }
+ return false;
}
/**
@@ -91,7 +96,7 @@ static function decrypt($file, $version = null) {
*/
static function encrypt($file, $version) {
self::setup();
- $infile = self::SavePath . basename($file) . ".$version" . self::Suffix;
+ $infile = self::getPlaintextPathForVersion($file, $version);
if (!file_exists($infile)) {
throw new Exception('Could not load raw config');
}
@@ -102,7 +107,7 @@ static function encrypt($file, $version) {
$data = serialize($raw);
$encrypted = Encryption::encrypt($data, $key);
- $outfile = self::SavePath . basename($file) . ".$version.php";
+ $outfile = self::getPathForVersion($file, $version);
if (file_put_contents($outfile, $encrypted) === false) {
return false;
}
@@ -122,19 +127,62 @@ private static function writeConfigs() {
return (bool) file_put_contents(self::ConfigPath, '<?php return ' . var_export(self::$configs, true) . ';');
}
- public static function prepNextVersion($file, $author) {
+ private static function getPathForVersion($file, $version) {
+ return self::SavePath . basename($file) . ".$version.php";
+ }
+
+ public static function getPlaintextPathForVersion($file, $version) {
+ return self::SavePath . basename($file) . ".$version" . self::Suffix;
+ }
+
+ public static function getNextVersion($file) {
self::setup();
if (!isset(self::$configs[$file])) {
- $maxVersion = 1;
+ return 1;
}
else {
- $maxVersion = max(array_keys(self::$configs[$file]['versions'])) + 1;
+ return max(array_keys(self::$configs[$file]['versions'])) + 1;
+ }
+
+ }
+
+ public static function prepNextVersion($file, $author) {
+ if (!$author) {
+ throw new BadMethodCallException("File Author is required");
}
- self::$configs[$file]['versions'][$maxVersion] = array(
+ self::setup();
+ $file = basename($file);
+ $nextVersion = self::getNextVersion($file);
+ self::$configs[$file]['versions'][$nextVersion] = array(
'author' => $author,
'update' => date('c')
);
+ return self::writeConfigs() ? $nextVersion : false;
+ }
+
+ public static function setActiveVersion($file, $version) {
+ $file = basename($file);
+ self::$configs[$file]['active'] = $version;
return self::writeConfigs();
+ } // function setActiveVersion
+
+ public static function rotate($file, $author, $bump, $oldVersion) {
+ $newVersion = self::prepNextVersion($file, $author);
+ // Fixme: this should not need to write decrypted data to disk to bump version
+ $oldPath = self::decrypt($file, $oldVersion);
+ $newPath = self::getPlaintextPathForVersion($file, $newVersion);
+ if (!rename($oldPath, $newPath)) {
+ unlink($oldPath);
+ unlink($newPath);
+ return false;
+ }
+ if (!self::encrypt($file, $newVersion)) {
+ return false;
+ }
+ if ($bump) {
+ EncryptedData::setActiveVersion($file, $newVersion);
+ }
+ return $newVersion;
}
}

No commit comments for this range

Something went wrong with that request. Please try again.