|  | 
|  | 1 | +/** | 
|  | 2 | + * @file tls_context.h | 
|  | 3 | + * | 
|  | 4 | + * Context object for TLS (SSL) sockets. | 
|  | 5 | + * | 
|  | 6 | + * @author Jens Alfke | 
|  | 7 | + * @author Couchbase, Inc. | 
|  | 8 | + * @author www.couchbase.com | 
|  | 9 | + * | 
|  | 10 | + * @date August 2019 | 
|  | 11 | + */ | 
|  | 12 | + | 
|  | 13 | +// -------------------------------------------------------------------------- | 
|  | 14 | +// This file is part of the "sockpp" C++ socket library. | 
|  | 15 | +// | 
|  | 16 | +// Copyright (c) 2014-2019 Frank Pagliughi | 
|  | 17 | +// All rights reserved. | 
|  | 18 | +// | 
|  | 19 | +// Redistribution and use in source and binary forms, with or without | 
|  | 20 | +// modification, are permitted provided that the following conditions are | 
|  | 21 | +// met: | 
|  | 22 | +// | 
|  | 23 | +// 1. Redistributions of source code must retain the above copyright notice, | 
|  | 24 | +// this list of conditions and the following disclaimer. | 
|  | 25 | +// | 
|  | 26 | +// 2. Redistributions in binary form must reproduce the above copyright | 
|  | 27 | +// notice, this list of conditions and the following disclaimer in the | 
|  | 28 | +// documentation and/or other materials provided with the distribution. | 
|  | 29 | +// | 
|  | 30 | +// 3. Neither the name of the copyright holder nor the names of its | 
|  | 31 | +// contributors may be used to endorse or promote products derived from this | 
|  | 32 | +// software without specific prior written permission. | 
|  | 33 | +// | 
|  | 34 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | 
|  | 35 | +// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 
|  | 36 | +// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 
|  | 37 | +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | 
|  | 38 | +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | 
|  | 39 | +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | 
|  | 40 | +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | 
|  | 41 | +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | 
|  | 42 | +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | 
|  | 43 | +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 
|  | 44 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | 45 | +// -------------------------------------------------------------------------- | 
|  | 46 | + | 
|  | 47 | +#ifndef __sockpp_tls_context_h | 
|  | 48 | +#define __sockpp_tls_context_h | 
|  | 49 | + | 
|  | 50 | +#include "sockpp/platform.h" | 
|  | 51 | +#include <memory> | 
|  | 52 | +#include <string> | 
|  | 53 | + | 
|  | 54 | +namespace sockpp { | 
|  | 55 | +    class connector; | 
|  | 56 | +    class stream_socket; | 
|  | 57 | +    class tls_socket; | 
|  | 58 | + | 
|  | 59 | +    /** | 
|  | 60 | +     * Context / configuration for TLS (SSL) connections; also acts as a factory for | 
|  | 61 | +     * \ref tls_socket objects. | 
|  | 62 | +     * | 
|  | 63 | +     * A single context can be shared by any number of \ref tls_socket instances. | 
|  | 64 | +     * A context must remain in scope as long as any socket using it remains in scope. | 
|  | 65 | +     */ | 
|  | 66 | +    class tls_context | 
|  | 67 | +    { | 
|  | 68 | +    public: | 
|  | 69 | +        enum role_t { | 
|  | 70 | +            CLIENT = 0, | 
|  | 71 | +            SERVER = 1 | 
|  | 72 | +        }; | 
|  | 73 | +        /** | 
|  | 74 | +         * A singleton context that can be used if you don't need any per-connection | 
|  | 75 | +         * configuration. | 
|  | 76 | +         */ | 
|  | 77 | +        static tls_context& default_context(); | 
|  | 78 | + | 
|  | 79 | +        virtual ~tls_context() =default; | 
|  | 80 | + | 
|  | 81 | +        /** | 
|  | 82 | +         * Tells whether the context is initialized and valid. Check this after constructing | 
|  | 83 | +         * an instance and do not use if not valid. | 
|  | 84 | +         * @return Zero if valid, a nonzero error code if initialization failed. | 
|  | 85 | +         *         The code may be a POSIX code, or one specific to the TLS library. | 
|  | 86 | +         */ | 
|  | 87 | +        int status() const { | 
|  | 88 | +            return status_; | 
|  | 89 | +        } | 
|  | 90 | + | 
|  | 91 | +        operator bool() const { | 
|  | 92 | +            return status_ == 0; | 
|  | 93 | +        } | 
|  | 94 | + | 
|  | 95 | +        /** | 
|  | 96 | +         * Overrides the set of trusted root certificates used for validation. | 
|  | 97 | +         */ | 
|  | 98 | +        virtual void set_root_certs(const std::string &certData) =0; | 
|  | 99 | + | 
|  | 100 | +        /** | 
|  | 101 | +         * Allows connections to peers whose X.509 certificates are not valid. | 
|  | 102 | +         * **If enabled, you take responsibility for validating the certificate yourself!** | 
|  | 103 | +         * @param allow Pass true to allow invalid certs to be used, false to disallow | 
|  | 104 | +         *              (default is false.) | 
|  | 105 | +         */ | 
|  | 106 | +        virtual void allow_invalid_peer_certs(bool allow) =0; | 
|  | 107 | + | 
|  | 108 | +        /** | 
|  | 109 | +         * Requires that the peer have the exact certificate given. | 
|  | 110 | +         * This is known as "cert-pinning". It's more secure, but requires that the client | 
|  | 111 | +         * update its copy of the certificate whenever the server updates it. | 
|  | 112 | +         * @param certData The X.509 certificate in DER or PEM form; or an empty string for | 
|  | 113 | +         *                  no pinning (the default). | 
|  | 114 | +         */ | 
|  | 115 | +        virtual void allow_only_certificate(const std::string &certData) =0; | 
|  | 116 | + | 
|  | 117 | +        virtual void set_identity(const std::string &certificate_data, | 
|  | 118 | +                                  const std::string &private_key_data) =0; | 
|  | 119 | + | 
|  | 120 | +        virtual void set_identity_files(const std::string &certificate_file, | 
|  | 121 | +                                        const std::string &private_key_file, | 
|  | 122 | +                                        const std::string &private_key_password) =0; | 
|  | 123 | + | 
|  | 124 | +        /** | 
|  | 125 | +         * Creates a new \ref tls_socket instance that wraps the given connector socket. | 
|  | 126 | +         * The \ref tls_socket takes ownership of the base socket and will close it when | 
|  | 127 | +         * it's closed. | 
|  | 128 | +         * When this method returns, the TLS handshake will already have completed; | 
|  | 129 | +         * be sure to check the stream's status, since the handshake may have failed. | 
|  | 130 | +         * @param socket The underlying connector socket that TLS will use for I/O. | 
|  | 131 | +         * @param role CLIENT or SERVER mode. | 
|  | 132 | +         * @param peer_name  The peer's canonical hostname, or other distinguished name, | 
|  | 133 | +         *                  to be used for certificate validation. | 
|  | 134 | +         * @return A new \ref tls_socket to use for secure I/O. | 
|  | 135 | +         */ | 
|  | 136 | +        virtual std::unique_ptr<tls_socket> wrap_socket(std::unique_ptr<stream_socket> socket, | 
|  | 137 | +                                                        role_t role, | 
|  | 138 | +                                                        const std::string &peer_name) =0; | 
|  | 139 | + | 
|  | 140 | +    protected: | 
|  | 141 | +        tls_context() =default; | 
|  | 142 | + | 
|  | 143 | +        /** | 
|  | 144 | +         * Sets the error status of the context. Call this if initialization fails. | 
|  | 145 | +         */ | 
|  | 146 | +        void set_status(int s) const { | 
|  | 147 | +            status_ = s; | 
|  | 148 | +        } | 
|  | 149 | + | 
|  | 150 | +    private: | 
|  | 151 | +        tls_context(const tls_context&) =delete; | 
|  | 152 | + | 
|  | 153 | +        mutable int status_ =0; | 
|  | 154 | +    }; | 
|  | 155 | + | 
|  | 156 | +} | 
|  | 157 | + | 
|  | 158 | +#endif | 
0 commit comments