github.com/secure-build/gitlab-runner@v12.5.0+incompatible/helpers/tls/ca_chain/resolver_verify.go (about)

     1  // Inspired by https://github.com/zakjan/cert-chain-resolver/blob/master/certUtil/chain.go
     2  // which is licensed on a MIT license.
     3  //
     4  // Shout out to Jan Žák (http://zakjan.cz) original author of `certUtil` package and other
     5  // contributors who updated it!
     6  
     7  package ca_chain
     8  
     9  import (
    10  	"crypto/x509"
    11  	"fmt"
    12  
    13  	"github.com/sirupsen/logrus"
    14  )
    15  
    16  type verifier func(cert *x509.Certificate) ([][]*x509.Certificate, error)
    17  
    18  type verifyResolver struct {
    19  	logger   logrus.FieldLogger
    20  	verifier verifier
    21  }
    22  
    23  func newVerifyResolver(logger logrus.FieldLogger) resolver {
    24  	return &verifyResolver{
    25  		logger:   logger,
    26  		verifier: verifyCertificate,
    27  	}
    28  }
    29  
    30  func (r *verifyResolver) Resolve(certs []*x509.Certificate) ([]*x509.Certificate, error) {
    31  	if len(certs) < 1 {
    32  		return certs, nil
    33  	}
    34  
    35  	lastCert := certs[len(certs)-1]
    36  
    37  	if isSelfSigned(lastCert) {
    38  		return certs, nil
    39  	}
    40  
    41  	prepareCertificateLogger(r.logger, lastCert).
    42  		Debug("Verifying last certificate to find the final root certificate")
    43  
    44  	verifyChains, err := r.verifier(lastCert)
    45  	if err != nil {
    46  		_, ok := err.(x509.UnknownAuthorityError)
    47  		if ok {
    48  			prepareCertificateLogger(r.logger, lastCert).
    49  				WithError(err).
    50  				Warning("Last certificate signed by unknown authority; will not update the chain")
    51  
    52  			return certs, nil
    53  		}
    54  
    55  		return nil, fmt.Errorf("error while verifying last certificate from the chain: %v", err)
    56  	}
    57  
    58  	for _, cert := range verifyChains[0] {
    59  		if lastCert.Equal(cert) {
    60  			continue
    61  		}
    62  
    63  		prepareCertificateLogger(r.logger, cert).
    64  			Debug("Adding cert from verify chain to the final chain")
    65  
    66  		certs = append(certs, cert)
    67  	}
    68  
    69  	return certs, nil
    70  }