github.com/letsencrypt/boulder@v0.20251208.0/test/aia-test-srv/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "flag" 6 "fmt" 7 "net/http" 8 "net/url" 9 "os" 10 "path" 11 "regexp" 12 "strings" 13 "time" 14 15 "github.com/letsencrypt/boulder/cmd" 16 "github.com/letsencrypt/boulder/issuance" 17 ) 18 19 type aiaTestSrv struct { 20 issuersByName map[string]*issuance.Certificate 21 } 22 23 func (srv *aiaTestSrv) handleIssuer(w http.ResponseWriter, r *http.Request) { 24 issuerName, err := url.PathUnescape(r.URL.Path[1:]) 25 if err != nil { 26 w.WriteHeader(http.StatusBadRequest) 27 return 28 } 29 issuerName = strings.ReplaceAll(issuerName, "-", " ") 30 31 issuer, ok := srv.issuersByName[issuerName] 32 if !ok { 33 w.WriteHeader(http.StatusNotFound) 34 w.Write(fmt.Appendf(nil, "issuer %q not found", issuerName)) 35 return 36 } 37 38 w.Header().Set("Content-Type", "application/pkix-cert") 39 w.WriteHeader(http.StatusOK) 40 w.Write(issuer.Certificate.Raw) 41 } 42 43 // This regex excludes the "...-cross.cert.pem" files, since we don't serve our 44 // cross-signed certs at AIA URLs. 45 var issuerCertRegex = regexp.MustCompile(`int-(rsa|ecdsa)-[a-z]\.cert\.pem$`) 46 47 func main() { 48 listenAddr := flag.String("addr", "", "Address to listen on") 49 hierarchyDir := flag.String("hierarchy", "", "Directory to load certs from") 50 flag.Parse() 51 52 files, err := os.ReadDir(*hierarchyDir) 53 cmd.FailOnError(err, "opening hierarchy directory") 54 55 byName := make(map[string]*issuance.Certificate) 56 for _, file := range files { 57 if issuerCertRegex.Match([]byte(file.Name())) { 58 cert, err := issuance.LoadCertificate(path.Join(*hierarchyDir, file.Name())) 59 cmd.FailOnError(err, "loading issuer certificate") 60 61 name := cert.Certificate.Subject.CommonName 62 if _, found := byName[name]; found { 63 cmd.FailOnError(fmt.Errorf("loaded two certs with CN %q", name), "") 64 } 65 byName[name] = cert 66 } 67 } 68 69 srv := aiaTestSrv{ 70 issuersByName: byName, 71 } 72 73 http.HandleFunc("/", srv.handleIssuer) 74 75 s := http.Server{ 76 ReadTimeout: 30 * time.Second, 77 Addr: *listenAddr, 78 } 79 80 go func() { 81 err := s.ListenAndServe() 82 if err != nil && err != http.ErrServerClosed { 83 cmd.FailOnError(err, "Running TLS server") 84 } 85 }() 86 87 defer func() { 88 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 89 defer cancel() 90 _ = s.Shutdown(ctx) 91 }() 92 93 cmd.WaitForSignal() 94 }