blob: f4a3a22eba5fcb5ac7820d7092e5c9149e189403 [file] [log] [blame]
/*
* Copyright 2019, Giorgio Zoppi
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
#include <string>
#include <vector>
#include <cstdlib>
#include <boost/date_time.hpp>
#include <amcl/mpin_BN254.h>
#include <bsd/stdlib.h>
#include <amcl/randapi.h>
#include <amcl/pbc_support.h>
#include <amcl/amcl.h>
#include <utils.h>
#include <secret_proxy.h>
namespace milagro
{
namespace secure_store
{
using namespace BN254;
using namespace boost::local_time;
secret_proxy::secret_proxy ()
{
init_state ();
}
secret_proxy::secret_proxy (const std::string & path)
{
init_state ();
}
secret_proxy::~secret_proxy ()
{
KILL_CSPRNG (&_secure_random);
}
void secret_proxy::init_state ()
{
char raw[100];
// FIXME this works only on linux and bsd
arc4random_buf (raw, sizeof raw);
amcl::octet row_octet =
{
0, sizeof (raw), raw};
CREATE_CSPRNG (&_secure_random, &row_octet);
}
/*
* Generate the D-TA master secret -
* @param type type of the store, optional parameter.
*/
amcl::octet secret_proxy::generate_master_secret (store_type type)
{
char secret_chars[PGS_BN254];
amcl::octet secret =
{
0, sizeof (secret_chars), secret_chars};
_master_startTime = boost::posix_time::second_clock::local_time ();
MPIN_RANDOM_GENERATE (&_secure_random, &secret);
return secret;
}
/*
* Generate the client secret for the MPIN Protocol.
* One between the user_id or the hash_pin_id shall be present.
* If juse the user_id is present create the hash from the user_id.
* @param user_id optional value for the user identifier
* @param hash_pin_id optional value for the mpin
* @returns An octect to be used as a secret key
*/
amcl::octet secret_proxy::generate_client_secret (const std::optional <
std::string > &user_id,
const std::optional <
std::string >
&hash_pin_id,
store_type type)
{
char client_id[256];
char idhex[256];
char token[2 * PFS_BN254 + 1];
char hcid[PFS_BN254];
amcl::octet HCID =
{
0, sizeof (hcid), hcid};
amcl::octet CLIENT_ID =
{
0, sizeof (client_id), client_id};
// compute when we shall expire.
auto local = local_sec_clock::local_time (time_zone_ptr ());
local += boost::gregorian::days (DAYS_CLIENT_SECRET_MAX);
_client_expireTime = local.utc_time ();
if (!user_id.has_value () && (!hash_pin_id.value ().size () == 64))
{
throw std::invalid_argument ("Client identifier too long");
}
milagro::utils::make_hash_id (hash_pin_id, user_id, HCID);
// we have here the hash id anyway.
amcl::octet TOKEN =
{
0, sizeof (token), token};
int currentSize = _master_secret.size ();
amcl::octet S =
{
currentSize, currentSize,
const_cast < char *>(_master_secret.c_str ())};
MPIN_GET_CLIENT_SECRET (&S, &HCID, &TOKEN);
return TOKEN;
}
/*
* Get the time permits
* @param mash_
*/
std::vector < std::string >
secret_proxy::get_time_permits (const
std::optional < std::string >
&mhash_pin_id, int count)
{
char permit[2 * PFS_BN254 + 1];
int day = amcl::today ();
std::vector < std::string > tmp;
amcl::octet HCID;
amcl::octet PERMIT =
{
0, sizeof (permit), permit};
int currentSize = _master_secret.size ();
amcl::octet S =
{
currentSize,
currentSize, const_cast < char *>(_master_secret.c_str ())};
milagro::utils::make_hash_id (mhash_pin_id, std::nullopt, HCID);
for (int i = 0; i < count; ++count)
{
MPIN_GET_CLIENT_PERMIT (HASH_TYPE_BN254, day, &S, &HCID, &PERMIT);
// This encoding makes Time permit look random
if (MPIN_ENCODING (&_secure_random, &PERMIT) != 0)
{
throw std::runtime_error ("Encoding permit is not possible");
}
std::string str = milagro::utils::octet_to_string (PERMIT);
tmp.push_back (str);
std::memset (&PERMIT, 0, sizeof (amcl::octet));
}
return tmp;
}
/*
*
*/
boost::posix_time::ptime secret_proxy::client_key_expire ()const
{
return _client_expireTime;
}
/*
*
*/
boost::posix_time::ptime secret_proxy::server_key_start () const
{
return _master_startTime;
}
/*
*
*/
std::optional < amcl::octet > secret_proxy::search_key (int appId)
{
auto value = _key_store.find (appId);
if (value != _key_store.end ())
{
return std::make_optional < amcl::octet > (value->second);
}
return std::nullopt;
}
}
}