"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "test/ocsp/helper/helper.go" between
boulder-release-2020-06-23.tar.gz and boulder-release-2020-06-29.tar.gz

About: Boulder is an ACME-based Certificate Authority (CA) used by Let’s Encrypt (written in Go).

helper.go  (boulder-release-2020-06-23):helper.go  (boulder-release-2020-06-29)
skipping to change at line 14 skipping to change at line 14
"bytes" "bytes"
"crypto/x509" "crypto/x509"
"encoding/asn1" "encoding/asn1"
"encoding/base64" "encoding/base64"
"encoding/pem" "encoding/pem"
"flag" "flag"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/url" "net/url"
"sync"
"time" "time"
"golang.org/x/crypto/ocsp" "golang.org/x/crypto/ocsp"
) )
var method = flag.String("method", "GET", "Method to use for fetching OCSP") var (
var urlOverride = flag.String("url", "", "URL of OCSP responder to override") method = flag.String("method", "GET", "Method to use for fetc
var hostOverride = flag.String("host", "", "Host header to override in HTTP requ hing OCSP")
est") urlOverride = flag.String("url", "", "URL of OCSP responder to ove
var tooSoon = flag.Int("too-soon", 76, "If NextUpdate is fewer than this many ho rride")
urs in future, warn.") hostOverride = flag.String("host", "", "Host header to override in
var ignoreExpiredCerts = flag.Bool("ignore-expired-certs", false, "If a cert is HTTP request")
expired, don't bother requesting OCSP.") tooSoon = flag.Int("too-soon", 76, "If NextUpdate is fewer tha
var expectStatus = flag.Int("expect-status", 0, "Expect response to have this nu n this many hours in future, warn.")
meric status (0=good, 1=revoked)") ignoreExpiredCerts = flag.Bool("ignore-expired-certs", false, "If a cert
is expired, don't bother requesting OCSP.")
expectStatus = flag.Int("expect-status", 0, "Expect response to hav
e this numeric status (0=Good, 1=Revoked, 2=Unknown); or -1 for no enforcement."
)
expectReason = flag.Int("expect-reason", -1, "Expect response to ha
ve this numeric revocation reason (0=Unspecified, 1=KeyCompromise, etc); or -1 f
or no enforcement.")
)
// Config contains fields which control various behaviors of the
// checker's behavior.
type Config struct {
method string
urlOverride string
hostOverride string
tooSoon int
ignoreExpiredCerts bool
expectStatus int
expectReason int
}
// DefaultConfig is a Config populated with the same defaults as if no
// command-line had been provided, so all retain their default value.
var DefaultConfig = Config{
method: *method,
urlOverride: *urlOverride,
hostOverride: *hostOverride,
tooSoon: *tooSoon,
ignoreExpiredCerts: *ignoreExpiredCerts,
expectStatus: *expectStatus,
expectReason: *expectReason,
}
var parseFlagsOnce sync.Once
// ConfigFromFlags returns a Config whose values are populated from
// any command line flags passed by the user, or default values if not passed.
func ConfigFromFlags() Config {
parseFlagsOnce.Do(func() {
flag.Parse()
})
return Config{
method: *method,
urlOverride: *urlOverride,
hostOverride: *hostOverride,
tooSoon: *tooSoon,
ignoreExpiredCerts: *ignoreExpiredCerts,
expectStatus: *expectStatus,
expectReason: *expectReason,
}
}
// WithExpectStatus returns a new Config with the given expectStatus,
// and all other fields the same as the receiver.
func (template Config) WithExpectStatus(status int) Config {
ret := template
ret.expectStatus = status
return ret
}
func getIssuer(cert *x509.Certificate) (*x509.Certificate, error) { func getIssuer(cert *x509.Certificate) (*x509.Certificate, error) {
if cert == nil { if cert == nil {
return nil, fmt.Errorf("nil certificate") return nil, fmt.Errorf("nil certificate")
} }
if len(cert.IssuingCertificateURL) == 0 { if len(cert.IssuingCertificateURL) == 0 {
return nil, fmt.Errorf("No AIA information available, can't get i ssuer") return nil, fmt.Errorf("No AIA information available, can't get i ssuer")
} }
issuerURL := cert.IssuingCertificateURL[0] issuerURL := cert.IssuingCertificateURL[0]
resp, err := http.Get(issuerURL) resp, err := http.Get(issuerURL)
skipping to change at line 95 skipping to change at line 150
if err != nil { if err != nil {
return nil, fmt.Errorf("parsing CMS: %s", err) return nil, fmt.Errorf("parsing CMS: %s", err)
} }
cert, err := x509.ParseCertificate(msg.SignedData.Certificates.Bytes) cert, err := x509.ParseCertificate(msg.SignedData.Certificates.Bytes)
if err != nil { if err != nil {
return nil, fmt.Errorf("parsing CMS: %s", err) return nil, fmt.Errorf("parsing CMS: %s", err)
} }
return cert, nil return cert, nil
} }
func Req(fileName string) (*ocsp.Response, error) { // Req makes an OCSP request using the given config for the PEM certificate in
// fileName, and returns the response.
func Req(fileName string, config Config) (*ocsp.Response, error) {
contents, err := ioutil.ReadFile(fileName) contents, err := ioutil.ReadFile(fileName)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return ReqDER(contents, *expectStatus) return ReqDER(contents, config)
} }
func ReqDER(der []byte, expectStatus int) (*ocsp.Response, error) { // ReqDER makes an OCSP request using the given config for the given DER-encoded
// certificate, and returns the response.
func ReqDER(der []byte, config Config) (*ocsp.Response, error) {
cert, err := parse(der) cert, err := parse(der)
if err != nil { if err != nil {
return nil, fmt.Errorf("parsing certificate: %s", err) return nil, fmt.Errorf("parsing certificate: %s", err)
} }
if time.Now().After(cert.NotAfter) { if time.Now().After(cert.NotAfter) {
if *ignoreExpiredCerts { if config.ignoreExpiredCerts {
return nil, nil return nil, nil
} else { } else {
return nil, fmt.Errorf("certificate expired %s ago: %s", return nil, fmt.Errorf("certificate expired %s ago: %s",
time.Since(cert.NotAfter), cert.NotAfter) time.Since(cert.NotAfter), cert.NotAfter)
} }
} }
issuer, err := getIssuer(cert) issuer, err := getIssuer(cert)
if err != nil { if err != nil {
return nil, fmt.Errorf("getting issuer: %s", err) return nil, fmt.Errorf("getting issuer: %s", err)
} }
req, err := ocsp.CreateRequest(cert, issuer, nil) req, err := ocsp.CreateRequest(cert, issuer, nil)
if err != nil { if err != nil {
return nil, fmt.Errorf("creating OCSP request: %s", err) return nil, fmt.Errorf("creating OCSP request: %s", err)
} }
ocspURL, err := getOCSPURL(cert) ocspURL, err := getOCSPURL(cert, config.urlOverride)
if err != nil { if err != nil {
return nil, err return nil, err
} }
httpResp, err := sendHTTPRequest(req, ocspURL) httpResp, err := sendHTTPRequest(req, ocspURL, config.method, config.host Override)
if err != nil { if err != nil {
return nil, err return nil, err
} }
fmt.Printf("HTTP %d\n", httpResp.StatusCode) fmt.Printf("HTTP %d\n", httpResp.StatusCode)
for k, v := range httpResp.Header { for k, v := range httpResp.Header {
for _, vv := range v { for _, vv := range v {
fmt.Printf("%s: %s\n", k, vv) fmt.Printf("%s: %s\n", k, vv)
} }
} }
if httpResp.StatusCode != 200 { if httpResp.StatusCode != 200 {
return nil, fmt.Errorf("http status code %d", httpResp.StatusCode ) return nil, fmt.Errorf("http status code %d", httpResp.StatusCode )
} }
respBytes, err := ioutil.ReadAll(httpResp.Body) respBytes, err := ioutil.ReadAll(httpResp.Body)
defer httpResp.Body.Close() defer httpResp.Body.Close()
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(respBytes) == 0 { if len(respBytes) == 0 {
return nil, fmt.Errorf("empty response body") return nil, fmt.Errorf("empty response body")
} }
return parseAndPrint(respBytes, cert, issuer, expectStatus) return parseAndPrint(respBytes, cert, issuer, config)
} }
func sendHTTPRequest(req []byte, ocspURL *url.URL) (*http.Response, error) { func sendHTTPRequest(req []byte, ocspURL *url.URL, method string, host string) ( *http.Response, error) {
encodedReq := base64.StdEncoding.EncodeToString(req) encodedReq := base64.StdEncoding.EncodeToString(req)
var httpRequest *http.Request var httpRequest *http.Request
var err error var err error
if *method == "GET" { if method == "GET" {
ocspURL.Path = encodedReq ocspURL.Path = encodedReq
fmt.Printf("Fetching %s\n", ocspURL.String()) fmt.Printf("Fetching %s\n", ocspURL.String())
httpRequest, err = http.NewRequest("GET", ocspURL.String(), http. NoBody) httpRequest, err = http.NewRequest("GET", ocspURL.String(), http. NoBody)
} else if *method == "POST" { } else if method == "POST" {
fmt.Printf("POSTing request, reproduce with: curl -i --data-binar y @- %s < <(base64 -d <<<%s)\n", fmt.Printf("POSTing request, reproduce with: curl -i --data-binar y @- %s < <(base64 -d <<<%s)\n",
ocspURL, encodedReq) ocspURL, encodedReq)
httpRequest, err = http.NewRequest("POST", ocspURL.String(), byte s.NewBuffer(req)) httpRequest, err = http.NewRequest("POST", ocspURL.String(), byte s.NewBuffer(req))
} else { } else {
return nil, fmt.Errorf("invalid method %s, expected GET or POST", *method) return nil, fmt.Errorf("invalid method %s, expected GET or POST", method)
} }
if err != nil { if err != nil {
return nil, err return nil, err
} }
httpRequest.Header.Add("Content-Type", "application/ocsp-request") httpRequest.Header.Add("Content-Type", "application/ocsp-request")
if *hostOverride != "" { if host != "" {
httpRequest.Host = *hostOverride httpRequest.Host = host
} }
client := http.Client{ client := http.Client{
Timeout: 5 * time.Second, Timeout: 5 * time.Second,
} }
return client.Do(httpRequest) return client.Do(httpRequest)
} }
func getOCSPURL(cert *x509.Certificate) (*url.URL, error) { func getOCSPURL(cert *x509.Certificate, urlOverride string) (*url.URL, error) {
var ocspServer string var ocspServer string
if *urlOverride != "" { if urlOverride != "" {
ocspServer = *urlOverride ocspServer = urlOverride
} else if len(cert.OCSPServer) > 0 { } else if len(cert.OCSPServer) > 0 {
ocspServer = cert.OCSPServer[0] ocspServer = cert.OCSPServer[0]
} else { } else {
return nil, fmt.Errorf("no ocsp servers in cert") return nil, fmt.Errorf("no ocsp servers in cert")
} }
ocspURL, err := url.Parse(ocspServer) ocspURL, err := url.Parse(ocspServer)
if err != nil { if err != nil {
return nil, fmt.Errorf("parsing URL: %s", err) return nil, fmt.Errorf("parsing URL: %s", err)
} }
return ocspURL, nil return ocspURL, nil
skipping to change at line 230 skipping to change at line 289
if time.Now().After(ocspSigner.NotAfter) { if time.Now().After(ocspSigner.NotAfter) {
return fmt.Errorf("OCSP signer (%s) expired at %s", ocspSigner.Su bject, ocspSigner.NotAfter) return fmt.Errorf("OCSP signer (%s) expired at %s", ocspSigner.Su bject, ocspSigner.NotAfter)
} }
if time.Now().Before(ocspSigner.NotBefore) { if time.Now().Before(ocspSigner.NotBefore) {
return fmt.Errorf("OCSP signer (%s) not valid until %s", ocspSign er.Subject, ocspSigner.NotBefore) return fmt.Errorf("OCSP signer (%s) not valid until %s", ocspSign er.Subject, ocspSigner.NotBefore)
} }
return nil return nil
} }
func parseAndPrint(respBytes []byte, cert, issuer *x509.Certificate, expectStatu s int) (*ocsp.Response, error) { func parseAndPrint(respBytes []byte, cert, issuer *x509.Certificate, config Conf ig) (*ocsp.Response, error) {
fmt.Printf("\nDecoding body: %s\n", base64.StdEncoding.EncodeToString(res pBytes)) fmt.Printf("\nDecoding body: %s\n", base64.StdEncoding.EncodeToString(res pBytes))
resp, err := ocsp.ParseResponseForCert(respBytes, cert, issuer) resp, err := ocsp.ParseResponseForCert(respBytes, cert, issuer)
if err != nil { if err != nil {
return nil, fmt.Errorf("parsing response: %s", err) return nil, fmt.Errorf("parsing response: %s", err)
} }
if resp.Status != expectStatus { if config.expectStatus != -1 && resp.Status != config.expectStatus {
return nil, fmt.Errorf("wrong CertStatus %d, expected %d", resp.S return nil, fmt.Errorf("wrong CertStatus %d, expected %d", resp.S
tatus, expectStatus) tatus, config.expectStatus)
}
if config.expectReason != -1 && resp.RevocationReason != config.expectRea
son {
return nil, fmt.Errorf("wrong RevocationReason %d, expected %d",
resp.RevocationReason, config.expectReason)
} }
timeTilExpiry := time.Until(resp.NextUpdate) timeTilExpiry := time.Until(resp.NextUpdate)
tooSoonDuration := time.Duration(*tooSoon) * time.Hour tooSoonDuration := time.Duration(config.tooSoon) * time.Hour
if timeTilExpiry < tooSoonDuration { if timeTilExpiry < tooSoonDuration {
return nil, fmt.Errorf("NextUpdate is too soon: %s", timeTilExpir y) return nil, fmt.Errorf("NextUpdate is too soon: %s", timeTilExpir y)
} }
err = checkSignerTimes(resp, issuer) err = checkSignerTimes(resp, issuer)
if err != nil { if err != nil {
return nil, fmt.Errorf("checking signature on delegated signer: % s", err) return nil, fmt.Errorf("checking signature on delegated signer: % s", err)
} }
fmt.Printf("\n") fmt.Printf("\n")
 End of changes. 19 change blocks. 
31 lines changed or deleted 100 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)