1
#pragma once
2

            
3
#include <array>
4
#include <deque>
5
#include <functional>
6
#include <string>
7
#include <vector>
8

            
9
#include "envoy/common/pure.h"
10
#include "envoy/network/transport_socket.h"
11
#include "envoy/ssl/context.h"
12
#include "envoy/ssl/context_config.h"
13
#include "envoy/ssl/private_key/private_key.h"
14
#include "envoy/ssl/ssl_socket_extended_info.h"
15

            
16
#include "source/common/common/matchers.h"
17
#include "source/common/stats/symbol_table.h"
18
#include "source/common/tls/stats.h"
19

            
20
#include "openssl/ssl.h"
21
#include "openssl/x509v3.h"
22

            
23
namespace Envoy {
24
namespace Extensions {
25
namespace TransportSockets {
26
namespace Tls {
27

            
28
struct ValidationResults {
29
  enum class ValidationStatus {
30
    Pending,
31
    Successful,
32
    Failed,
33
  };
34
  // If the value is Pending, the validation is asynchronous.
35
  // If the value is Failed, refer to tls_alert and error_details for detailed error messages.
36
  ValidationStatus status;
37
  // Detailed status of the underlying validation. Depending on the validation configuration,
38
  // `status` may be valid but `detailed_status` might not be.
39
  Envoy::Ssl::ClientValidationStatus detailed_status;
40
  // The TLS alert used to interpret validation error if the validation failed.
41
  absl::optional<uint8_t> tls_alert;
42
  // The detailed error messages populated during validation.
43
  absl::optional<std::string> error_details;
44
};
45

            
46
class CertValidator {
47
public:
48
  // Wraps cert validation parameters added from time to time.
49
  struct ExtraValidationContext {
50
    // The pointer to transport socket callbacks.
51
    Network::TransportSocketCallbacks* callbacks;
52
  };
53

            
54
7096
  virtual ~CertValidator() = default;
55

            
56
  /**
57
   * Called to add the client validation context information to a given ssl context
58
   *
59
   * @param context the store context
60
   * @param require_client_cert whether or not client cert is required
61
   * @return an error status if the context was invalid.
62
   */
63
  virtual absl::Status addClientValidationContext(SSL_CTX* context, bool require_client_cert) PURE;
64

            
65
  /**
66
   * Called by customVerifyCallback to do the actual cert chain verification which could be
67
   * asynchronous. If the verification is asynchronous, Pending will be returned. After the
68
   * asynchronous verification is finished, the result should be passed back via a
69
   * VerifyResultCallback object.
70
   * @param cert_chain the cert chain with the leaf cert on top.
71
   * @param callback called after the asynchronous validation finishes to handle the result. Must
72
   * outlive this call if it returns Pending. Not used if doing synchronous verification. If not
73
   * provided and the validation is asynchronous, ssl_extended_info will create one.
74
   * @param transport_socket_options config options to validate cert, might short live the
75
   * validation if it is asynchronous.
76
   * @param ssl_ctx the config context this validation should use.
77
   * @param validation_context a placeholder for additional validation parameters.
78
   * @param is_server whether the validation is on server side.
79
   * @return ValidationResult the validation status and error messages if there is any.
80
   */
81
  virtual ValidationResults
82
  doVerifyCertChain(STACK_OF(X509)& cert_chain, Ssl::ValidateResultCallbackPtr callback,
83
                    const Network::TransportSocketOptionsConstSharedPtr& transport_socket_options,
84
                    SSL_CTX& ssl_ctx, const ExtraValidationContext& validation_context,
85
                    bool is_server, absl::string_view host_name) PURE;
86

            
87
  /**
88
   * Called to initialize all ssl contexts
89
   *
90
   * @param contexts the store context
91
   * @param handshaker_provides_certificates whether or not a handshaker implementation provides
92
   * certificates itself.
93
   * @param scope the stats scope.
94
   * @return the ssl verification mode flag or an error if initialization failed.
95
   */
96
  virtual absl::StatusOr<int> initializeSslContexts(std::vector<SSL_CTX*> contexts,
97
                                                    bool handshaker_provides_certificates,
98
                                                    Stats::Scope& scope) PURE;
99

            
100
  /**
101
   * Called when calculation hash for session context ids. This hash MUST include all
102
   * configuration used to validate a peer certificate, so that if this configuration
103
   * is changed, sessions cannot be re-used and must be re-negotiated and re-validated
104
   * using the new settings.
105
   *
106
   * @param md the store context
107
   * @param hash_buffer the buffer used for digest calculation
108
   * @param hash_length the expected length of hash
109
   */
110
  virtual void updateDigestForSessionId(bssl::ScopedEVP_MD_CTX& md,
111
                                        uint8_t hash_buffer[EVP_MAX_MD_SIZE],
112
                                        unsigned hash_length) PURE;
113

            
114
  virtual absl::optional<uint32_t> daysUntilFirstCertExpires() const PURE;
115
  virtual std::string getCaFileName() const PURE;
116
  virtual Envoy::Ssl::CertificateDetailsPtr getCaCertInformation() const PURE;
117
};
118

            
119
using CertValidatorPtr = std::unique_ptr<CertValidator>;
120

            
121
} // namespace Tls
122
} // namespace TransportSockets
123
} // namespace Extensions
124
} // namespace Envoy