12c593315Sopenharmony_ci/*
22c593315Sopenharmony_ci * nghttp2 - HTTP/2 C Library
32c593315Sopenharmony_ci *
42c593315Sopenharmony_ci * Copyright (c) 2012 Tatsuhiro Tsujikawa
52c593315Sopenharmony_ci *
62c593315Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining
72c593315Sopenharmony_ci * a copy of this software and associated documentation files (the
82c593315Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
92c593315Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
102c593315Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to
112c593315Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
122c593315Sopenharmony_ci * the following conditions:
132c593315Sopenharmony_ci *
142c593315Sopenharmony_ci * The above copyright notice and this permission notice shall be
152c593315Sopenharmony_ci * included in all copies or substantial portions of the Software.
162c593315Sopenharmony_ci *
172c593315Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
182c593315Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
192c593315Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
202c593315Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
212c593315Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
222c593315Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
232c593315Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
242c593315Sopenharmony_ci */
252c593315Sopenharmony_ci#ifndef SHRPX_TLS_H
262c593315Sopenharmony_ci#define SHRPX_TLS_H
272c593315Sopenharmony_ci
282c593315Sopenharmony_ci#include "shrpx.h"
292c593315Sopenharmony_ci
302c593315Sopenharmony_ci#include <vector>
312c593315Sopenharmony_ci#include <mutex>
322c593315Sopenharmony_ci
332c593315Sopenharmony_ci#include <openssl/ssl.h>
342c593315Sopenharmony_ci#include <openssl/err.h>
352c593315Sopenharmony_ci
362c593315Sopenharmony_ci#include <ev.h>
372c593315Sopenharmony_ci
382c593315Sopenharmony_ci#ifdef HAVE_NEVERBLEED
392c593315Sopenharmony_ci#  include <neverbleed.h>
402c593315Sopenharmony_ci#endif // HAVE_NEVERBLEED
412c593315Sopenharmony_ci
422c593315Sopenharmony_ci#include "network.h"
432c593315Sopenharmony_ci#include "shrpx_config.h"
442c593315Sopenharmony_ci#include "shrpx_router.h"
452c593315Sopenharmony_ci
462c593315Sopenharmony_cinamespace shrpx {
472c593315Sopenharmony_ci
482c593315Sopenharmony_ciclass ClientHandler;
492c593315Sopenharmony_ciclass Worker;
502c593315Sopenharmony_ciclass DownstreamConnectionPool;
512c593315Sopenharmony_cistruct DownstreamAddr;
522c593315Sopenharmony_cistruct UpstreamAddr;
532c593315Sopenharmony_ci
542c593315Sopenharmony_cinamespace tls {
552c593315Sopenharmony_ci
562c593315Sopenharmony_cistruct TLSSessionCache {
572c593315Sopenharmony_ci  // ASN1 representation of SSL_SESSION object.  See
582c593315Sopenharmony_ci  // i2d_SSL_SESSION(3SSL).
592c593315Sopenharmony_ci  std::vector<uint8_t> session_data;
602c593315Sopenharmony_ci  // The last time stamp when this cache entry is created or updated.
612c593315Sopenharmony_ci  std::chrono::steady_clock::time_point last_updated;
622c593315Sopenharmony_ci};
632c593315Sopenharmony_ci
642c593315Sopenharmony_ci// This struct stores the additional information per SSL_CTX.  This is
652c593315Sopenharmony_ci// attached to SSL_CTX using SSL_CTX_set_app_data().
662c593315Sopenharmony_cistruct TLSContextData {
672c593315Sopenharmony_ci  // SCT data formatted so that this can be directly sent as
682c593315Sopenharmony_ci  // extension_data of signed_certificate_timestamp.
692c593315Sopenharmony_ci  std::vector<uint8_t> sct_data;
702c593315Sopenharmony_ci#ifndef HAVE_ATOMIC_STD_SHARED_PTR
712c593315Sopenharmony_ci  // Protects ocsp_data;
722c593315Sopenharmony_ci  std::mutex mu;
732c593315Sopenharmony_ci#endif // !HAVE_ATOMIC_STD_SHARED_PTR
742c593315Sopenharmony_ci  // OCSP response
752c593315Sopenharmony_ci  std::shared_ptr<std::vector<uint8_t>> ocsp_data;
762c593315Sopenharmony_ci
772c593315Sopenharmony_ci  // Path to certificate file
782c593315Sopenharmony_ci  const char *cert_file;
792c593315Sopenharmony_ci};
802c593315Sopenharmony_ci
812c593315Sopenharmony_ci// Create server side SSL_CTX
822c593315Sopenharmony_ciSSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file,
832c593315Sopenharmony_ci                            const std::vector<uint8_t> &sct_data
842c593315Sopenharmony_ci
852c593315Sopenharmony_ci#ifdef HAVE_NEVERBLEED
862c593315Sopenharmony_ci                            ,
872c593315Sopenharmony_ci                            neverbleed_t *nb
882c593315Sopenharmony_ci#endif // HAVE_NEVERBLEED
892c593315Sopenharmony_ci);
902c593315Sopenharmony_ci
912c593315Sopenharmony_ci// Create client side SSL_CTX.  This does not configure ALPN settings.
922c593315Sopenharmony_ci// |next_proto_select_cb| is for NPN.
932c593315Sopenharmony_ciSSL_CTX *create_ssl_client_context(
942c593315Sopenharmony_ci#ifdef HAVE_NEVERBLEED
952c593315Sopenharmony_ci    neverbleed_t *nb,
962c593315Sopenharmony_ci#endif // HAVE_NEVERBLEED
972c593315Sopenharmony_ci    const StringRef &cacert, const StringRef &cert_file,
982c593315Sopenharmony_ci    const StringRef &private_key_file,
992c593315Sopenharmony_ci    int (*next_proto_select_cb)(SSL *s, unsigned char **out,
1002c593315Sopenharmony_ci                                unsigned char *outlen, const unsigned char *in,
1012c593315Sopenharmony_ci                                unsigned int inlen, void *arg));
1022c593315Sopenharmony_ci
1032c593315Sopenharmony_ci#ifdef ENABLE_HTTP3
1042c593315Sopenharmony_ciSSL_CTX *create_quic_ssl_client_context(
1052c593315Sopenharmony_ci#  ifdef HAVE_NEVERBLEED
1062c593315Sopenharmony_ci    neverbleed_t *nb,
1072c593315Sopenharmony_ci#  endif // HAVE_NEVERBLEED
1082c593315Sopenharmony_ci    const StringRef &cacert, const StringRef &cert_file,
1092c593315Sopenharmony_ci    const StringRef &private_key_file,
1102c593315Sopenharmony_ci    int (*next_proto_select_cb)(SSL *s, unsigned char **out,
1112c593315Sopenharmony_ci                                unsigned char *outlen, const unsigned char *in,
1122c593315Sopenharmony_ci                                unsigned int inlen, void *arg));
1132c593315Sopenharmony_ci#endif // ENABLE_HTTP3
1142c593315Sopenharmony_ci
1152c593315Sopenharmony_ciClientHandler *accept_connection(Worker *worker, int fd, sockaddr *addr,
1162c593315Sopenharmony_ci                                 int addrlen, const UpstreamAddr *faddr);
1172c593315Sopenharmony_ci
1182c593315Sopenharmony_ci// Check peer's certificate against given |address| and |host|.
1192c593315Sopenharmony_ciint check_cert(SSL *ssl, const Address *addr, const StringRef &host);
1202c593315Sopenharmony_ci// Check peer's certificate against given host name described in
1212c593315Sopenharmony_ci// |addr| and numeric address in |raddr|.  Note that |raddr| might not
1222c593315Sopenharmony_ci// point to &addr->addr.
1232c593315Sopenharmony_ciint check_cert(SSL *ssl, const DownstreamAddr *addr, const Address *raddr);
1242c593315Sopenharmony_ci
1252c593315Sopenharmony_ci// Verify |cert| using numeric IP address.  |hostname| and |addr|
1262c593315Sopenharmony_ci// should contain the same numeric IP address.  This function returns
1272c593315Sopenharmony_ci// 0 if it succeeds, or -1.
1282c593315Sopenharmony_ciint verify_numeric_hostname(X509 *cert, const StringRef &hostname,
1292c593315Sopenharmony_ci                            const Address *addr);
1302c593315Sopenharmony_ci
1312c593315Sopenharmony_ci// Verify |cert| using DNS name hostname.  This function returns 0 if
1322c593315Sopenharmony_ci// it succeeds, or -1.
1332c593315Sopenharmony_ciint verify_dns_hostname(X509 *cert, const StringRef &hostname);
1342c593315Sopenharmony_ci
1352c593315Sopenharmony_cistruct WildcardRevPrefix {
1362c593315Sopenharmony_ci  WildcardRevPrefix(const StringRef &prefix, size_t idx)
1372c593315Sopenharmony_ci      : prefix(std::begin(prefix), std::end(prefix)), idx(idx) {}
1382c593315Sopenharmony_ci
1392c593315Sopenharmony_ci  // "Prefix" of wildcard pattern.  It is reversed from original form.
1402c593315Sopenharmony_ci  // For example, if the original wildcard is "test*.nghttp2.org",
1412c593315Sopenharmony_ci  // prefix would be "tset".
1422c593315Sopenharmony_ci  ImmutableString prefix;
1432c593315Sopenharmony_ci  // The index of SSL_CTX.  See ConnectionHandler::get_ssl_ctx().
1442c593315Sopenharmony_ci  size_t idx;
1452c593315Sopenharmony_ci};
1462c593315Sopenharmony_ci
1472c593315Sopenharmony_cistruct WildcardPattern {
1482c593315Sopenharmony_ci  // Wildcard host sharing only suffix is probably rare, so we just do
1492c593315Sopenharmony_ci  // linear search.
1502c593315Sopenharmony_ci  std::vector<WildcardRevPrefix> rev_prefix;
1512c593315Sopenharmony_ci};
1522c593315Sopenharmony_ci
1532c593315Sopenharmony_ciclass CertLookupTree {
1542c593315Sopenharmony_cipublic:
1552c593315Sopenharmony_ci  CertLookupTree();
1562c593315Sopenharmony_ci
1572c593315Sopenharmony_ci  // Adds hostname pattern |hostname| to the lookup tree, associating
1582c593315Sopenharmony_ci  // value |index|.  When the queried host matches this pattern,
1592c593315Sopenharmony_ci  // |index| is returned.  We support wildcard pattern.  The left most
1602c593315Sopenharmony_ci  // '*' is considered as wildcard character, and it must match at
1612c593315Sopenharmony_ci  // least one character.  If the same pattern has been already added,
1622c593315Sopenharmony_ci  // this function does not alter the tree, and returns the existing
1632c593315Sopenharmony_ci  // matching index.
1642c593315Sopenharmony_ci  //
1652c593315Sopenharmony_ci  // The caller should lower-case |hostname| since this function does
1662c593315Sopenharmony_ci  // do that, and lookup function performs case-sensitive match.
1672c593315Sopenharmony_ci  //
1682c593315Sopenharmony_ci  // TODO Treat wildcard pattern described as RFC 6125.
1692c593315Sopenharmony_ci  //
1702c593315Sopenharmony_ci  // This function returns the index.  It returns -1 if it fails
1712c593315Sopenharmony_ci  // (e.g., hostname is too long).  If the returned index equals to
1722c593315Sopenharmony_ci  // |index|, then hostname is added to the tree with the value
1732c593315Sopenharmony_ci  // |index|.  If it is not -1, and does not equal to |index|, same
1742c593315Sopenharmony_ci  // hostname has already been added to the tree.
1752c593315Sopenharmony_ci  ssize_t add_cert(const StringRef &hostname, size_t index);
1762c593315Sopenharmony_ci
1772c593315Sopenharmony_ci  // Looks up index using the given |hostname|.  The exact match takes
1782c593315Sopenharmony_ci  // precedence over wildcard match.  For wildcard match, longest
1792c593315Sopenharmony_ci  // match (sum of matched suffix and prefix length in bytes) is
1802c593315Sopenharmony_ci  // preferred, breaking a tie with longer suffix.
1812c593315Sopenharmony_ci  //
1822c593315Sopenharmony_ci  // The caller should lower-case |hostname| since this function
1832c593315Sopenharmony_ci  // performs case-sensitive match.
1842c593315Sopenharmony_ci  ssize_t lookup(const StringRef &hostname);
1852c593315Sopenharmony_ci
1862c593315Sopenharmony_ci  // Dumps the contents of this lookup tree to stderr.
1872c593315Sopenharmony_ci  void dump() const;
1882c593315Sopenharmony_ci
1892c593315Sopenharmony_ciprivate:
1902c593315Sopenharmony_ci  // Exact match
1912c593315Sopenharmony_ci  Router router_;
1922c593315Sopenharmony_ci  // Wildcard reversed suffix match.  The returned index is into
1932c593315Sopenharmony_ci  // wildcard_patterns_.
1942c593315Sopenharmony_ci  Router rev_wildcard_router_;
1952c593315Sopenharmony_ci  // Stores wildcard suffix patterns.
1962c593315Sopenharmony_ci  std::vector<WildcardPattern> wildcard_patterns_;
1972c593315Sopenharmony_ci};
1982c593315Sopenharmony_ci
1992c593315Sopenharmony_ci// Adds hostnames in certificate in |ssl_ctx| to lookup tree |lt|.
2002c593315Sopenharmony_ci// The subjectAltNames and commonName are considered as eligible
2012c593315Sopenharmony_ci// hostname.  If there is at least one dNSName in subjectAltNames,
2022c593315Sopenharmony_ci// commonName is not considered.  |ssl_ctx| is also added to
2032c593315Sopenharmony_ci// |indexed_ssl_ctx|.  This function returns 0 if it succeeds, or -1.
2042c593315Sopenharmony_ciint cert_lookup_tree_add_ssl_ctx(
2052c593315Sopenharmony_ci    CertLookupTree *lt, std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
2062c593315Sopenharmony_ci    SSL_CTX *ssl_ctx);
2072c593315Sopenharmony_ci
2082c593315Sopenharmony_ci// Returns true if |proto| is included in the
2092c593315Sopenharmony_ci// protocol list |protos|.
2102c593315Sopenharmony_cibool in_proto_list(const std::vector<StringRef> &protos,
2112c593315Sopenharmony_ci                   const StringRef &proto);
2122c593315Sopenharmony_ci
2132c593315Sopenharmony_ci// Returns true if security requirement for HTTP/2 is fulfilled.
2142c593315Sopenharmony_cibool check_http2_requirement(SSL *ssl);
2152c593315Sopenharmony_ci
2162c593315Sopenharmony_ci// Returns SSL/TLS option mask to disable SSL/TLS protocol version not
2172c593315Sopenharmony_ci// included in |tls_proto_list|.  The returned mask can be directly
2182c593315Sopenharmony_ci// passed to SSL_CTX_set_options().
2192c593315Sopenharmony_cilong int create_tls_proto_mask(const std::vector<StringRef> &tls_proto_list);
2202c593315Sopenharmony_ci
2212c593315Sopenharmony_ciint set_alpn_prefs(std::vector<unsigned char> &out,
2222c593315Sopenharmony_ci                   const std::vector<StringRef> &protos);
2232c593315Sopenharmony_ci
2242c593315Sopenharmony_ci// Setups server side SSL_CTX.  This function inspects get_config()
2252c593315Sopenharmony_ci// and if upstream_no_tls is true, returns nullptr.  Otherwise
2262c593315Sopenharmony_ci// construct default SSL_CTX.  If subcerts are available
2272c593315Sopenharmony_ci// (get_config()->subcerts), caller should provide CertLookupTree
2282c593315Sopenharmony_ci// object as |cert_tree| parameter, otherwise SNI does not work.  All
2292c593315Sopenharmony_ci// the created SSL_CTX is stored into |all_ssl_ctx|.  They are also
2302c593315Sopenharmony_ci// added to |indexed_ssl_ctx|.  |cert_tree| uses its index to
2312c593315Sopenharmony_ci// associate hostname to the SSL_CTX.
2322c593315Sopenharmony_ciSSL_CTX *
2332c593315Sopenharmony_cisetup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx,
2342c593315Sopenharmony_ci                         std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
2352c593315Sopenharmony_ci                         CertLookupTree *cert_tree
2362c593315Sopenharmony_ci#ifdef HAVE_NEVERBLEED
2372c593315Sopenharmony_ci                         ,
2382c593315Sopenharmony_ci                         neverbleed_t *nb
2392c593315Sopenharmony_ci#endif // HAVE_NEVERBLEED
2402c593315Sopenharmony_ci);
2412c593315Sopenharmony_ci
2422c593315Sopenharmony_ci#ifdef ENABLE_HTTP3
2432c593315Sopenharmony_ciSSL_CTX *setup_quic_server_ssl_context(
2442c593315Sopenharmony_ci    std::vector<SSL_CTX *> &all_ssl_ctx,
2452c593315Sopenharmony_ci    std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx,
2462c593315Sopenharmony_ci    CertLookupTree *cert_tree
2472c593315Sopenharmony_ci#  ifdef HAVE_NEVERBLEED
2482c593315Sopenharmony_ci    ,
2492c593315Sopenharmony_ci    neverbleed_t *nb
2502c593315Sopenharmony_ci#  endif // HAVE_NEVERBLEED
2512c593315Sopenharmony_ci);
2522c593315Sopenharmony_ci#endif // ENABLE_HTTP3
2532c593315Sopenharmony_ci
2542c593315Sopenharmony_ci// Setups client side SSL_CTX.
2552c593315Sopenharmony_ciSSL_CTX *setup_downstream_client_ssl_context(
2562c593315Sopenharmony_ci#ifdef HAVE_NEVERBLEED
2572c593315Sopenharmony_ci    neverbleed_t *nb
2582c593315Sopenharmony_ci#endif // HAVE_NEVERBLEED
2592c593315Sopenharmony_ci);
2602c593315Sopenharmony_ci
2612c593315Sopenharmony_ci// Sets ALPN settings in |SSL| suitable for HTTP/2 use.
2622c593315Sopenharmony_civoid setup_downstream_http2_alpn(SSL *ssl);
2632c593315Sopenharmony_ci// Sets ALPN settings in |SSL| suitable for HTTP/1.1 use.
2642c593315Sopenharmony_civoid setup_downstream_http1_alpn(SSL *ssl);
2652c593315Sopenharmony_ci
2662c593315Sopenharmony_ci// Creates CertLookupTree.  If frontend is configured not to use TLS,
2672c593315Sopenharmony_ci// this function returns nullptr.
2682c593315Sopenharmony_cistd::unique_ptr<CertLookupTree> create_cert_lookup_tree();
2692c593315Sopenharmony_ci
2702c593315Sopenharmony_ciSSL *create_ssl(SSL_CTX *ssl_ctx);
2712c593315Sopenharmony_ci
2722c593315Sopenharmony_ci// Returns true if SSL/TLS is enabled on upstream
2732c593315Sopenharmony_cibool upstream_tls_enabled(const ConnectionConfig &connconf);
2742c593315Sopenharmony_ci
2752c593315Sopenharmony_ci// Performs TLS hostname match.  |pattern| can contain wildcard
2762c593315Sopenharmony_ci// character '*', which matches prefix of target hostname.  There are
2772c593315Sopenharmony_ci// several restrictions to make wildcard work.  The matching algorithm
2782c593315Sopenharmony_ci// is based on RFC 6125.
2792c593315Sopenharmony_cibool tls_hostname_match(const StringRef &pattern, const StringRef &hostname);
2802c593315Sopenharmony_ci
2812c593315Sopenharmony_ci// Caches |session|.  |session| is serialized into ASN1
2822c593315Sopenharmony_ci// representation, and stored.  |t| is used as a time stamp.
2832c593315Sopenharmony_ci// Depending on the existing cache's time stamp, |session| might not
2842c593315Sopenharmony_ci// be cached.
2852c593315Sopenharmony_civoid try_cache_tls_session(TLSSessionCache *cache, SSL_SESSION *session,
2862c593315Sopenharmony_ci                           const std::chrono::steady_clock::time_point &t);
2872c593315Sopenharmony_ci
2882c593315Sopenharmony_ci// Returns cached session associated |addr|.  If no cache entry is
2892c593315Sopenharmony_ci// found associated to |addr|, nullptr will be returned.
2902c593315Sopenharmony_ciSSL_SESSION *reuse_tls_session(const TLSSessionCache &addr);
2912c593315Sopenharmony_ci
2922c593315Sopenharmony_ci// Loads certificate form file |filename|.  The caller should delete
2932c593315Sopenharmony_ci// the returned object using X509_free().
2942c593315Sopenharmony_ciX509 *load_certificate(const char *filename);
2952c593315Sopenharmony_ci
2962c593315Sopenharmony_ci// Returns TLS version from |v|.  The returned value is defined in
2972c593315Sopenharmony_ci// OpenSSL header file.  This function returns -1 if |v| is not valid
2982c593315Sopenharmony_ci// TLS version string.
2992c593315Sopenharmony_ciint proto_version_from_string(const StringRef &v);
3002c593315Sopenharmony_ci
3012c593315Sopenharmony_ci// Verifies OCSP response |ocsp_resp| of length |ocsp_resplen|.  This
3022c593315Sopenharmony_ci// function returns 0 if it succeeds, or -1.
3032c593315Sopenharmony_ciint verify_ocsp_response(SSL_CTX *ssl_ctx, const uint8_t *ocsp_resp,
3042c593315Sopenharmony_ci                         size_t ocsp_resplen);
3052c593315Sopenharmony_ci
3062c593315Sopenharmony_ci// Stores fingerprint of |x| in |dst| of length |dstlen|.  |md|
3072c593315Sopenharmony_ci// specifies hash function to use, and |dstlen| must be large enough
3082c593315Sopenharmony_ci// to include hash value (e.g., 32 bytes for SHA-256).  This function
3092c593315Sopenharmony_ci// returns the number of bytes written in |dst|, or -1.
3102c593315Sopenharmony_cissize_t get_x509_fingerprint(uint8_t *dst, size_t dstlen, const X509 *x,
3112c593315Sopenharmony_ci                             const EVP_MD *md);
3122c593315Sopenharmony_ci
3132c593315Sopenharmony_ci// Returns subject name of |x|.  If this function fails to get subject
3142c593315Sopenharmony_ci// name, it returns an empty string.
3152c593315Sopenharmony_ciStringRef get_x509_subject_name(BlockAllocator &balloc, X509 *x);
3162c593315Sopenharmony_ci
3172c593315Sopenharmony_ci// Returns issuer name of |x|.  If this function fails to get issuer
3182c593315Sopenharmony_ci// name, it returns an empty string.
3192c593315Sopenharmony_ciStringRef get_x509_issuer_name(BlockAllocator &balloc, X509 *x);
3202c593315Sopenharmony_ci
3212c593315Sopenharmony_ci// Returns serial number of |x|.  If this function fails to get serial
3222c593315Sopenharmony_ci// number, it returns an empty string.  number
3232c593315Sopenharmony_ciStringRef get_x509_serial(BlockAllocator &balloc, X509 *x);
3242c593315Sopenharmony_ci
3252c593315Sopenharmony_ci// Fills NotBefore of |x| in |t|.  This function returns 0 if it
3262c593315Sopenharmony_ci// succeeds, or -1.
3272c593315Sopenharmony_ciint get_x509_not_before(time_t &t, X509 *x);
3282c593315Sopenharmony_ci
3292c593315Sopenharmony_ci// Fills NotAfter of |x| in |t|.  This function returns 0 if it
3302c593315Sopenharmony_ci// succeeds, or -1.
3312c593315Sopenharmony_ciint get_x509_not_after(time_t &t, X509 *x);
3322c593315Sopenharmony_ci
3332c593315Sopenharmony_ci} // namespace tls
3342c593315Sopenharmony_ci
3352c593315Sopenharmony_ci} // namespace shrpx
3362c593315Sopenharmony_ci
3372c593315Sopenharmony_ci#endif // SHRPX_TLS_H
338