diff options
author | lloyd <[email protected]> | 2008-09-28 22:42:40 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2008-09-28 22:42:40 +0000 |
commit | 60fac1a24709d8854489eaf27c2f5b32de56dd6f (patch) | |
tree | d30ece3f0e1ae14e78520bde3c5b0aaf7b8d505f /src/codec | |
parent | c32a8e6c7ecf97fc9423e6a967ce3d98b0689404 (diff) |
Put OpenPGP codec routines into codec/openpgp module
Diffstat (limited to 'src/codec')
-rw-r--r-- | src/codec/openpgp/modinfo.txt | 8 | ||||
-rw-r--r-- | src/codec/openpgp/openpgp.cpp | 194 | ||||
-rw-r--r-- | src/codec/openpgp/openpgp.h | 32 |
3 files changed, 234 insertions, 0 deletions
diff --git a/src/codec/openpgp/modinfo.txt b/src/codec/openpgp/modinfo.txt new file mode 100644 index 000000000..32a18fa4f --- /dev/null +++ b/src/codec/openpgp/modinfo.txt @@ -0,0 +1,8 @@ +realname "OpenPGP Codec" + +define OPENPGP_CODEC + +<add> +openpgp.cpp +openpgp.h +</add> diff --git a/src/codec/openpgp/openpgp.cpp b/src/codec/openpgp/openpgp.cpp new file mode 100644 index 000000000..2a84b037e --- /dev/null +++ b/src/codec/openpgp/openpgp.cpp @@ -0,0 +1,194 @@ +/************************************************* +* OpenPGP Source File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#include <botan/openpgp.h> +#include <botan/filters.h> +#include <botan/charset.h> + +namespace Botan { + +namespace OpenPGP { + +/************************************************* +* OpenPGP Base64 encoding * +*************************************************/ +std::string encode(const byte input[], u32bit 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 u32bit 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("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 encode(const byte input[], u32bit length, + const std::string& type) + { + std::map<std::string, std::string> empty; + return encode(input, length, type, empty); + } + +/************************************************* +* OpenPGP Base64 decoding * +*************************************************/ +SecureVector<byte> decode(DataSource& source, std::string& label, + std::map<std::string, std::string>& headers) + { + const u32bit RANDOM_CHAR_LIMIT = 5; + + const std::string PGP_HEADER1 = "-----BEGIN PGP "; + const std::string PGP_HEADER2 = "-----"; + u32bit 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(u32bit 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(0, + new Chain(new Hash_Filter("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 * +*************************************************/ +SecureVector<byte> decode(DataSource& source, std::string& label) + { + std::map<std::string, std::string> ignored; + return decode(source, label, ignored); + } + +} + +} + diff --git a/src/codec/openpgp/openpgp.h b/src/codec/openpgp/openpgp.h new file mode 100644 index 000000000..1a078a630 --- /dev/null +++ b/src/codec/openpgp/openpgp.h @@ -0,0 +1,32 @@ +/************************************************* +* OpenPGP Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_OPENPGP_H__ +#define BOTAN_OPENPGP_H__ + +#include <botan/data_src.h> +#include <string> +#include <map> + +namespace Botan { + +namespace OpenPGP { + +/************************************************* +* OpenPGP Base64 encoding/decoding * +*************************************************/ +BOTAN_DLL std::string encode(const byte[], u32bit, const std::string&, + const std::map<std::string, std::string>&); +BOTAN_DLL SecureVector<byte> decode(DataSource&, std::string&, + std::map<std::string, std::string>&); + +BOTAN_DLL std::string encode(const byte[], u32bit, const std::string&); +BOTAN_DLL SecureVector<byte> decode(DataSource&, std::string&); + +} + +} + +#endif |