aboutsummaryrefslogtreecommitdiffstats
path: root/src/cli/fpe.cpp
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2015-12-19 15:36:40 -0500
committerJack Lloyd <[email protected]>2015-12-19 15:36:40 -0500
commitb48e6fb097c62bb246629ee7a182c57e497e4130 (patch)
tree0cb8ea2d05a89f5e90467f323ae56268d4d3480e /src/cli/fpe.cpp
parentd774a9edc46ffcebb28205a678058f083ea75c28 (diff)
CLI rewrite
The command line tools' origin as a collection of examples and test programs glued together led to some unfortunate problems; lots of hardcoded values, missing parameters, and obsolete crypto. Adds a small library for writing command line programs of the sort needed here (cli.h), which cuts the length of many of the commands in half and makes commands more pleasant to write and extend. Generalizes a lot of the commands also, eg previously only signing/verification with DSA/SHA-1 was included! Removes the fuzzer entry point since that's fairly useless outside of an instrumented build. Removes the in-library API for benchmarking.
Diffstat (limited to 'src/cli/fpe.cpp')
-rw-r--r--src/cli/fpe.cpp153
1 files changed, 0 insertions, 153 deletions
diff --git a/src/cli/fpe.cpp b/src/cli/fpe.cpp
deleted file mode 100644
index 10b3096bf..000000000
--- a/src/cli/fpe.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
-* (C) 2014,2015 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include "apps.h"
-
-#if defined(BOTAN_HAS_FPE_FE1) && defined(BOTAN_HAS_SHA1)
-
-#include <botan/fpe_fe1.h>
-#include <botan/sha160.h>
-
-using namespace Botan;
-
-namespace {
-
-byte luhn_checksum(u64bit cc_number)
- {
- byte sum = 0;
-
- bool alt = false;
- while(cc_number)
- {
- byte digit = cc_number % 10;
- if(alt)
- {
- digit *= 2;
- if(digit > 9)
- digit -= 9;
- }
-
- sum += digit;
-
- cc_number /= 10;
- alt = !alt;
- }
-
- return (sum % 10);
- }
-
-bool luhn_check(u64bit cc_number)
- {
- return (luhn_checksum(cc_number) == 0);
- }
-
-u64bit cc_rank(u64bit cc_number)
- {
- // Remove Luhn checksum
- return cc_number / 10;
- }
-
-u64bit cc_derank(u64bit cc_number)
- {
- for(u32bit i = 0; i != 10; ++i)
- if(luhn_check(cc_number * 10 + i))
- return (cc_number * 10 + i);
- return 0;
- }
-
-/*
-* Use the SHA-1 hash of the account name or ID as a tweak
-*/
-std::vector<byte> sha1(const std::string& acct_name)
- {
- SHA_160 hash;
- hash.update(acct_name);
- return unlock(hash.final());
- }
-
-u64bit encrypt_cc_number(u64bit cc_number,
- const SymmetricKey& key,
- const std::string& acct_name)
- {
- BigInt n = 1000000000000000;
-
- u64bit cc_ranked = cc_rank(cc_number);
-
- BigInt c = FPE::fe1_encrypt(n, cc_ranked, key, sha1(acct_name));
-
- if(c.bits() > 50)
- throw std::runtime_error("FPE produced a number too large");
-
- u64bit enc_cc = 0;
- for(u32bit i = 0; i != 7; ++i)
- enc_cc = (enc_cc << 8) | c.byte_at(6-i);
- return cc_derank(enc_cc);
- }
-
-u64bit decrypt_cc_number(u64bit enc_cc,
- const SymmetricKey& key,
- const std::string& acct_name)
- {
- BigInt n = 1000000000000000;
-
- u64bit cc_ranked = cc_rank(enc_cc);
-
- BigInt c = FPE::fe1_decrypt(n, cc_ranked, key, sha1(acct_name));
-
- if(c.bits() > 50)
- throw std::runtime_error("FPE produced a number too large");
-
- u64bit dec_cc = 0;
- for(u32bit i = 0; i != 7; ++i)
- dec_cc = (dec_cc << 8) | c.byte_at(6-i);
- return cc_derank(dec_cc);
- }
-
-int fpe(const std::vector<std::string> &args)
- {
- if(args.size() != 4)
- {
- std::cout << "Usage: " << args[0] << " cc-number acct-name passwd" << std::endl;
- return 1;
- }
-
- u64bit cc_number = atoll(args[1].c_str());
- std::string acct_name = args[2];
- std::string passwd = args[3];
-
- std::cout << "Input was: " << cc_number << ' '
- << luhn_check(cc_number) << std::endl;
-
- /*
- * In practice something like PBKDF2 with a salt and high iteration
- * count would be a good idea.
- */
- SymmetricKey key(sha1(passwd));
-
- u64bit enc_cc = encrypt_cc_number(cc_number, key, acct_name);
-
- std::cout << "Encrypted: " << enc_cc
- << ' ' << luhn_check(enc_cc) << std::endl;
-
- u64bit dec_cc = decrypt_cc_number(enc_cc, key, acct_name);
-
- std::cout << "Decrypted: " << dec_cc
- << ' ' << luhn_check(dec_cc) << std::endl;
-
- if(dec_cc != cc_number)
- {
- std::cout << "Something went wrong :( Bad CC checksum?" << std::endl;
- return 2;
- }
-
- return 0;
- }
-
-REGISTER_APP(fpe);
-
-}
-
-#endif // BOTAN_HAS_FPE_FE1 && BOTAN_HAS_SHA1