1 /*
2  * SRT - Secure, Reliable, Transport
3  * Copyright (c) 2018 Haivision Systems Inc.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  */
10 
11 #if ENABLE_HAICRYPT_LOGGING
12 
13 #include "hcrypt.h"
14 #include "haicrypt.h"
15 #include "../srtcore/srt.h"
16 #include "../srtcore/logging.h"
17 
18 extern srt_logging::LogConfig srt_logger_config;
19 
20 // LOGFA symbol defined in srt.h
21 srt_logging::Logger hclog(SRT_LOGFA_HAICRYPT, srt_logger_config, "SRT.hc");
22 
23 extern "C" {
24 
HaiCrypt_SetLogLevel(int level,int logfa)25 int HaiCrypt_SetLogLevel(int level, int logfa)
26 {
27     srt_setloglevel(level);
28     if (logfa != SRT_LOGFA_GENERAL) // General can't be turned on or off
29     {
30         srt_addlogfa(logfa);
31     }
32     return 0;
33 }
34 
35 // HaiCrypt will be using its own FA, which will be turned off by default.
36 
37 // Templates made C way.
38 // It's tempting to use the HAICRYPT_DEFINE_LOG_DISPATCHER macro here because it would provide the
39 // exact signature that is needed here, the problem is though that this would expand the LOGLEVEL
40 // parameter, which is also a macro, into the value that the macro designates, which would generate
41 // the HaiCrypt_LogF_0 instead of HaiCrypt_LogF_LOG_DEBUG, for example.
42 #define HAICRYPT_DEFINE_LOG_DISPATCHER(LOGLEVEL, dispatcher) \
43     int HaiCrypt_LogF_##LOGLEVEL ( const char* file, int line, const char* function, const char* format, ...) \
44 { \
45     va_list ap; \
46     va_start(ap, format); \
47     srt_logging::LogDispatcher& lg = hclog.dispatcher; \
48     if (!lg.CheckEnabled()) return -1; \
49     lg().setloc(file, line, function).vform(format, ap); \
50     va_end(ap); \
51     return 0; \
52 }
53 
54 
55 HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_DEBUG, Debug);
56 HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_NOTICE, Note);
57 HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_INFO, Note);
58 HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_WARNING, Warn);
59 HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_ERR, Error);
60 HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_CRIT, Fatal);
61 HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_ALERT, Fatal);
62 HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_EMERG, Fatal);
63 
64 
DumpCfgFlags(int flags,std::ostream & out)65 static void DumpCfgFlags(int flags, std::ostream& out)
66 {
67     static struct { int flg; const char* desc; } flgtable [] = {
68 #define HCRYPTF(name) { HAICRYPT_CFG_F_##name, #name }
69         HCRYPTF(TX),
70         HCRYPTF(CRYPTO),
71         HCRYPTF(FEC)
72 #undef HCRYPTF
73     };
74     size_t flgtable_size = sizeof(flgtable)/sizeof(flgtable[0]);
75     size_t i;
76 
77     out << "{";
78     const char* sep = "";
79     const char* sep_bar = " | ";
80     for (i = 0; i < flgtable_size; ++i)
81     {
82         if ( (flgtable[i].flg & flags) != 0 )
83         {
84             out << sep << flgtable[i].desc;
85             sep = sep_bar;
86         }
87     }
88     out << "}";
89 }
90 
HaiCrypt_DumpConfig(const HaiCrypt_Cfg * cfg)91 void HaiCrypt_DumpConfig(const HaiCrypt_Cfg* cfg)
92 {
93     std::ostringstream cfg_flags;
94 
95     DumpCfgFlags(cfg->flags, cfg_flags);
96 
97     LOGC(hclog.Debug, log << "CFG DUMP: flags=" << cfg_flags.str()
98             << " xport=" << (cfg->xport == HAICRYPT_XPT_SRT ? "SRT" : "INVALID")
99             << " cipher="
100             << (cfg->cipher == HaiCryptCipher_OpenSSL_EVP_CTR() ? "OSSL-EVP-CTR":
101                 cfg->cipher == HaiCryptCipher_OpenSSL_AES() ? "OSSL-AES":
102                 // This below is used as the only one when Nettle is used. When OpenSSL
103                 // is used, one of the above will trigger, and the one below will then never trigger.
104                 cfg->cipher == HaiCryptCipher_Get_Instance() ? "Nettle-AES":
105                 "UNKNOWN")
106             << " key_len=" << cfg->key_len << " data_max_len=" << cfg->data_max_len);
107 
108 
109     LOGC(hclog.Debug, log << "CFG DUMP: txperiod="
110             << cfg->km_tx_period_ms << "ms kmrefresh=" << cfg->km_refresh_rate_pkt
111             << " kmpreannounce=" << cfg->km_pre_announce_pkt
112             << " secret "
113             << "{tp=" << (cfg->secret.typ == 1 ? "PSK" : cfg->secret.typ == 2 ? "PWD" : "???")
114             << " len=" << cfg->secret.len << " pwd=" << cfg->secret.str << "}");
115 
116 }
117 
118 } // extern "C"
119 
120 #endif // Block for the whole file
121