package codesign import ( "context" "fmt" "github.com/leonmika/wails-release/internal/runner" ) // Keychain identifies a temporary keychain we created. type Keychain struct { Path string Password string } // CreateKeychain creates a new keychain at path with the given password // and unlocks it. The keychain's auto-lock timeout is set to 6 hours so // it does not relock during a long notarization. func CreateKeychain(ctx context.Context, r runner.Runner, path, password string) (*Keychain, error) { steps := [][]string{ {"create-keychain", "-p", password, path}, {"set-keychain-settings", "-lut", "21600", path}, {"unlock-keychain", "-p", password, path}, } for _, args := range steps { if _, err := r.Run(ctx, runner.Spec{Name: "security", Args: args}); err != nil { return nil, fmt.Errorf("security %s: %w", args[0], err) } } return &Keychain{Path: path, Password: password}, nil } // ImportP12 imports the .p12 at certPath into kc using certPassword and // authorises codesign to use the resulting key without prompting. func ImportP12(ctx context.Context, r runner.Runner, kc Keychain, certPath, certPassword string) error { if _, err := r.Run(ctx, runner.Spec{ Name: "security", Args: []string{"import", certPath, "-k", kc.Path, "-P", certPassword, "-T", "/usr/bin/codesign"}, }); err != nil { return fmt.Errorf("security import: %w", err) } if _, err := r.Run(ctx, runner.Spec{ Name: "security", Args: []string{"set-key-partition-list", "-S", "apple-tool:,apple:,codesign:", "-s", "-k", kc.Password, kc.Path}, }); err != nil { return fmt.Errorf("security set-key-partition-list: %w", err) } return nil } // DeleteKeychain removes the keychain. Safe to call from cleanup. func DeleteKeychain(ctx context.Context, r runner.Runner, kc Keychain) error { if _, err := r.Run(ctx, runner.Spec{ Name: "security", Args: []string{"delete-keychain", kc.Path}, }); err != nil { return fmt.Errorf("security delete-keychain: %w", err) } return nil }