1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_SRC_CORE_TSI_SSL_KEY_LOGGING_SSL_KEY_LOGGING_H
16 #define GRPC_SRC_CORE_TSI_SSL_KEY_LOGGING_SSL_KEY_LOGGING_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include <iostream>
21 #include <map>
22 
23 #include <openssl/ssl.h>
24 
25 #include "absl/base/thread_annotations.h"
26 
27 #include <grpc/grpc_security.h>
28 #include <grpc/slice.h>
29 #include <grpc/support/sync.h>
30 
31 #include "src/core/lib/gprpp/memory.h"
32 #include "src/core/lib/gprpp/ref_counted.h"
33 #include "src/core/lib/gprpp/sync.h"
34 
35 namespace tsi {
36 
37 class TlsSessionKeyLoggerCache
38     : public grpc_core::RefCounted<TlsSessionKeyLoggerCache> {
39  public:
40   TlsSessionKeyLoggerCache();
41   ~TlsSessionKeyLoggerCache() override;
42 
43   // A helper class which facilitates appending Tls session keys into a file.
44   // The instance is bound to a file meaning only one instance of this object
45   // can ever exist for a given file path.
46   class TlsSessionKeyLogger
47       : public grpc_core::RefCounted<TlsSessionKeyLogger> {
48    public:
49     // Instantiates a TlsSessionKeyLogger instance bound to a specific path.
50     TlsSessionKeyLogger(
51         std::string tls_session_key_log_file_path,
52         grpc_core::RefCountedPtr<TlsSessionKeyLoggerCache> cache);
53     ~TlsSessionKeyLogger() override;
54 
55     // Not copyable nor assignable.
56     TlsSessionKeyLogger(const TlsSessionKeyLogger&) = delete;
57     TlsSessionKeyLogger& operator=(const TlsSessionKeyLogger&) = delete;
58     // Writes session keys into the file in the NSS key logging format.
59     // This is called upon completion of a handshake. The associated ssl_context
60     // is also provided here to support future extensions such as logging
61     // keys only when connections are made by certain IPs etc.
62     void LogSessionKeys(SSL_CTX* ssl_context,
63                         const std::string& session_keys_info);
64 
65    private:
66     grpc_core::Mutex lock_;  // protects appends to file
67     FILE* fd_ ABSL_GUARDED_BY(lock_);
68     std::string tls_session_key_log_file_path_;
69     grpc_core::RefCountedPtr<TlsSessionKeyLoggerCache> cache_;
70   };
71   // Creates and returns a TlsSessionKeyLogger instance.
72   static grpc_core::RefCountedPtr<TlsSessionKeyLogger> Get(
73       std::string tls_session_key_log_file_path);
74 
75  private:
76   std::map<std::string, TlsSessionKeyLogger*> tls_session_key_logger_map_;
77 };
78 
79 }  // namespace tsi
80 
81 #endif  // GRPC_SRC_CORE_TSI_SSL_KEY_LOGGING_SSL_KEY_LOGGING_H
82