00001
00002
00003
00004
00005
00006
00007
00008 #include <botan/pem.h>
00009 #include <botan/filters.h>
00010 #include <botan/parsing.h>
00011
00012 namespace Botan {
00013
00014 namespace PEM_Code {
00015
00016
00017
00018
00019 std::string encode(const byte der[], u32bit length, const std::string& label,
00020 u32bit width)
00021 {
00022 const std::string PEM_HEADER = "-----BEGIN " + label + "-----\n";
00023 const std::string PEM_TRAILER = "-----END " + label + "-----\n";
00024
00025 Pipe pipe(new Base64_Encoder(true, width));
00026 pipe.process_msg(der, length);
00027 return (PEM_HEADER + pipe.read_all_as_string() + PEM_TRAILER);
00028 }
00029
00030
00031
00032
00033 std::string encode(const MemoryRegion<byte>& data, const std::string& label,
00034 u32bit width)
00035 {
00036 return encode(data, data.size(), label, width);
00037 }
00038
00039
00040
00041
00042 SecureVector<byte> decode_check_label(DataSource& source,
00043 const std::string& label_want)
00044 {
00045 std::string label_got;
00046 SecureVector<byte> ber = decode(source, label_got);
00047 if(label_got != label_want)
00048 throw Decoding_Error("PEM: Label mismatch, wanted " + label_want +
00049 ", got " + label_got);
00050 return ber;
00051 }
00052
00053
00054
00055
00056 SecureVector<byte> decode(DataSource& source, std::string& label)
00057 {
00058 const u32bit RANDOM_CHAR_LIMIT = 8;
00059
00060 const std::string PEM_HEADER1 = "-----BEGIN ";
00061 const std::string PEM_HEADER2 = "-----";
00062 u32bit position = 0;
00063
00064 while(position != PEM_HEADER1.length())
00065 {
00066 byte b;
00067 if(!source.read_byte(b))
00068 throw Decoding_Error("PEM: No PEM header found");
00069 if(b == PEM_HEADER1[position])
00070 ++position;
00071 else if(position >= RANDOM_CHAR_LIMIT)
00072 throw Decoding_Error("PEM: Malformed PEM header");
00073 else
00074 position = 0;
00075 }
00076 position = 0;
00077 while(position != PEM_HEADER2.length())
00078 {
00079 byte b;
00080 if(!source.read_byte(b))
00081 throw Decoding_Error("PEM: No PEM header found");
00082 if(b == PEM_HEADER2[position])
00083 ++position;
00084 else if(position)
00085 throw Decoding_Error("PEM: Malformed PEM header");
00086
00087 if(position == 0)
00088 label += static_cast<char>(b);
00089 }
00090
00091 Pipe base64(new Base64_Decoder);
00092 base64.start_msg();
00093
00094 const std::string PEM_TRAILER = "-----END " + label + "-----";
00095 position = 0;
00096 while(position != PEM_TRAILER.length())
00097 {
00098 byte b;
00099 if(!source.read_byte(b))
00100 throw Decoding_Error("PEM: No PEM trailer found");
00101 if(b == PEM_TRAILER[position])
00102 ++position;
00103 else if(position)
00104 throw Decoding_Error("PEM: Malformed PEM trailer");
00105
00106 if(position == 0)
00107 base64.write(b);
00108 }
00109 base64.end_msg();
00110 return base64.read_all();
00111 }
00112
00113
00114
00115
00116 bool matches(DataSource& source, const std::string& extra,
00117 u32bit search_range)
00118 {
00119 const std::string PEM_HEADER = "-----BEGIN " + extra;
00120
00121 SecureVector<byte> search_buf(search_range);
00122 u32bit got = source.peek(search_buf, search_buf.size(), 0);
00123
00124 if(got < PEM_HEADER.length())
00125 return false;
00126
00127 u32bit index = 0;
00128
00129 for(u32bit j = 0; j != got; ++j)
00130 {
00131 if(search_buf[j] == PEM_HEADER[index])
00132 ++index;
00133 else
00134 index = 0;
00135 if(index == PEM_HEADER.size())
00136 return true;
00137 }
00138 return false;
00139 }
00140
00141 }
00142
00143 }