aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/misc/openpgp
diff options
context:
space:
mode:
authorlloyd <[email protected]>2015-02-05 07:44:25 +0000
committerlloyd <[email protected]>2015-02-05 07:44:25 +0000
commitcb0f83ae63c4555cbdd0607e3a5f6e9260c0d19c (patch)
tree4981027a25fa8074177b97c3a3ca7431f3337deb /src/lib/misc/openpgp
parent2c14faf0aa1cfe0f8d70af1938dcad5b4d6d3b59 (diff)
Clean up root dir, remove some unneeded dependencies
Diffstat (limited to 'src/lib/misc/openpgp')
-rw-r--r--src/lib/misc/openpgp/info.txt8
-rw-r--r--src/lib/misc/openpgp/openpgp.cpp196
-rw-r--r--src/lib/misc/openpgp/openpgp.h61
3 files changed, 265 insertions, 0 deletions
diff --git a/src/lib/misc/openpgp/info.txt b/src/lib/misc/openpgp/info.txt
new file mode 100644
index 000000000..72467ee72
--- /dev/null
+++ b/src/lib/misc/openpgp/info.txt
@@ -0,0 +1,8 @@
+define OPENPGP_CODEC 20131128
+
+load_on auto
+
+<requires>
+crc24
+filters
+</requires>
diff --git a/src/lib/misc/openpgp/openpgp.cpp b/src/lib/misc/openpgp/openpgp.cpp
new file mode 100644
index 000000000..3a464d906
--- /dev/null
+++ b/src/lib/misc/openpgp/openpgp.cpp
@@ -0,0 +1,196 @@
+/*
+* OpenPGP Codec
+* (C) 1999-2007 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/openpgp.h>
+#include <botan/filters.h>
+#include <botan/basefilt.h>
+#include <botan/charset.h>
+#include <botan/crc24.h>
+
+namespace Botan {
+
+/*
+* OpenPGP Base64 encoding
+*/
+std::string PGP_encode(
+ const byte input[], size_t length,
+ const std::string& label,
+ const std::map<std::string, std::string>& headers)
+ {
+ const std::string PGP_HEADER = "-----BEGIN PGP " + label + "-----\n";
+ const std::string PGP_TRAILER = "-----END PGP " + label + "-----\n";
+ const size_t PGP_WIDTH = 64;
+
+ std::string pgp_encoded = PGP_HEADER;
+
+ if(headers.find("Version") != headers.end())
+ pgp_encoded += "Version: " + headers.find("Version")->second + '\n';
+
+ std::map<std::string, std::string>::const_iterator i = headers.begin();
+ while(i != headers.end())
+ {
+ if(i->first != "Version")
+ pgp_encoded += i->first + ": " + i->second + '\n';
+ ++i;
+ }
+ pgp_encoded += '\n';
+
+ Pipe pipe(new Fork(
+ new Base64_Encoder(true, PGP_WIDTH),
+ new Chain(new Hash_Filter(new CRC24), new Base64_Encoder)
+ )
+ );
+
+ pipe.process_msg(input, length);
+
+ pgp_encoded += pipe.read_all_as_string(0);
+ pgp_encoded += '=' + pipe.read_all_as_string(1) + '\n';
+ pgp_encoded += PGP_TRAILER;
+
+ return pgp_encoded;
+ }
+
+/*
+* OpenPGP Base64 encoding
+*/
+std::string PGP_encode(const byte input[], size_t length,
+ const std::string& type)
+ {
+ std::map<std::string, std::string> empty;
+ return PGP_encode(input, length, type, empty);
+ }
+
+/*
+* OpenPGP Base64 decoding
+*/
+secure_vector<byte> PGP_decode(DataSource& source,
+ std::string& label,
+ std::map<std::string, std::string>& headers)
+ {
+ const size_t RANDOM_CHAR_LIMIT = 5;
+
+ const std::string PGP_HEADER1 = "-----BEGIN PGP ";
+ const std::string PGP_HEADER2 = "-----";
+ size_t position = 0;
+
+ while(position != PGP_HEADER1.length())
+ {
+ byte b;
+ if(!source.read_byte(b))
+ throw Decoding_Error("PGP: No PGP header found");
+ if(b == PGP_HEADER1[position])
+ ++position;
+ else if(position >= RANDOM_CHAR_LIMIT)
+ throw Decoding_Error("PGP: Malformed PGP header");
+ else
+ position = 0;
+ }
+ position = 0;
+ while(position != PGP_HEADER2.length())
+ {
+ byte b;
+ if(!source.read_byte(b))
+ throw Decoding_Error("PGP: No PGP header found");
+ if(b == PGP_HEADER2[position])
+ ++position;
+ else if(position)
+ throw Decoding_Error("PGP: Malformed PGP header");
+
+ if(position == 0)
+ label += static_cast<char>(b);
+ }
+
+ headers.clear();
+ bool end_of_headers = false;
+ while(!end_of_headers)
+ {
+ std::string this_header;
+ byte b = 0;
+ while(b != '\n')
+ {
+ if(!source.read_byte(b))
+ throw Decoding_Error("PGP: Bad armor header");
+ if(b != '\n')
+ this_header += static_cast<char>(b);
+ }
+
+ end_of_headers = true;
+ for(size_t j = 0; j != this_header.length(); ++j)
+ if(!Charset::is_space(this_header[j]))
+ end_of_headers = false;
+
+ if(!end_of_headers)
+ {
+ std::string::size_type pos = this_header.find(": ");
+ if(pos == std::string::npos)
+ throw Decoding_Error("OpenPGP: Bad headers");
+
+ std::string key = this_header.substr(0, pos);
+ std::string value = this_header.substr(pos + 2, std::string::npos);
+ headers[key] = value;
+ }
+ }
+
+ Pipe base64(new Base64_Decoder,
+ new Fork(nullptr,
+ new Chain(new Hash_Filter(new CRC24),
+ new Base64_Encoder)
+ )
+ );
+ base64.start_msg();
+
+ const std::string PGP_TRAILER = "-----END PGP " + label + "-----";
+ position = 0;
+ bool newline_seen = 0;
+ std::string crc;
+ while(position != PGP_TRAILER.length())
+ {
+ byte b;
+ if(!source.read_byte(b))
+ throw Decoding_Error("PGP: No PGP trailer found");
+ if(b == PGP_TRAILER[position])
+ ++position;
+ else if(position)
+ throw Decoding_Error("PGP: Malformed PGP trailer");
+
+ if(b == '=' && newline_seen)
+ {
+ while(b != '\n')
+ {
+ if(!source.read_byte(b))
+ throw Decoding_Error("PGP: Bad CRC tail");
+ if(b != '\n')
+ crc += static_cast<char>(b);
+ }
+ }
+ else if(b == '\n')
+ newline_seen = true;
+ else if(position == 0)
+ {
+ base64.write(b);
+ newline_seen = false;
+ }
+ }
+ base64.end_msg();
+
+ if(crc != "" && crc != base64.read_all_as_string(1))
+ throw Decoding_Error("PGP: Corrupt CRC");
+
+ return base64.read_all();
+ }
+
+/*
+* OpenPGP Base64 decoding
+*/
+secure_vector<byte> PGP_decode(DataSource& source, std::string& label)
+ {
+ std::map<std::string, std::string> ignored;
+ return PGP_decode(source, label, ignored);
+ }
+
+}
+
diff --git a/src/lib/misc/openpgp/openpgp.h b/src/lib/misc/openpgp/openpgp.h
new file mode 100644
index 000000000..538b31342
--- /dev/null
+++ b/src/lib/misc/openpgp/openpgp.h
@@ -0,0 +1,61 @@
+/*
+* OpenPGP Codec
+* (C) 1999-2007 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_OPENPGP_CODEC_H__
+#define BOTAN_OPENPGP_CODEC_H__
+
+#include <botan/data_src.h>
+#include <string>
+#include <map>
+
+namespace Botan {
+
+/**
+* @param input the input data
+* @param length length of input in bytes
+* @param label the human-readable label
+* @param headers a set of key/value pairs included in the header
+*/
+BOTAN_DLL std::string PGP_encode(
+ const byte input[],
+ size_t length,
+ const std::string& label,
+ const std::map<std::string, std::string>& headers);
+
+/**
+* @param input the input data
+* @param length length of input in bytes
+* @param label the human-readable label
+*/
+BOTAN_DLL std::string PGP_encode(
+ const byte input[],
+ size_t length,
+ const std::string& label);
+
+/**
+* @param source the input source
+* @param label is set to the human-readable label
+* @param headers is set to any headers
+* @return decoded output as raw binary
+*/
+BOTAN_DLL secure_vector<byte> PGP_decode(
+ DataSource& source,
+ std::string& label,
+ std::map<std::string, std::string>& headers);
+
+/**
+* @param source the input source
+* @param label is set to the human-readable label
+* @return decoded output as raw binary
+*/
+BOTAN_DLL secure_vector<byte> PGP_decode(
+ DataSource& source,
+ std::string& label);
+
+}
+
+#endif