-
Notifications
You must be signed in to change notification settings - Fork 88
Added OCSP worker to retrieve certificate status #286
Changes from 5 commits
7d8b2ef
279c152
3558cf7
91e434f
e8f9ab8
8777904
d660338
f8e5276
0117572
504ca32
701157e
b386954
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the end entity is already parsed in |
||
| rawIssuerCert, _ := base64.StdEncoding.DecodeString(in.CertificateChain.Certs[1]) | ||
| issuerCertificate, _ := x509.ParseCertificate(rawIssuerCert) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should check for errors here. It might also be worthwhile to make sure the issuer is the right one (that it sign the end-entity) because ordering isn't always guaranteed. You can use CheckSignatureFrom from the x509 package for this. |
||
|
|
||
| opts := &ocsp.RequestOptions{Hash: crypto.SHA256} | ||
| req, err := ocsp.CreateRequest(certificate, issuerCertificate, opts) | ||
| if err != nil { | ||
| res.Errors = append(res.Errors, err.Error()) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. errors need to be inserted into the response channel, otherwise they will be dropped. Something like this: func (w runner) error(res chan worker.Result, messageFormat string, args ...interface{}) {
out, _ := json.Marshal(fmt.Sprintf(messageFormat, args...))
res <- worker.Result{
Success: false,
WorkerName: workerName,
Result: out,
}
}and use it as follows: if err != nil {
w.error(res, "there was an error: %v", err)
return
} |
||
| 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 | ||
| } | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a |
||
| 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) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't ignore errors, you never know what the OCSP response will contain |
||
|
|
||
| res.Success = true | ||
| res.Result = out | ||
|
|
||
| resChan <- res | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: remove "Worker" from the name, it's already under /worker/