monotone

monotone Mtn Source Tree

Root/botan/pem.cpp

1/*************************************************
2* PEM Encoding/Decoding Source File *
3* (C) 1999-2005 The Botan Project *
4*************************************************/
5
6#include <botan/pem.h>
7#include <botan/conf.h>
8#include <botan/filters.h>
9#include <botan/parsing.h>
10
11namespace Botan {
12
13namespace PEM_Code {
14
15/*************************************************
16* PEM encode BER/DER-encoded objects *
17*************************************************/
18std::string encode(const byte der[], u32bit length, const std::string& label)
19 {
20 const u32bit PEM_WIDTH = Config::get_u32bit("pem/width");
21
22 if(PEM_WIDTH < 50 || PEM_WIDTH > 76)
23 throw Encoding_Error("PEM: Invalid line width " + to_string(PEM_WIDTH));
24
25 const std::string PEM_HEADER = "-----BEGIN " + label + "-----\n";
26 const std::string PEM_TRAILER = "-----END " + label + "-----\n";
27
28 Pipe pipe(new Base64_Encoder(true, PEM_WIDTH));
29 pipe.process_msg(der, length);
30 return (PEM_HEADER + pipe.read_all_as_string() + PEM_TRAILER);
31 }
32
33/*************************************************
34* PEM encode BER/DER-encoded objects *
35*************************************************/
36std::string encode(const MemoryRegion<byte>& data, const std::string& label)
37 {
38 return encode(data, data.size(), label);
39 }
40
41/*************************************************
42* Decode PEM down to raw BER/DER *
43*************************************************/
44SecureVector<byte> decode_check_label(DataSource& source,
45 const std::string& label_want)
46 {
47 std::string label_got;
48 SecureVector<byte> ber = decode(source, label_got);
49 if(label_got != label_want)
50 throw Decoding_Error("PEM: Label mismatch, wanted " + label_want +
51 ", got " + label_got);
52 return ber;
53 }
54
55/*************************************************
56* Decode PEM down to raw BER/DER *
57*************************************************/
58SecureVector<byte> decode(DataSource& source, std::string& label)
59 {
60 const u32bit RANDOM_CHAR_LIMIT = Config::get_u32bit("pem/forgive");
61
62 const std::string PEM_HEADER1 = "-----BEGIN ";
63 const std::string PEM_HEADER2 = "-----";
64 u32bit position = 0;
65
66 while(position != PEM_HEADER1.length())
67 {
68 byte b;
69 if(!source.read_byte(b))
70 throw Decoding_Error("PEM: No PEM header found");
71 if(b == PEM_HEADER1[position])
72 position++;
73 else if(position >= RANDOM_CHAR_LIMIT)
74 throw Decoding_Error("PEM: Malformed PEM header");
75 else
76 position = 0;
77 }
78 position = 0;
79 while(position != PEM_HEADER2.length())
80 {
81 byte b;
82 if(!source.read_byte(b))
83 throw Decoding_Error("PEM: No PEM header found");
84 if(b == PEM_HEADER2[position])
85 position++;
86 else if(position)
87 throw Decoding_Error("PEM: Malformed PEM header");
88
89 if(position == 0)
90 label += (char)b;
91 }
92
93 Pipe base64(new Base64_Decoder);
94 base64.start_msg();
95
96 const std::string PEM_TRAILER = "-----END " + label + "-----";
97 position = 0;
98 while(position != PEM_TRAILER.length())
99 {
100 byte b;
101 if(!source.read_byte(b))
102 throw Decoding_Error("PEM: No PEM trailer found");
103 if(b == PEM_TRAILER[position])
104 position++;
105 else if(position)
106 throw Decoding_Error("PEM: Malformed PEM trailer");
107
108 if(position == 0)
109 base64.write(b);
110 }
111 base64.end_msg();
112 return base64.read_all();
113 }
114
115/*************************************************
116* Search for a PEM signature *
117*************************************************/
118bool matches(DataSource& source, const std::string& extra)
119 {
120 const u32bit PEM_SEARCH_RANGE = Config::get_u32bit("pem/search");
121 const std::string PEM_HEADER = "-----BEGIN " + extra;
122
123 SecureVector<byte> search_buf(PEM_SEARCH_RANGE);
124 u32bit got = source.peek(search_buf, search_buf.size(), 0);
125
126 if(got < PEM_HEADER.length())
127 return false;
128
129 u32bit index = 0;
130
131 for(u32bit j = 0; j != got; j++)
132 {
133 if(search_buf[j] == PEM_HEADER[index])
134 index++;
135 else
136 index = 0;
137 if(index == PEM_HEADER.size())
138 return true;
139 }
140 return false;
141 }
142
143}
144
145}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status