/* * Copyright (c) 2017-2020, [Ribose Inc](https://www.ribose.com). * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef STREAM_ARMOUR_H_ #define STREAM_ARMOUR_H_ #include "stream-common.h" typedef enum { PGP_ARMORED_UNKNOWN, PGP_ARMORED_MESSAGE, PGP_ARMORED_PUBLIC_KEY, PGP_ARMORED_SECRET_KEY, PGP_ARMORED_SIGNATURE, PGP_ARMORED_CLEARTEXT, PGP_ARMORED_BASE64 } pgp_armored_msg_t; /* @brief Init dearmoring stream * @param src allocated pgp_source_t structure * @param readsrc source to read data from * @return RNP_SUCCESS on success or error code otherwise **/ rnp_result_t init_armored_src(pgp_source_t *src, pgp_source_t *readsrc, bool noheaders = false); /* @brief Init armoring stream * @param dst allocated pgp_dest_t structure * @param writedst destination to write armored data to * @param msgtype type of the message (see pgp_armored_msg_t) * @return RNP_SUCCESS on success or error code otherwise **/ rnp_result_t init_armored_dst(pgp_dest_t * dst, pgp_dest_t * writedst, pgp_armored_msg_t msgtype); /* @brief Dearmor the source, outputting binary data * @param src initialized source with armored data * @param dst initialized dest to write binary data to * @return RNP_SUCCESS on success or error code otherwise **/ rnp_result_t rnp_dearmor_source(pgp_source_t *src, pgp_dest_t *dst); /* @brief Armor the source, outputting base64-encoded data with headers * @param src initialized source with binary data * @param dst destination to write armored data * @msgtype type of the message, to write correct armor headers * @return RNP_SUCCESS on success or error code otherwise **/ rnp_result_t rnp_armor_source(pgp_source_t *src, pgp_dest_t *dst, pgp_armored_msg_t msgtype); /* @brief Guess the corresponding armored message type by first byte(s) of PGP message * @param src initialized source with binary PGP message data * @return corresponding enum element or PGP_ARMORED_UNKNOWN **/ pgp_armored_msg_t rnp_armor_guess_type(pgp_source_t *src); /* @brief Get type of the armored message by peeking header. * @param src initialized source with armored message data. * @return corresponding enum element or PGP_ARMORED_UNKNOWN **/ pgp_armored_msg_t rnp_armored_get_type(pgp_source_t *src); /* @brief Check whether source could be an armored source * @param src initialized source with some data * @return true if source could be an armored data or false otherwise **/ bool is_armored_source(pgp_source_t *src); /* @brief Check whether destination is armored * @param dest initialized destination * @return true if destination is armored or false otherwise **/ bool is_armored_dest(pgp_dest_t *dst); /* @brief Check whether source is cleartext signed * @param src initialized source with some data * @return true if source could be a cleartext signed data or false otherwise **/ bool is_cleartext_source(pgp_source_t *src); /** @brief Check whether source is base64-encoded * @param src initialized source with some data * @return true if source could be a base64-encoded data or false otherwise **/ bool is_base64_source(pgp_source_t &src); /** Set line length for armoring * * @param dst initialized dest to write armored data to * @param llen line length in characters * @return RNP_SUCCESS on success, or any other value on error */ rnp_result_t armored_dst_set_line_length(pgp_dest_t *dst, size_t llen); namespace rnp { class ArmoredSource : public Source { pgp_source_t &readsrc_; bool armored_; bool multiple_; public: static const uint32_t AllowBinary; static const uint32_t AllowBase64; static const uint32_t AllowMultiple; ArmoredSource(const ArmoredSource &) = delete; ArmoredSource(ArmoredSource &&) = delete; ArmoredSource(pgp_source_t &readsrc, uint32_t flags = 0); pgp_source_t &src(); bool multiple() { return multiple_; } /* Restart dearmoring in case of multiple armored messages in a single stream */ void restart(); }; class ArmoredDest : public Dest { pgp_dest_t &writedst_; public: ArmoredDest(const ArmoredDest &) = delete; ArmoredDest(ArmoredDest &&) = delete; ArmoredDest(pgp_dest_t &writedst, pgp_armored_msg_t msgtype) : Dest(), writedst_(writedst) { auto ret = init_armored_dst(&dst_, &writedst_, msgtype); if (ret) { throw rnp::rnp_exception(ret); } }; ~ArmoredDest() { if (!discard_) { dst_finish(&dst_); } } }; } // namespace rnp #endif