github.com/ztalab/ZACA@v0.0.1/pkg/caclient/ocsp_impl.go (about)

     1  package caclient
     2  
     3  import (
     4  	"bytes"
     5  	"crypto"
     6  	"crypto/x509"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"net/http"
    10  	"sync/atomic"
    11  
    12  	"golang.org/x/crypto/ocsp"
    13  	"golang.org/x/sync/singleflight"
    14  
    15  	"github.com/pkg/errors"
    16  	"github.com/ztalab/ZACA/pkg/logger"
    17  )
    18  
    19  var ocspBlockSign int64 = 0
    20  
    21  var sg = new(singleflight.Group)
    22  
    23  var ocspOpts = ocsp.RequestOptions{
    24  	Hash: crypto.SHA1,
    25  }
    26  
    27  func SendOcspRequest(server string, req []byte, leaf, issuer *x509.Certificate) (*ocsp.Response, error) {
    28  	if server == "" {
    29  		server = leaf.OCSPServer[0]
    30  	}
    31  	var resp *http.Response
    32  	var err error
    33  	buf := bytes.NewBuffer(req)
    34  	resp, err = httpClient.Post(server, "application/ocsp-request", buf)
    35  
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	body, err := ioutil.ReadAll(resp.Body)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	defer resp.Body.Close()
    45  
    46  	if resp.StatusCode != http.StatusOK {
    47  		logger.With("url", server, resp.Status, "body", string(body)).
    48  			Warnf("Request error")
    49  		return nil, fmt.Errorf("ocsp response err: %v", resp.Status)
    50  	}
    51  
    52  	switch {
    53  	case bytes.Equal(body, ocsp.UnauthorizedErrorResponse):
    54  		return nil, errors.New("OSCP unauthorized")
    55  	case bytes.Equal(body, ocsp.MalformedRequestErrorResponse):
    56  		return nil, errors.New("OSCP malformed")
    57  	case bytes.Equal(body, ocsp.InternalErrorErrorResponse):
    58  		return nil, errors.New("OSCP internal error")
    59  	case bytes.Equal(body, ocsp.TryLaterErrorResponse):
    60  		return nil, errors.New("OSCP try later")
    61  	case bytes.Equal(body, ocsp.SigRequredErrorResponse):
    62  		return nil, errors.New("OSCP signature required")
    63  	}
    64  
    65  	parsedOcspResp, err := ocsp.ParseResponseForCert(body, leaf, issuer)
    66  	if err != nil {
    67  		logger.With("body", string(body)).Errorf("ocsp Parsing error: %v", err)
    68  		return nil, errors.Wrap(err, "ocsp Parsing error")
    69  	}
    70  
    71  	return parsedOcspResp, nil
    72  }
    73  
    74  // BlockOcspRequests Blocking OCSP requests will cause the MTLs handshake to fail
    75  func BlockOcspRequests() {
    76  	atomic.StoreInt64(&ocspBlockSign, 1)
    77  }
    78  
    79  // AllowOcspRequests
    80  func AllowOcspRequests() {
    81  	atomic.StoreInt64(&ocspBlockSign, 0)
    82  }