aboutsummaryrefslogtreecommitdiffstats
path: root/doc/examples/read_ssh.cpp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2009-11-20 15:36:10 +0000
committerlloyd <[email protected]>2009-11-20 15:36:10 +0000
commit80726182fb8ea0ba39be3d145a183972a004e31d (patch)
tree3ae2e7b3a22ae4503bde1501041789364766fc8f /doc/examples/read_ssh.cpp
parent461e0b52e176ec7e4ebb5d0eaa0e0c53742066c9 (diff)
Add an example of reading SSH2 public keys
Diffstat (limited to 'doc/examples/read_ssh.cpp')
-rw-r--r--doc/examples/read_ssh.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/doc/examples/read_ssh.cpp b/doc/examples/read_ssh.cpp
new file mode 100644
index 000000000..a88306caa
--- /dev/null
+++ b/doc/examples/read_ssh.cpp
@@ -0,0 +1,119 @@
+/*
+* Example of reading SSH2 format public keys (see RFC 4716)
+*/
+
+#include <fstream>
+#include <botan/x509_key.h>
+#include <botan/filters.h>
+#include <botan/loadstor.h>
+#include <botan/rsa.h>
+#include <botan/dsa.h>
+
+using namespace Botan;
+
+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);
+
+ SecureVector<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 0;
+
+ 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 0;
+
+ 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 0;
+ }
+
+#include <botan/init.h>
+#include <iostream>
+
+int main()
+ {
+ LibraryInitializer init;
+
+ Public_Key* key = read_ssh_pubkey("dsa.ssh");
+
+ if(key == 0)
+ {
+ std::cout << "Failed\n";
+ return 1;
+ }
+
+ std::cout << X509::PEM_encode(*key);
+
+ return 0;
+ }