10#include <botan/base64.h>
11#include <botan/data_src.h>
12#include <botan/exceptn.h>
13#include <botan/internal/fmt.h>
19std::string linewrap(
size_t width, std::string_view in) {
21 for(
size_t i = 0; i != in.size(); ++i) {
22 if(i > 0 && i % width == 0) {
27 if(!out.empty() && out[out.size() - 1] !=
'\n') {
39std::string
encode(
const uint8_t der[],
size_t length, std::string_view label,
size_t width) {
40 const std::string PEM_HEADER =
fmt(
"-----BEGIN {}-----\n", label);
41 const std::string PEM_TRAILER =
fmt(
"-----END {}-----\n", label);
43 return (PEM_HEADER + linewrap(width,
base64_encode(der, length)) + PEM_TRAILER);
50 std::string label_got;
52 if(label_got != label_want) {
53 throw Decoding_Error(
fmt(
"PEM: Label mismatch, wanted '{}' got '{}'", label_want, label_got));
63 const size_t RANDOM_CHAR_LIMIT = 8;
67 const std::string PEM_HEADER1 =
"-----BEGIN ";
68 const std::string PEM_HEADER2 =
"-----";
71 while(position != PEM_HEADER1.length()) {
76 if(
static_cast<char>(
b) == PEM_HEADER1[position]) {
78 }
else if(position >= RANDOM_CHAR_LIMIT) {
85 while(position != PEM_HEADER2.length()) {
90 if(
static_cast<char>(
b) == PEM_HEADER2[position]) {
97 label +=
static_cast<char>(
b);
101 std::vector<char> b64;
103 const std::string PEM_TRAILER =
fmt(
"-----END {}-----", label);
105 while(position != PEM_TRAILER.length()) {
110 if(
static_cast<char>(
b) == PEM_TRAILER[position]) {
112 }
else if(position) {
131 return decode(src, label);
138 const std::string PEM_HEADER =
fmt(
"-----BEGIN {}", extra);
141 const size_t got = source.
peek(search_buf.data(), search_buf.size(), 0);
143 if(got < PEM_HEADER.length()) {
149 for(
size_t j = 0; j != got; ++j) {
150 if(
static_cast<char>(search_buf[j]) == PEM_HEADER[index]) {
156 if(index == PEM_HEADER.size()) {
size_t read_byte(uint8_t &out)
virtual size_t peek(uint8_t out[], size_t length, size_t peek_offset) const =0
std::string encode(const uint8_t der[], size_t length, std::string_view label, size_t width)
secure_vector< uint8_t > decode_check_label(DataSource &source, std::string_view label_want)
bool matches(DataSource &source, std::string_view extra, size_t search_range)
secure_vector< uint8_t > decode(DataSource &source, std::string &label)
std::string fmt(std::string_view format, const T &... args)
size_t base64_encode(char out[], const uint8_t in[], size_t input_length, size_t &input_consumed, bool final_inputs)
size_t base64_decode(uint8_t out[], const char in[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws)
std::vector< T, secure_allocator< T > > secure_vector