code: func loadCertificateChains(chainConfig map[string][]string) (map[string][]byte, error) {
  	results := make(map[string][]byte, len(chainConfig))
  
  	// For each AIA Issuer URL we need to read the chain cert files
  	for aiaIssuerURL, certFiles := range chainConfig {
  		var buffer bytes.Buffer
  
  		// There must be at least one chain file specified
  		if len(certFiles) == 0 {
  			return nil, fmt.Errorf(
  				"CertificateChain entry for AIA issuer url %q has no chain "+
  					"file names configured",
  				aiaIssuerURL)
  		}
  
  		// certFiles are read and appended in the order they appear in the
  		// configuration
  		for _, c := range certFiles {
  			// Prepend a newline before each chain entry
  			buffer.Write([]byte("\n"))
  
  			// Read and validate the chain file contents
  			pemBytes, err := loadCertificateFile(aiaIssuerURL, c)
  			if err != nil {
  				return nil, err
  			}
  
  			// Write the PEM bytes to the result buffer for this AIAIssuer
  			buffer.Write(pemBytes)
  		}
  
  		// Save the full PEM chain contents
  		results[aiaIssuerURL] = buffer.Bytes()
  	}
  	return results, nil
  }
docs: // loadCertificateChains processes the provided chainConfig of AIA Issuer URLs
  // and cert filenames. For each AIA issuer URL all of its cert filenames are
  // read, validated as PEM certificates, and concatenated together separated by
  // newlines. The combined PEM certificate chain contents for each are returned
  // in the results map, keyed by the AIA Issuer URL.