aboutsummaryrefslogtreecommitdiffstats
path: root/src/apps/read_ssh.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2014-01-01 23:32:24 +0000
committerlloyd <[email protected]>2014-01-01 23:32:24 +0000
commit7323f3ff83ff2199b1090f9d5f729b08ccac3151 (patch)
tree84edcf72e8837ac328aae505f5059c95f4e459a5 /src/apps/read_ssh.cpp
parent0c7008498790caea563ed3601df1943f8f7b6269 (diff)
Move base64, bzip, ca, and tls examples
Diffstat (limited to 'src/apps/read_ssh.cpp')
-rw-r--r--src/apps/read_ssh.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/apps/read_ssh.cpp b/src/apps/read_ssh.cpp
new file mode 100644
index 000000000..ce72fa064
--- /dev/null
+++ b/src/apps/read_ssh.cpp
@@ -0,0 +1,134 @@
+/*
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+/*
+* Example of reading SSH2 format public keys (see RFC 4716)
+*/
+
+#include "apps.h"
+
+#include <botan/x509_key.h>
+#include <botan/filters.h>
+#include <botan/loadstor.h>
+#include <botan/rsa.h>
+#include <botan/dsa.h>
+#include <fstream>
+#include <memory>
+
+using namespace Botan;
+
+namespace {
+
+u32bit read_u32bit(Pipe& pipe)
+ {
+ byte out[4] = { 0 };
+ pipe.read(out, 4);
+ u32bit len = load_be<u32bit>(out, 0);
+ if(len > 10000)
+ throw Decoding_Error("Huge size in read_u32bit, something went wrong");
+ return len;
+ }
+
+std::string read_string(Pipe& pipe)
+ {
+ u32bit len = read_u32bit(pipe);
+
+ std::string out(len, 'X');
+ pipe.read(reinterpret_cast<byte*>(&out[0]), len);
+ return out;
+ }
+
+BigInt read_bigint(Pipe& pipe)
+ {
+ u32bit len = read_u32bit(pipe);
+
+ secure_vector<byte> buf(len);
+ pipe.read(&buf[0], len);
+ return BigInt::decode(buf);
+ }
+
+Public_Key* read_ssh_pubkey(const std::string& file)
+ {
+ std::ifstream in(file.c_str());
+
+ const std::string ssh_header = "---- BEGIN SSH2 PUBLIC KEY ----";
+ const std::string ssh_trailer = "---- END SSH2 PUBLIC KEY ----";
+
+ std::string hex_bits;
+
+ std::string line;
+ std::getline(in, line);
+
+ if(line != ssh_header)
+ return nullptr;
+
+ while(in.good())
+ {
+ std::getline(in, line);
+
+ if(line.find("Comment: ") == 0)
+ {
+ while(line[line.size()-1] == '\\')
+ std::getline(in, line);
+ std::getline(in, line);
+ }
+
+ if(line == ssh_trailer)
+ break;
+
+ hex_bits += line;
+ }
+
+ Pipe pipe(new Base64_Decoder);
+ pipe.process_msg(hex_bits);
+
+ std::string key_type = read_string(pipe);
+
+ if(key_type != "ssh-rsa" && key_type != "ssh-dss")
+ return nullptr;
+
+ if(key_type == "ssh-rsa")
+ {
+ BigInt e = read_bigint(pipe);
+ BigInt n = read_bigint(pipe);
+ return new RSA_PublicKey(n, e);
+ }
+ else if(key_type == "ssh-dss")
+ {
+ BigInt p = read_bigint(pipe);
+ BigInt q = read_bigint(pipe);
+ BigInt g = read_bigint(pipe);
+ BigInt y = read_bigint(pipe);
+
+ return new DSA_PublicKey(DL_Group(p, q, g), y);
+ }
+
+ return nullptr;
+ }
+
+}
+
+int read_ssh(int argc, char* argv[])
+ {
+ if(argc != 2)
+ {
+ std::cout << "Usage: " << argv[0] << " file";
+ return 1;
+ }
+
+ const std::string filename = argv[1];
+ std::unique_ptr<Public_Key> key(read_ssh_pubkey(filename));
+
+ if(key == 0)
+ {
+ std::cout << "Failed to read" << filename << "\n";
+ return 1;
+ }
+
+ std::cout << X509::PEM_encode(*key);
+
+ return 0;
+ }