monotone

monotone Mtn Source Tree

Root/botan/pem.cpp

1/*************************************************
2* PEM Encoding/Decoding Source File *
3* (C) 1999-2006 The Botan Project *
4*************************************************/
5
6#include <botan/pem.h>
7#include <botan/config.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 = global_config().option_as_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 =
61 global_config().option_as_u32bit("pem/forgive");
62
63 const std::string PEM_HEADER1 = "-----BEGIN ";
64 const std::string PEM_HEADER2 = "-----";
65 u32bit position = 0;
66
67 while(position != PEM_HEADER1.length())
68 {
69 byte b;
70 if(!source.read_byte(b))
71 throw Decoding_Error("PEM: No PEM header found");
72 if(b == PEM_HEADER1[position])
73 ++position;
74 else if(position >= RANDOM_CHAR_LIMIT)
75 throw Decoding_Error("PEM: Malformed PEM header");
76 else
77 position = 0;
78 }
79 position = 0;
80 while(position != PEM_HEADER2.length())
81 {
82 byte b;
83 if(!source.read_byte(b))
84 throw Decoding_Error("PEM: No PEM header found");
85 if(b == PEM_HEADER2[position])
86 ++position;
87 else if(position)
88 throw Decoding_Error("PEM: Malformed PEM header");
89
90 if(position == 0)
91 label += (char)b;
92 }
93
94 Pipe base64(new Base64_Decoder);
95 base64.start_msg();
96
97 const std::string PEM_TRAILER = "-----END " + label + "-----";
98 position = 0;
99 while(position != PEM_TRAILER.length())
100 {
101 byte b;
102 if(!source.read_byte(b))
103 throw Decoding_Error("PEM: No PEM trailer found");
104 if(b == PEM_TRAILER[position])
105 ++position;
106 else if(position)
107 throw Decoding_Error("PEM: Malformed PEM trailer");
108
109 if(position == 0)
110 base64.write(b);
111 }
112 base64.end_msg();
113 return base64.read_all();
114 }
115
116/*************************************************
117* Search for a PEM signature *
118*************************************************/
119bool matches(DataSource& source, const std::string& extra)
120 {
121 const u32bit PEM_SEARCH_RANGE =
122 global_config().option_as_u32bit("pem/search");
123
124 const std::string PEM_HEADER = "-----BEGIN " + extra;
125
126 SecureVector<byte> search_buf(PEM_SEARCH_RANGE);
127 u32bit got = source.peek(search_buf, search_buf.size(), 0);
128
129 if(got < PEM_HEADER.length())
130 return false;
131
132 u32bit index = 0;
133
134 for(u32bit j = 0; j != got; ++j)
135 {
136 if(search_buf[j] == PEM_HEADER[index])
137 ++index;
138 else
139 index = 0;
140 if(index == PEM_HEADER.size())
141 return true;
142 }
143 return false;
144 }
145
146}
147
148}

Archive Download this file

Branches

Tags

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