|
- ///////////////////////////////////////////////////////////////////////////////
- //
- // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
- //
- // See accompanying file COPYING.TXT file for licensing details.
- //
- ///////////////////////////////////////////////////////////////////////////////
- #include <cppcms/json.h>
- #include <cppcms/urandom.h>
- #include <cppcms/crypto.h>
- #include <iostream>
- #include <fstream>
-
- #include "tohex.h"
-
- void help()
- {
- std::cerr <<
- "Usage: cppcms_make_key --hmac HMAC [--hmac-file hmac_key_file] [--cbc CBC] \n"
- " [--cbc-file cbc_key_file.txt] [-h] [--output output_file.js]\n"
- " -h: display help\n"
- " HMAC: is one of md5, sha1, sha224, sah256, sha384 or sha512\n"
- " CBC: is one of aes, aes128, aes192, aes256\n"
- "\n"
- " If the options --hmac-file or --cbc-file are not given \n"
- " the keys are created inline withing the json configuration\n"
- " --output output configuration file, default stdout\n"
- "\n"
- "For example:\n"
- " cppcms_make_key --hmac sha1 --hmac-file hmac.txt --output config.js\n"
- " cppcms_make_key --hmac sha1 --cbc aes --hmac-file hmac.txt --cbc-file cbc.txt\n";
-
- }
-
- std::string make_key(int size)
- {
- std::vector<char> key(size,0);
- std::vector<char> res(size*2+1,0);
- cppcms::urandom_device r;
- r.generate(&key[0],size);
- cppcms::impl::tohex(&key[0],size,&res[0]);
- std::string s = &res[0];
- return s;
- }
-
- bool make_entry(cppcms::json::value &val,std::string type,std::string algo,std::string file,int bytes)
- {
- val["session"]["client"][type]=algo;
- std::string key=make_key(bytes);
- if(!file.empty()) {
- std::ofstream f(file.c_str());
- if(!f) {
- std::cerr << "Failed to open file " << file << std::endl;
- return false;
- }
- f << key << std::endl;
- f.close();
- val["session"]["client"][type +"_key_file"]=file;
- }
- else {
- val["session"]["client"][type+"_key"] = key;
- }
- return true;
- }
-
- int main(int argc,char **argv)
- {
- std::string hmac,hmac_file;
- std::string cbc,cbc_file;
- std::string output;
- for(int i=1;i<argc;i++) {
- std::string arg=argv[i];
- if(arg=="-h") {
- help();
- return 0;
- }
- else if(i+1==argc) {
- help();
- return 1;
- }
- i++;
- std::string next = argv[i];
- if(arg=="--hmac")
- hmac = next;
- else if(arg=="--cbc")
- cbc = next;
- else if(arg=="--hmac-file")
- hmac_file = next;
- else if(arg=="--hmac-cbc")
- cbc_file = next;
- else if(arg=="--output")
- output = next;
- else {
- help();
- return 1;
- }
- }
- if(hmac.empty()) {
- help();
- return 1;
- }
-
- cppcms::json::value val;
-
- std::auto_ptr<cppcms::crypto::message_digest> digest = cppcms::crypto::message_digest::create_by_name(hmac);
- if(!digest.get()) {
- std::cerr << "Unsupported HMAC " << hmac << std::endl;
- return 1;
- }
- if(!make_entry(val,"hmac",hmac,hmac_file,digest->digest_size()))
- return 1;
- if(!cbc.empty()) {
- std::auto_ptr<cppcms::crypto::cbc> p = cppcms::crypto::cbc::create(cbc);
- if(!p.get()) {
- std::cerr << "Unsupported CBC " << cbc << std::endl;
- return 1;
- }
- if(!make_entry(val,"cbc",cbc,cbc_file,p->key_size()))
- return 1;
- }
-
- if(output.empty()) {
- val.save(std::cout,cppcms::json::readable);
- }
- else {
- std::ofstream out(output.c_str());
- if(!out) {
- std::cerr << "Failed to create a file " << output << std::endl;
- return 1;
- }
- val.save(out,cppcms::json::readable);
- }
- return 0;
-
- }
|