@@ -49,6 +49,20 @@ static int providerLogLevel = WP_LOG_LEVEL_ALL;
4949 * in wolfProv_LogComponents. Default components include all. */
5050static int providerLogComponents = WP_LOG_COMPONENTS_ALL ;
5151
52+ /* Callback functions to parse environment variables WOLFPROV_LOG_LEVEL and WOLFPROV_LOG_COMPONENTS */
53+ static void wolfProv_LogLevelToMask (const char * level , size_t len , void * ctx );
54+ static void wolfProv_LogComponentToMask (const char * level , size_t len , void * ctx );
55+
56+ /* Callback receives a pointer to the token (valid only during this call),
57+ * the token length (excluding the trailing '\0'), and an opaque context.
58+ */
59+ typedef void (* token_cb )(const char * token , size_t len , void * ctx );
60+ /* Parse environment variables WOLFPROV_LOG_LEVEL and WOLFPROV_LOG_COMPONENTS
61+ * in the form (WP_LOG_ERROR | WP_LOG_LEAVE).
62+ * See wp_logging.h for valid values */
63+ static int wolfProv_TokenParse (const char * input , const char * delims ,
64+ token_cb cb , void * ctx );
65+
5266#endif /* WOLFPROV_DEBUG */
5367
5468/**
@@ -98,6 +112,46 @@ void wolfProv_Debugging_OFF(void)
98112#endif
99113}
100114
115+ int wolfProv_LogInit (void )
116+ {
117+ #ifdef WOLFPROV_DEBUG
118+ #if defined(XGETENV ) && !defined(NO_GETENV )
119+ uint32_t level = 0 ;
120+ uint32_t components = 0 ;
121+ char * logLevelStr = XGETENV ("WOLFPROV_LOG_LEVEL" );
122+ char * logComponentsStr = XGETENV ("WOLFPROV_LOG_COMPONENTS" );
123+
124+ if (logLevelStr != NULL ) {
125+ if (wolfProv_TokenParse (logLevelStr , "()| \t" , wolfProv_LogLevelToMask ,
126+ & level ) == 0 ) {
127+ WOLFPROV_MSG (WP_LOG_PROVIDER ,
128+ "Setting WOLFPROV_LOG_LEVEL to 0x%X" , level );
129+ providerLogLevel = level ;
130+ }
131+ else {
132+ WOLFPROV_MSG (WP_LOG_PROVIDER ,
133+ "WOLFPROV_LOG_LEVEL environment variable too long or missing, "
134+ "ignoring it" );
135+ }
136+ }
137+ if (logComponentsStr != NULL ) {
138+ if (wolfProv_TokenParse (logComponentsStr , "()| \t" ,
139+ wolfProv_LogComponentToMask , & components ) == 0 ) {
140+ WOLFPROV_MSG (WP_LOG_PROVIDER ,
141+ "Setting WOLFPROV_LOG_COMPONENTS to 0x%X" , components );
142+ providerLogComponents = components ;
143+ }
144+ else {
145+ WOLFPROV_MSG (WP_LOG_PROVIDER ,
146+ "WOLFPROV_LOG_COMPONENTS environment variable too long or "
147+ "missing, ignoring it" );
148+ }
149+ }
150+ #endif
151+ #endif
152+ return 0 ;
153+ }
154+
101155/**
102156 * Set wolfProv logging level.
103157 * Default logging level for wolfProv is WP_LOG_LEVEL_DEFAULT.
@@ -182,7 +236,8 @@ static void wolfprovider_log(const int logLevel, const int component,
182236 if (logFileHandle == NULL ) {
183237 logFileHandle = XFOPEN (WOLFPROV_LOG_FILE , "a" );
184238 if (logFileHandle ) {
185- XFPRINTF (stderr , "wolfProvider: Using log file %s\n" , WOLFPROV_LOG_FILE );
239+ XFPRINTF (stderr , "wolfProvider: Using log file %s\n" ,
240+ WOLFPROV_LOG_FILE );
186241 fflush (stderr );
187242 }
188243 else {
@@ -535,5 +590,142 @@ void WOLFPROV_BUFFER(int component, const unsigned char* buffer,
535590 }
536591}
537592
593+ static void wolfProv_LogLevelToMask (const char * level , size_t len , void * ctx ) {
594+ /* Map strings to enum values.
595+ * Ensure this table is kept in sync with the enum in wp_logging.h */
596+ static const struct {
597+ const char * name ;
598+ size_t len ;
599+ uint32_t mask ;
600+ } log_levels [] = {
601+ { "WP_LOG_ERROR" , XSTRLEN ("WP_LOG_ERROR" ), WP_LOG_ERROR },
602+ { "WP_LOG_ENTER" , XSTRLEN ("WP_LOG_ENTER" ), WP_LOG_ENTER },
603+ { "WP_LOG_LEAVE" , XSTRLEN ("WP_LOG_LEAVE" ), WP_LOG_LEAVE },
604+ { "WP_LOG_INFO" , XSTRLEN ("WP_LOG_INFO" ), WP_LOG_INFO },
605+ { "WP_LOG_VERBOSE" , XSTRLEN ("WP_LOG_VERBOSE" ),WP_LOG_VERBOSE },
606+ { "WP_LOG_DEBUG" , XSTRLEN ("WP_LOG_DEBUG" ), WP_LOG_DEBUG },
607+ { "WP_LOG_TRACE" , XSTRLEN ("WP_LOG_TRACE" ), WP_LOG_TRACE },
608+ { "WP_LOG_LEVEL_DEFAULT" ,
609+ XSTRLEN ("WP_LOG_LEVEL_DEFAULT" ),
610+ WP_LOG_LEVEL_DEFAULT },
611+ { "WP_LOG_LEVEL_ALL" ,
612+ XSTRLEN ("WP_LOG_LEVEL_ALL" ),
613+ WP_LOG_LEVEL_ALL },
614+ };
615+ static const size_t num_levels = sizeof (log_levels ) / sizeof (log_levels [0 ]);
616+ uint32_t * mask = (uint32_t * )ctx ;
617+
618+ for (size_t i = 0 ; i < num_levels ; ++ i ) {
619+ if (log_levels [i ].len == len &&
620+ XSTRNCMP (level , log_levels [i ].name , len ) == 0 ) {
621+ * mask |= log_levels [i ].mask ;
622+ break ;
623+ }
624+ }
625+ }
626+
627+ static void wolfProv_LogComponentToMask (const char * level , size_t len , void * ctx ) {
628+ /* Map strings to enum values.
629+ * Ensure this table is kept in sync with the enum in wp_logging.h */
630+ static const struct {
631+ const char * name ;
632+ size_t len ;
633+ uint32_t mask ;
634+ } log_components [] = {
635+ { "WP_LOG_RNG" , XSTRLEN ("WP_LOG_RNG" ), WP_LOG_RNG },
636+ { "WP_LOG_DIGEST" , XSTRLEN ("WP_LOG_DIGEST" ), WP_LOG_DIGEST },
637+ { "WP_LOG_MAC" , XSTRLEN ("WP_LOG_MAC" ), WP_LOG_MAC },
638+ { "WP_LOG_CIPHER" , XSTRLEN ("WP_LOG_CIPHER" ), WP_LOG_CIPHER },
639+ { "WP_LOG_PK" , XSTRLEN ("WP_LOG_PK" ), WP_LOG_PK },
640+ { "WP_LOG_KE" , XSTRLEN ("WP_LOG_KE" ), WP_LOG_KE },
641+ { "WP_LOG_KDF" , XSTRLEN ("WP_LOG_KDF" ), WP_LOG_KDF },
642+ { "WP_LOG_PROVIDER" , XSTRLEN ("WP_LOG_PROVIDER" ), WP_LOG_PROVIDER },
643+ { "WP_LOG_RSA" , XSTRLEN ("WP_LOG_RSA" ), WP_LOG_RSA },
644+ { "WP_LOG_ECC" , XSTRLEN ("WP_LOG_ECC" ), WP_LOG_ECC },
645+ { "WP_LOG_DH" , XSTRLEN ("WP_LOG_DH" ), WP_LOG_DH },
646+ { "WP_LOG_AES" , XSTRLEN ("WP_LOG_AES" ), WP_LOG_AES },
647+ { "WP_LOG_DES" , XSTRLEN ("WP_LOG_DES" ), WP_LOG_DES },
648+ { "WP_LOG_SHA" , XSTRLEN ("WP_LOG_SHA" ), WP_LOG_SHA },
649+ { "WP_LOG_MD5" , XSTRLEN ("WP_LOG_MD5" ), WP_LOG_MD5 },
650+ { "WP_LOG_HMAC" , XSTRLEN ("WP_LOG_HMAC" ), WP_LOG_HMAC },
651+ { "WP_LOG_CMAC" , XSTRLEN ("WP_LOG_CMAC" ), WP_LOG_CMAC },
652+ { "WP_LOG_HKDF" , XSTRLEN ("WP_LOG_HKDF" ), WP_LOG_HKDF },
653+ { "WP_LOG_PBKDF2" , XSTRLEN ("WP_LOG_PBKDF2" ), WP_LOG_PBKDF2 },
654+ { "WP_LOG_KRB5KDF" , XSTRLEN ("WP_LOG_KRB5KDF" ), WP_LOG_KRB5KDF },
655+ { "WP_LOG_DRBG" , XSTRLEN ("WP_LOG_DRBG" ), WP_LOG_DRBG },
656+ { "WP_LOG_ECDSA" , XSTRLEN ("WP_LOG_ECDSA" ), WP_LOG_ECDSA },
657+ { "WP_LOG_ECDH" , XSTRLEN ("WP_LOG_ECDH" ), WP_LOG_ECDH },
658+ { "WP_LOG_ED25519" , XSTRLEN ("WP_LOG_ED25519" ), WP_LOG_ED25519 },
659+ { "WP_LOG_ED448" , XSTRLEN ("WP_LOG_ED448" ), WP_LOG_ED448 },
660+ { "WP_LOG_X25519" , XSTRLEN ("WP_LOG_X25519" ), WP_LOG_X25519 },
661+ { "WP_LOG_X448" , XSTRLEN ("WP_LOG_X448" ), WP_LOG_X448 },
662+ { "WP_LOG_QUERY" , XSTRLEN ("WP_LOG_QUERY" ), WP_LOG_QUERY },
663+ { "WP_LOG_TLS1_PRF" , XSTRLEN ("WP_LOG_TLS1_PRF" ), WP_LOG_TLS1_PRF },
664+ { "WP_LOG_COMPONENTS_ALL" ,
665+ XSTRLEN ("WP_LOG_COMPONENTS_ALL" ),
666+ WP_LOG_COMPONENTS_ALL },
667+ { "WP_LOG_COMPONENTS_DEFAULT" ,
668+ XSTRLEN ("WP_LOG_COMPONENTS_DEFAULT" ),
669+ WP_LOG_COMPONENTS_DEFAULT },
670+ };
671+ static const size_t num_components =
672+ sizeof (log_components ) / sizeof (log_components [0 ]);
673+ uint32_t * mask = (uint32_t * )ctx ;
674+
675+ for (size_t i = 0 ; i < num_components ; ++ i ) {
676+ if (log_components [i ].len == len &&
677+ XSTRNCMP (level , log_components [i ].name , len ) == 0 ) {
678+ * mask |= log_components [i ].mask ;
679+ break ;
680+ }
681+ }
682+ }
683+
684+ /* Returns number of tokens passed to cb,
685+ * 0 if input is NULL or empty,
686+ * -1 on allocation failure.
687+ */
688+ static int wolfProv_TokenParse (const char * input ,
689+ const char * delims , /* e.g. "()| \t" */
690+ token_cb cb ,
691+ void * ctx ) /* opaque context passed to cb */
692+ {
693+ if (!cb || !delims ) return -1 ;
694+ if (!input || !* input ) return 0 ;
695+
696+ char token [256 ];
697+ size_t n = XSTRLEN (input );
698+
699+ if (n < sizeof (token )) {
700+ /* Copy the input string to a writable buffer, including the trailing '\0' */
701+ XSTRNCPY (token , input , n + 1 );
702+ }
703+ else {
704+ return -1 ;
705+ }
706+
707+ /* Overwrite delimiters with '\0' using a simple nested loop. */
708+ for (size_t i = 0 ; i < n ; ++ i ) {
709+ for (const char * d = delims ; * d ; ++ d ) {
710+ if (token [i ] == * d ) {
711+ token [i ] = '\0' ;
712+ break ;
713+ }
714+ }
715+ }
716+
717+ /* Walk tokens: skip runs of NULs, emit non-empty spans. */
718+ for (size_t i = 0 ; i <= n ; i ++ ) {
719+ if (token [i ] == '\0' ) {
720+ continue ; /* skip empties */
721+ }
722+ size_t len = strlen (& token [i ]);
723+ cb (& token [i ], len , ctx );
724+ i += len ; /* hop past this token */
725+ }
726+
727+ return 0 ;
728+ }
729+
538730#endif /* WOLFPROV_DEBUG */
539731
0 commit comments