...

Source file src/github.com/letsencrypt/boulder/test/integration/common_mock.go

Documentation: github.com/letsencrypt/boulder/test/integration

     1  //go:build integration
     2  
     3  package integration
     4  
     5  import (
     6  	"bytes"
     7  	"crypto/x509"
     8  	"encoding/base64"
     9  	"encoding/json"
    10  	"fmt"
    11  	"net/http"
    12  
    13  	berrors "github.com/letsencrypt/boulder/errors"
    14  )
    15  
    16  var ctSrvPorts = []int{4600, 4601, 4602, 4603, 4604, 4605, 4606, 4607, 4608, 4609}
    17  
    18  // ctAddRejectHost adds a domain to all of the CT test server's reject-host
    19  // lists. If this fails the test is aborted with a fatal error.
    20  func ctAddRejectHost(domain string) error {
    21  	for _, port := range ctSrvPorts {
    22  		url := fmt.Sprintf("http://boulder.service.consul:%d/add-reject-host", port)
    23  		body := []byte(fmt.Sprintf(`{"host": %q}`, domain))
    24  		resp, err := http.Post(url, "", bytes.NewBuffer(body))
    25  		if err != nil {
    26  			return err
    27  		}
    28  		if resp.StatusCode != http.StatusOK {
    29  			return fmt.Errorf("adding reject host: %d", resp.StatusCode)
    30  		}
    31  		resp.Body.Close()
    32  	}
    33  	return nil
    34  }
    35  
    36  // ctGetRejections returns a slice of base64 encoded certificates that were
    37  // rejected by the CT test server at the specified port or an error.
    38  func ctGetRejections(port int) ([]string, error) {
    39  	url := fmt.Sprintf("http://boulder.service.consul:%d/get-rejections", port)
    40  	resp, err := http.Get(url)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	defer resp.Body.Close()
    45  	if resp.StatusCode != http.StatusOK {
    46  		return nil, fmt.Errorf(
    47  			"getting rejections: status %d", resp.StatusCode)
    48  	}
    49  	var rejections []string
    50  	err = json.NewDecoder(resp.Body).Decode(&rejections)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	return rejections, nil
    55  }
    56  
    57  // ctFindRejection returns a parsed x509.Certificate matching the given domains
    58  // from the base64 certificates any CT test server rejected. If no rejected
    59  // certificate matching the provided domains is found an error is returned.
    60  func ctFindRejection(domains []string) (*x509.Certificate, error) {
    61  	// Collect up rejections from all of the ctSrvPorts
    62  	var rejections []string
    63  	for _, port := range ctSrvPorts {
    64  		r, err := ctGetRejections(port)
    65  		if err != nil {
    66  			continue
    67  		}
    68  		rejections = append(rejections, r...)
    69  	}
    70  
    71  	// Parse each rejection cert
    72  	var cert *x509.Certificate
    73  RejectionLoop:
    74  	for _, r := range rejections {
    75  		precertDER, err := base64.StdEncoding.DecodeString(r)
    76  		if err != nil {
    77  			return nil, err
    78  		}
    79  		c, err := x509.ParseCertificate(precertDER)
    80  		if err != nil {
    81  			return nil, err
    82  		}
    83  		// If the cert doesn't have the right number of names it won't be a match.
    84  		if len(c.DNSNames) != len(domains) {
    85  			continue
    86  		}
    87  		// If any names don't match, it isn't a match
    88  		for i, name := range c.DNSNames {
    89  			if name != domains[i] {
    90  				continue RejectionLoop
    91  			}
    92  		}
    93  		// It's a match!
    94  		cert = c
    95  		break
    96  	}
    97  	if cert == nil {
    98  		return nil, berrors.NotFoundError("no matching ct-test-srv rejection found")
    99  	}
   100  	return cert, nil
   101  }
   102  

View as plain text