package hsm import ( "context" "errors" "fmt" "log" "os" "strings" "syscall" "github.com/ThalesIgnite/crypto11" "golang.org/x/term" ) func prepareCrypto11Context(ctx context.Context, label string) (*crypto11.Context, error) { storage, ok := GetSignerConfig(ctx).KeyStorage[label] if !ok { return nil, fmt.Errorf("could not find storage definition with label %s", label) } var ( err error p11Context *crypto11.Context ) p11Config := &crypto11.Config{ Path: storage.Module, TokenLabel: storage.Label, } log.Printf("using PKCS#11 module %s", p11Config.Path) log.Printf("looking for token with label %s", p11Config.TokenLabel) p11Config.Pin, err = getPin(p11Config) if err != nil { return nil, err } p11Context, err = crypto11.Configure(p11Config) if err != nil { return nil, fmt.Errorf("could not configure PKCS#11 library: %v", err) } return p11Context, nil } func getPin(p11Config *crypto11.Config) (string, error) { tokenPinEnv := strings.ReplaceAll(p11Config.TokenLabel, "-", "_") tokenPinEnv = strings.ReplaceAll(tokenPinEnv, " ", "_") tokenPinEnv = strings.ToUpper(tokenPinEnv) tokenPinEnv = fmt.Sprintf("TOKEN_PIN_%s", tokenPinEnv) pin, found := os.LookupEnv(tokenPinEnv) if !found { log.Printf("environment variable %s has not been set", tokenPinEnv) if !term.IsTerminal(syscall.Stdin) { return "", errors.New("stdin is not a terminal") } fmt.Printf("Enter PIN for token %s: ", p11Config.TokenLabel) bytePin, err := term.ReadPassword(syscall.Stdin) if err != nil { return "", errors.New("could not read PIN") } fmt.Println() pin = string(bytePin) } return strings.TrimSpace(pin), nil }