1 // Copyright 2017 Google LLC. All Rights Reserved. 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 package ctfe 16 17 import ( 18 "context" 19 "encoding/hex" 20 "time" 21 22 "github.com/google/certificate-transparency-go/x509" 23 "github.com/google/certificate-transparency-go/x509util" 24 "k8s.io/klog/v2" 25 ) 26 27 const vLevel = 9 28 29 // RequestLog allows implementations to do structured logging of CTFE 30 // request parameters, submitted chains and other internal details that 31 // are useful for log operators when debugging issues. CTFE handlers will 32 // call the appropriate methods during request processing. The implementation 33 // is responsible for collating and storing the resulting logging information. 34 type RequestLog interface { 35 // Start will be called once at the beginning of handling each request. 36 // The supplied context will be the one used for request processing and 37 // can be used by the logger to set values on the returned context. 38 // The returned context should be used in all the following calls to 39 // this API. This is normally arranged by the request handler code. 40 Start(context.Context) context.Context 41 // LogPrefix will be called once per request to set the log prefix. 42 LogPrefix(context.Context, string) 43 // AddDERToChain will be called once for each certificate in a submitted 44 // chain. It's called early in request processing so the supplied bytes 45 // have not been checked for validity. Calls will be in order of the 46 // certificates as presented in the request with the root last. 47 AddDERToChain(context.Context, []byte) 48 // AddCertToChain will be called once for each certificate in the chain 49 // after it has been parsed and verified. Calls will be in order of the 50 // certificates as presented in the request with the root last. 51 AddCertToChain(context.Context, *x509.Certificate) 52 // FirstAndSecond will be called once for a consistency proof request with 53 // the first and second tree sizes involved (if they parse correctly). 54 FirstAndSecond(context.Context, int64, int64) 55 // StartAndEnd will be called once for a get entries request with the 56 // endpoints of the range requested (if they parse correctly). 57 StartAndEnd(context.Context, int64, int64) 58 // LeafIndex will be called once with the index of a leaf being requested 59 // by get entry and proof (if the request params parse correctly). 60 LeafIndex(context.Context, int64) 61 // TreeSize will be called once with the requested tree size for get entry 62 // and proof requests (if the request params parse correctly). 63 TreeSize(context.Context, int64) 64 // LeafHash will be called once for get proof by hash requests with the 65 // requested hash value (if the parameters parse correctly). 66 LeafHash(context.Context, []byte) 67 // IssueSCT will be called once when the server is about to issue an SCT to a 68 // client. This should not be called if the submission process fails before an 69 // SCT could be presented to a client, even if this is unrelated to 70 // the validity of the submitted chain. The SCT bytes will be in TLS 71 // serialized format. 72 IssueSCT(context.Context, []byte) 73 // Status will be called once to set the HTTP status code that was the 74 // the result after the request has been handled. 75 Status(context.Context, int) 76 } 77 78 // DefaultRequestLog is an implementation of RequestLog that does nothing 79 // except log the calls at a high level of verbosity. 80 type DefaultRequestLog struct { 81 } 82 83 // Start logs the start of request processing. 84 func (dlr *DefaultRequestLog) Start(ctx context.Context) context.Context { 85 klog.V(vLevel).Info("RL: Start") 86 return ctx 87 } 88 89 // LogPrefix logs the prefix of the CT log that this request is for. 90 func (dlr *DefaultRequestLog) LogPrefix(_ context.Context, p string) { 91 klog.V(vLevel).Infof("RL: LogPrefix: %s", p) 92 } 93 94 // AddDERToChain logs the raw bytes of a submitted certificate. 95 func (dlr *DefaultRequestLog) AddDERToChain(_ context.Context, d []byte) { 96 // Explicit hex encoding below to satisfy CodeQL: 97 klog.V(vLevel).Infof("RL: Cert DER: %s", hex.EncodeToString(d)) 98 } 99 100 // AddCertToChain logs some issuer / subject / timing fields from a 101 // certificate that is part of a submitted chain. 102 func (dlr *DefaultRequestLog) AddCertToChain(_ context.Context, cert *x509.Certificate) { 103 klog.V(vLevel).Infof("RL: Cert: Sub: %s Iss: %s notBef: %s notAft: %s", 104 x509util.NameToString(cert.Subject), 105 x509util.NameToString(cert.Issuer), 106 cert.NotBefore.Format(time.RFC1123Z), 107 cert.NotAfter.Format(time.RFC1123Z)) 108 } 109 110 // FirstAndSecond logs request parameters. 111 func (dlr *DefaultRequestLog) FirstAndSecond(_ context.Context, f, s int64) { 112 klog.V(vLevel).Infof("RL: First: %d Second: %d", f, s) 113 } 114 115 // StartAndEnd logs request parameters. 116 func (dlr *DefaultRequestLog) StartAndEnd(_ context.Context, s, e int64) { 117 klog.V(vLevel).Infof("RL: Start: %d End: %d", s, e) 118 } 119 120 // LeafIndex logs request parameters. 121 func (dlr *DefaultRequestLog) LeafIndex(_ context.Context, li int64) { 122 klog.V(vLevel).Infof("RL: LeafIndex: %d", li) 123 } 124 125 // TreeSize logs request parameters. 126 func (dlr *DefaultRequestLog) TreeSize(_ context.Context, ts int64) { 127 klog.V(vLevel).Infof("RL: TreeSize: %d", ts) 128 } 129 130 // LeafHash logs request parameters. 131 func (dlr *DefaultRequestLog) LeafHash(_ context.Context, lh []byte) { 132 // Explicit hex encoding below to satisfy CodeQL: 133 klog.V(vLevel).Infof("RL: LeafHash: %s", hex.EncodeToString(lh)) 134 } 135 136 // IssueSCT logs an SCT that will be issued to a client. 137 func (dlr *DefaultRequestLog) IssueSCT(_ context.Context, sct []byte) { 138 klog.V(vLevel).Infof("RL: Issuing SCT: %x", sct) 139 } 140 141 // Status logs the response HTTP status code after processing completes. 142 func (dlr *DefaultRequestLog) Status(_ context.Context, s int) { 143 klog.V(vLevel).Infof("RL: Status: %d", s) 144 } 145