diff --git a/src/seclock.cpp b/src/seclock.cpp new file mode 100644 index 0000000..44819b4 --- /dev/null +++ b/src/seclock.cpp @@ -0,0 +1,116 @@ + +/* + * This file is part of Codecrypt. + * + * Copyright (C) 2013-2017 Mirek Kratochvil + * + * Codecrypt is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Codecrypt is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Codecrypt. If not, see . + */ + +#include "seclock.h" + +#include "pwrng.h" +#include "iohelpers.h" + +#include +#include + +#include + +#define LOCKED_PREFIX "ccr_lock" +#define LOCKED_PREFIX_LEN 8 + +bool looks_like_locked_secret (const std::string&s) +{ + std::string prefix = LOCKED_PREFIX; + /* + * unlocked version of this thing is always some kind of sencode, which + * will never start with 'ccr_lock'. Abusing it right here. + */ + return s.length() > LOCKED_PREFIX_LEN + && s.substr (0, LOCKED_PREFIX_LEN) == LOCKED_PREFIX; +} + +bool load_lock_secret (symkey&sk, + std::string withlock, + const std::string &reason, + const std::string &secret_type, + bool for_locking) +{ + if (withlock == "") withlock = "@"; //default for password + if (withlock[0] == '@') { + //ask the user and generate a symmetric key + pw_rng r; + r.init(); + if (!r.seed_from_user_password + ( (for_locking ? "locking " : "unlocking ") + reason, + "CCR_" + secret_type + "_PASSWORD", + for_locking)) + return false; + + withlock.erase (0, 1); //delete the @ + if (withlock.empty()) { + std::string alg = "CCR_" + secret_type + "_ALGORITHM"; + const char* algorithm = getenv (alg.c_str()); + if (algorithm) withlock = algorithm; + else withlock = "CHACHA20,CUBE512,SHORTBLOCK"; + //TODO make sure this is synced with synonyms + } + return sk.create (withlock, r); + } else { + return sk.load (withlock, "", false, false); + } +} + +bool lock_secret (const std::string &secret, std::string &locked, + const std::string &withlock, + const std::string &reason, + const std::string &secret_type, + prng&rng) +{ + + symkey sk; + if (!load_lock_secret (sk, withlock, reason, secret_type, true)) + return false; + + std::istringstream i (secret); + std::ostringstream o; + o << LOCKED_PREFIX; + bool ret = sk.encrypt (i, o, rng); + locked = o.str(); + return ret; +} + +bool unlock_secret (const std::string &locked, std::string &secret, + const std::string &withlock, + const std::string &reason, + const std::string &secret_type) +{ + symkey sk; + if (!looks_like_locked_secret (locked)) { + err ("seclock: malformed locked secret"); + return false; + } + + if (!load_lock_secret (sk, withlock, reason, secret_type, false)) + return false; + + + std::istringstream i (locked); + i.ignore (LOCKED_PREFIX_LEN); + std::ostringstream o; + bool ret = !sk.decrypt (i, o); //returns int! + secret = o.str(); + return ret; +} diff --git a/src/seclock.h b/src/seclock.h new file mode 100644 index 0000000..d9b57df --- /dev/null +++ b/src/seclock.h @@ -0,0 +1,45 @@ + +/* + * This file is part of Codecrypt. + * + * Copyright (C) 2013-2016 Mirek Kratochvil + * + * Codecrypt is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or (at + * your option) any later version. + * + * Codecrypt is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Codecrypt. If not, see . + */ + +#ifndef _ccr_seclock_h_ +#define _ccr_seclock_h_ + +#include + +#include "prng.h" +#include "symkey.h" + +bool looks_like_locked_secret (const std::string&); +bool load_lock_secret (symkey&sk, + std::string withlock, + const std::string &reason, + const std::string &secret_type, + bool for_locking); +bool lock_secret (const std::string&secret, std::string&locked, + const std::string&withlock, + const std::string&reason, + const std::string&secret_type, + prng&rng); +bool unlock_secret (const std::string&locked, std::string&secret, + const std::string&withlock, + const std::string&reason, + const std::string&secret_type); + +#endif