diff --git a/tlsobs-scanner/workerconfig.go b/tlsobs-scanner/workerconfig.go index 1fe9dc164..14c69de55 100644 --- a/tlsobs-scanner/workerconfig.go +++ b/tlsobs-scanner/workerconfig.go @@ -9,4 +9,5 @@ import ( _ "github.com/mozilla/tls-observatory/worker/sslLabsClientSupport" _ "github.com/mozilla/tls-observatory/worker/symantecDistrust" _ "github.com/mozilla/tls-observatory/worker/top1m" + _ "github.com/mozilla/tls-observatory/worker/ocspStatusWorker" ) diff --git a/worker/ocspStatusWorker/ocspStatusWorker.go b/worker/ocspStatusWorker/ocspStatusWorker.go new file mode 100644 index 000000000..bbf93471f --- /dev/null +++ b/worker/ocspStatusWorker/ocspStatusWorker.go @@ -0,0 +1,81 @@ +package ocspStatusWorker + +import ( + "encoding/json" + "io/ioutil" + "net/http" + "crypto/x509" + + "github.com/mozilla/tls-observatory/logger" + "github.com/mozilla/tls-observatory/worker" + "golang.org/x/crypto/ocsp" + "bytes" + "crypto" + "time" + "encoding/base64" +) + +var workerName = "ocspStatusWorker" +var workerDesc = `Determines a certificate's status via OCSP'` + +var log = logger.GetLogger() + +func init() { + worker.RegisterWorker(workerName, worker.Info{Runner: new(ocspStatusWorker), Description: workerDesc}) +} + +type ocspStatusWorker struct { + status OCSPStatus +} + +type OCSPStatus struct { + Status int `json:"status"` + RevokedAt time.Time `json:"revoked_at"` + +} + +type params struct { +} + +func (w ocspStatusWorker) Run(in worker.Input, resChan chan worker.Result) { + res := worker.Result{WorkerName: workerName, Success:false} + + rawCert, _ := base64.StdEncoding.DecodeString(in.CertificateChain.Certs[0]) + certificate, _ := x509.ParseCertificate(rawCert) + rawIssuerCert, _ := base64.StdEncoding.DecodeString(in.CertificateChain.Certs[1]) + issuerCertificate, _ := x509.ParseCertificate(rawIssuerCert) + + opts := &ocsp.RequestOptions{Hash: crypto.SHA256} + req, err := ocsp.CreateRequest(certificate, issuerCertificate, opts) + if err != nil { + res.Errors = append(res.Errors, err.Error()) + return + } + + httpResponse, err := http.Post(certificate.OCSPServer[0], "application/ocsp-request", bytes.NewReader(req)) + if err != nil { + res.Errors = append(res.Errors, err.Error()) + return + } + + output, err := ioutil.ReadAll(httpResponse.Body) + if err != nil { + res.Errors = append(res.Errors, err.Error()) + return + } + + OCSPResponse, err := ocsp.ParseResponse(output, issuerCertificate) + if err != nil { + res.Errors = append(res.Errors, err.Error()) + return + } + + status := OCSPStatus{ Status:OCSPResponse.Status, RevokedAt:OCSPResponse.RevokedAt } + + out, _ := json.Marshal(status) + + res.Success = true + res.Result = out + + resChan <- res +}