summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Weingärtner <timo@tiwe.de>2013-09-01 12:32:55 +0200
committerTimo Weingärtner <timo@tiwe.de>2013-09-01 12:32:55 +0200
commitbd8e837efbc00eb49607ca493287d307ea47697b (patch)
tree137e639e3122c9d16dd52979a34c30c08b46b33b
parent84ab40ff5fc9d19066c579fce94cd6c24d1d3b90 (diff)
downloadssh-agent-filter-bd8e837efbc00eb49607ca493287d307ea47697b.tar.gz
move mpint/mpz conversion into separate file
these functions need linking against libgmp
-rw-r--r--Makefile2
-rw-r--r--rfc4251.h37
-rw-r--r--rfc4251_gmp.C61
3 files changed, 63 insertions, 37 deletions
diff --git a/Makefile b/Makefile
index 3747a03..644b055 100644
--- a/Makefile
+++ b/Makefile
@@ -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"/' > $@
diff --git a/rfc4251.h b/rfc4251.h
index 7f68407..80723a9 100644
--- a/rfc4251.h
+++ b/rfc4251.h
@@ -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;
+}