diff options
author | Timo Weingärtner <timo@tiwe.de> | 2013-09-01 12:32:55 +0200 |
---|---|---|
committer | Timo Weingärtner <timo@tiwe.de> | 2013-09-01 12:32:55 +0200 |
commit | bd8e837efbc00eb49607ca493287d307ea47697b (patch) | |
tree | 137e639e3122c9d16dd52979a34c30c08b46b33b | |
parent | 84ab40ff5fc9d19066c579fce94cd6c24d1d3b90 (diff) | |
download | ssh-agent-filter-bd8e837efbc00eb49607ca493287d307ea47697b.tar.gz |
move mpint/mpz conversion into separate file
these functions need linking against libgmp
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | rfc4251.h | 37 | ||||
-rw-r--r-- | rfc4251_gmp.C | 61 |
3 files changed, 63 insertions, 37 deletions
@@ -33,6 +33,8 @@ ssh-agent-filter: ssh-agent-filter.o ssh-agent-filter.o: ssh-agent-filter.C rfc4251.h ssh-agent.h version.h +rfc4251_gmp.o: rfc4251_gmp.C rfc4251.h + version.h: test ! -d .git || git describe | sed 's/^.*$$/#define SSH_AGENT_FILTER_VERSION "ssh-agent-filter \0"/' > $@ @@ -176,32 +176,6 @@ rfc4251string::rfc4251string (std::vector<std::string> const & v) { } } -rfc4251string::rfc4251string (mpz_srcptr x) { - if (mpz_sgn(x) == 0) - return; - - auto const import_positive = [] (mpz_srcptr x, std::vector<char> & value) { - size_t bits{mpz_sizeinbase(x, 2)}; - size_t bytes{(bits + 7) / 8}; - size_t extrabyte{(bits % 8) == 0}; // need extra byte if MSB is 1 to keep it non-negative - if (bytes + extrabyte > std::numeric_limits<uint32_t>::max()) - throw std::length_error{"32-bit limit for rfc4251string exceeded"}; - value.resize(bytes + extrabyte); - value[0] = 0; - mpz_export(value.data() + extrabyte, nullptr, 1, 1, 1, 0, x); - }; - if (mpz_sgn(x) == 1) - import_positive(x, value); - else { - // handle two's complement: add 1, invert all bits - mpz_class tmp{x}; - tmp += 1; - import_positive(tmp.get_mpz_t(), value); - for (auto & i : value) - i ^= 0xff; - } -} - rfc4251string::operator std::vector<std::string> () const { std::vector<std::string> ret; auto name_start = value.begin(); @@ -219,17 +193,6 @@ rfc4251string::operator std::vector<std::string> () const { return ret; } -rfc4251string::operator mpz_class () const { - mpz_class ret; - mpz_import(ret.get_mpz_t(), value.size(), 1, 1, 1, 0, value.data()); - if (mpz_sizeinbase(ret.get_mpz_t(), 2) == value.size() * 8) { // negative - mpz_com(ret.get_mpz_t(), ret.get_mpz_t()); - ret += 1; - mpz_neg(ret.get_mpz_t(), ret.get_mpz_t()); - } - return ret; -} - inline std::istream & operator>> (std::istream & is, rfc4251string & s) { s.value.clear(); rfc4251uint32 len; diff --git a/rfc4251_gmp.C b/rfc4251_gmp.C new file mode 100644 index 0000000..d3a664e --- /dev/null +++ b/rfc4251_gmp.C @@ -0,0 +1,61 @@ +/* + * rfc4251_gmp.C -- implements mpint/gmp conversions for rfc4251string + * + * these functions need linking against libgmp + * + * Copyright (C) 2013 Timo Weingärtner <timo@tiwe.de> + * + * This file is part of ssh-agent-filter. + * + * ssh-agent-filter is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ssh-agent-filter 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ssh-agent-filter. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "rfc4251.h" + +rfc4251string::rfc4251string (mpz_srcptr x) { + if (mpz_sgn(x) == 0) + return; + + auto const import_positive = [] (mpz_srcptr x, std::vector<char> & value) { + size_t bits{mpz_sizeinbase(x, 2)}; + size_t bytes{(bits + 7) / 8}; + size_t extrabyte{(bits % 8) == 0}; // need extra byte if MSB is 1 to keep it non-negative + if (bytes + extrabyte > std::numeric_limits<uint32_t>::max()) + throw std::length_error{"32-bit limit for rfc4251string exceeded"}; + value.resize(bytes + extrabyte); + value[0] = 0; + mpz_export(value.data() + extrabyte, nullptr, 1, 1, 1, 0, x); + }; + if (mpz_sgn(x) == 1) + import_positive(x, value); + else { + // handle two's complement: add 1, invert all bits + mpz_class tmp{x}; + tmp += 1; + import_positive(tmp.get_mpz_t(), value); + for (auto & i : value) + i ^= 0xff; + } +} + +rfc4251string::operator mpz_class () const { + mpz_class ret; + mpz_import(ret.get_mpz_t(), value.size(), 1, 1, 1, 0, value.data()); + if (mpz_sizeinbase(ret.get_mpz_t(), 2) == value.size() * 8) { // negative + mpz_com(ret.get_mpz_t(), ret.get_mpz_t()); + ret += 1; + mpz_neg(ret.get_mpz_t(), ret.get_mpz_t()); + } + return ret; +} |