golang.org/x/build@v0.0.0-20240506185731-218518f32b70/cmd/genbuilderkey/genbuilderkey.go (about)

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // The genbuilderkey binary generates a builder key or gomote user key
     6  // from the build system's master key.
     7  package main
     8  
     9  import (
    10  	"bytes"
    11  	"context"
    12  	"crypto/hmac"
    13  	"crypto/md5"
    14  	"flag"
    15  	"fmt"
    16  	"io"
    17  	"log"
    18  	"os"
    19  	"path/filepath"
    20  	"strings"
    21  
    22  	"golang.org/x/build/buildenv"
    23  	"golang.org/x/build/internal/secret"
    24  )
    25  
    26  func usage() {
    27  	fmt.Fprintln(os.Stderr, "Usage: genbuilderkey <Host Type>")
    28  	fmt.Fprintln(os.Stderr)
    29  	fmt.Fprintln(os.Stderr, "Master builder key should be available to genbuilderkey by either:")
    30  	fmt.Fprintln(os.Stderr, " - Secret Management: executing genbuilderkey with access to secret management")
    31  	fmt.Fprintln(os.Stderr, " - File: $HOME/keys/gobuilder-master.key")
    32  	fmt.Fprintln(os.Stderr)
    33  	fmt.Fprintln(os.Stderr, "Flags:")
    34  	flag.PrintDefaults()
    35  }
    36  
    37  func main() {
    38  	flag.Usage = usage
    39  	buildenv.RegisterStagingFlag()
    40  	flag.Parse()
    41  	if flag.NArg() != 1 {
    42  		flag.Usage()
    43  		os.Exit(2)
    44  	}
    45  	fmt.Println(key(flag.Arg(0)))
    46  }
    47  
    48  func key(principal string) string {
    49  	h := hmac.New(md5.New, getMasterKey())
    50  	io.WriteString(h, principal)
    51  	return fmt.Sprintf("%x", h.Sum(nil))
    52  }
    53  
    54  func getMasterKey() []byte {
    55  	v, err := getMasterKeyFromSecretManager()
    56  	if err == nil {
    57  		return []byte(strings.TrimSpace(v))
    58  	}
    59  	key, err := os.ReadFile(filepath.Join(os.Getenv("HOME"), "keys/gobuilder-master.key"))
    60  	if err == nil {
    61  		return bytes.TrimSpace(key)
    62  	}
    63  	log.Fatalf("no builder master key found")
    64  	panic("not reachable")
    65  }
    66  
    67  // getMasterKeyFromSecretManager retrieves the master key
    68  // from the secret manager service.
    69  func getMasterKeyFromSecretManager() (string, error) {
    70  	sc, err := secret.NewClientInProject(buildenv.FromFlags().ProjectName)
    71  	if err != nil {
    72  		return "", err
    73  	}
    74  	defer sc.Close()
    75  	return sc.Retrieve(context.Background(), secret.NameBuilderMasterKey)
    76  }