@@ -7,12 +7,13 @@ import (
77 "context"
88 "crypto"
99 "crypto/rsa"
10+ "crypto/subtle"
1011 "encoding/base64"
1112 "encoding/json"
1213 "fmt"
13- "hash"
1414 "sort"
1515 "strings"
16+ "time"
1617
1718 "go.opentelemetry.io/collector/component"
1819 "go.opentelemetry.io/collector/consumer"
@@ -33,11 +34,13 @@ type certificateHashProcessor struct {
3334 logger * zap.Logger
3435 nextLogs consumer.Logs
3536 reader * CertificateReader
36- hashFunc func () hash .Hash
37+ hashAlgo crypto .Hash
3738}
3839
3940func newProcessor (cfg * Config , nextLogs consumer.Logs , settings processor.Settings ) (* certificateHashProcessor , error ) {
40- ctx := context .Background ()
41+ ctx , cancel := context .WithTimeout (context .Background (), 30 * time .Second )
42+ defer cancel ()
43+
4144 settings .Logger .Info ("Initializing certificate reader from Kubernetes secret for verification" ,
4245 zap .String ("secret" , cfg .K8sSecret .Name ),
4346 zap .String ("namespace" , cfg .K8sSecret .Namespace ),
@@ -46,7 +49,7 @@ func newProcessor(cfg *Config, nextLogs consumer.Logs, settings processor.Settin
4649 reader , err := NewCertificateReaderFromK8sSecretForVerification (ctx , cfg .K8sSecret , settings .Logger )
4750 if err != nil {
4851 settings .Logger .Error ("Failed to initialize certificate reader from k8s secret" ,
49- zap .String ( "error" , err . Error () ),
52+ zap .Error (err ),
5053 zap .String ("secret" , cfg .K8sSecret .Name ),
5154 zap .String ("namespace" , cfg .K8sSecret .Namespace ),
5255 )
@@ -57,17 +60,8 @@ func newProcessor(cfg *Config, nextLogs consumer.Logs, settings processor.Settin
5760 zap .String ("namespace" , cfg .K8sSecret .Namespace ),
5861 )
5962
60- var hashFunc func () hash.Hash
61- switch cfg .GetHash () {
62- case crypto .SHA256 :
63- hashFunc = func () hash.Hash {
64- return crypto .SHA256 .New ()
65- }
66- case crypto .SHA512 :
67- hashFunc = func () hash.Hash {
68- return crypto .SHA512 .New ()
69- }
70- default :
63+ hashAlgo := cfg .GetHash ()
64+ if hashAlgo != crypto .SHA256 && hashAlgo != crypto .SHA512 {
7165 return nil , fmt .Errorf ("unsupported hash algorithm" )
7266 }
7367
@@ -76,7 +70,7 @@ func newProcessor(cfg *Config, nextLogs consumer.Logs, settings processor.Settin
7670 logger : settings .Logger ,
7771 nextLogs : nextLogs ,
7872 reader : reader ,
79- hashFunc : hashFunc ,
73+ hashAlgo : hashAlgo ,
8074 }, nil
8175}
8276
@@ -118,13 +112,10 @@ func (p *certificateHashProcessor) verifyLogRecord(lr plog.LogRecord) error {
118112 return fmt .Errorf ("missing required attribute: %s" , signatureAttributeKey )
119113 }
120114
121- var signContent string
122115 signContentAttr , signContentExists := lr .Attributes ().Get (signContentAttributeKey )
123- if signContentExists {
116+ var signContent string
117+ if signContentExists && signContentAttr .Str () != "" {
124118 signContent = signContentAttr .Str ()
125- if signContent != SignContentBody && signContent != SignContentMeta && signContent != SignContentAttr {
126- return fmt .Errorf ("invalid sign_content value in log attribute: %s (must be body, meta, or attr)" , signContent )
127- }
128119 } else {
129120 signContent = p .config .SignContent
130121 if signContent == "" {
@@ -135,6 +126,13 @@ func (p *certificateHashProcessor) verifyLogRecord(lr plog.LogRecord) error {
135126 receivedHashBase64 := hashAttr .Str ()
136127 receivedSignatureBase64 := signatureAttr .Str ()
137128
129+ if receivedHashBase64 == "" {
130+ return fmt .Errorf ("hash attribute is empty" )
131+ }
132+ if receivedSignatureBase64 == "" {
133+ return fmt .Errorf ("signature attribute is empty" )
134+ }
135+
138136 receivedHash , err := base64 .StdEncoding .DecodeString (receivedHashBase64 )
139137 if err != nil {
140138 return fmt .Errorf ("failed to decode hash: %w" , err )
@@ -150,28 +148,47 @@ func (p *certificateHashProcessor) verifyLogRecord(lr plog.LogRecord) error {
150148 return fmt .Errorf ("failed to serialize log record: %w" , err )
151149 }
152150
153- h := p .hashFunc ()
151+ if len (logData ) == 0 {
152+ return fmt .Errorf ("serialized log data is empty (sign_content: %s)" , signContent )
153+ }
154+
155+ h := p .hashAlgo .New ()
154156 if _ , err := h .Write (logData ); err != nil {
155157 return fmt .Errorf ("failed to compute hash: %w" , err )
156158 }
157159 computedHash := h .Sum (nil )
158160
159161 if ! equalHashes (computedHash , receivedHash ) {
160- return fmt .Errorf ("hash mismatch: computed %x, received %x" , computedHash , receivedHash )
162+ p .logger .Info ("Hash mismatch detected" ,
163+ zap .String ("algorithm" , p .config .HashAlgorithm ),
164+ zap .String ("sign_content" , signContent ),
165+ zap .String ("computed_hash" , fmt .Sprintf ("%x" , computedHash )),
166+ zap .String ("received_hash" , fmt .Sprintf ("%x" , receivedHash )),
167+ )
168+ return fmt .Errorf ("hash mismatch (algorithm: %s, sign_content: %s): computed %x, received %x" ,
169+ p .config .HashAlgorithm , signContent , computedHash , receivedHash )
170+ }
171+
172+ if p .reader == nil {
173+ return fmt .Errorf ("certificate reader is nil" )
161174 }
162175
163176 cert := p .reader .GetCertificate ()
177+ if cert == nil {
178+ return fmt .Errorf ("certificate is nil" )
179+ }
180+
164181 publicKey , ok := cert .PublicKey .(* rsa.PublicKey )
165182 if ! ok {
166183 return fmt .Errorf ("certificate public key is not RSA" )
167184 }
168185
169- err = rsa .VerifyPKCS1v15 (publicKey , p .config . GetHash () , computedHash , receivedSignature )
186+ err = rsa .VerifyPKCS1v15 (publicKey , p .hashAlgo , computedHash , receivedSignature )
170187 if err != nil {
171- return fmt .Errorf ("signature verification failed: %w" , err )
188+ return fmt .Errorf ("signature verification failed (algorithm : %s): %w" , p . config . HashAlgorithm , err )
172189 }
173190
174- p .logger .Debug ("Log record verification successful" ,
191+ p .logger .Info ("Log record verification successful" ,
175192 zap .String ("sign_content" , signContent ),
176193 )
177194
@@ -283,15 +300,7 @@ func (p *certificateHashProcessor) valueToInterface(v pcommon.Value) interface{}
283300}
284301
285302func equalHashes (a , b []byte ) bool {
286- if len (a ) != len (b ) {
287- return false
288- }
289- for i := range a {
290- if a [i ] != b [i ] {
291- return false
292- }
293- }
294- return true
303+ return len (a ) == len (b ) && subtle .ConstantTimeCompare (a , b ) == 1
295304}
296305
297306func (p * certificateHashProcessor ) Start (_ context.Context , _ component.Host ) error {
0 commit comments