diff --git a/.github/workflows/packagecloud.yml b/.github/workflows/packagecloud.yml new file mode 100644 index 0000000..baabce6 --- /dev/null +++ b/.github/workflows/packagecloud.yml @@ -0,0 +1,57 @@ +name: packagecloud + +on: + workflow_run: + workflows: ["goreleaser"] + types: + - completed + +jobs: + packagecloud: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - run: git fetch --force --tags + - run: cat VERSION + - run: echo "TAG=$(cat VERSION)" >> $GITHUB_ENV + - run: wget https://github.com/SaahilNotSahil/iitj-autoproxy/releases/download/${{ env.TAG }}/iitj-autoproxy_${{ env.TAG }}_linux_amd64.deb + - name: Upload package PackageCloud.io + uses: danielmundi/upload-packagecloud@v1 + with: + packagecloud-token: ${{ secrets.PACKAGECLOUD_TOKEN }} + packagecloud-username: "SaahilNotSahil" + packagecloud-repo: "iitj-autoproxy" + package-name: iitj-autoproxy_${{ env.TAG }}_linux_amd64.deb + packagecloud-distrib: any/any + + - run: wget https://github.com/SaahilNotSahil/iitj-autoproxy/releases/download/${{ env.TAG }}/iitj-autoproxy_${{ env.TAG }}_linux_arm64.deb + - name: Upload package PackageCloud.io + uses: danielmundi/upload-packagecloud@v1 + with: + packagecloud-token: ${{ secrets.PACKAGECLOUD_TOKEN }} + packagecloud-username: "SaahilNotSahil" + packagecloud-repo: "iitj-autoproxy" + package-name: iitj-autoproxy_${{ env.TAG }}_linux_arm64.deb + packagecloud-distrib: any/any + + - run: wget https://github.com/SaahilNotSahil/iitj-autoproxy/releases/download/${{ env.TAG }}/iitj-autoproxy_${{ env.TAG }}_linux_amd64.rpm + - name: Upload package PackageCloud.io + uses: danielmundi/upload-packagecloud@v1 + with: + packagecloud-token: ${{ secrets.PACKAGECLOUD_TOKEN }} + packagecloud-username: "SaahilNotSahil" + packagecloud-repo: "iitj-autoproxy" + package-name: iitj-autoproxy_${{ env.TAG }}_linux_amd64.rpm + packagecloud-distrib: rpm_any/rpm_any + + - run: wget https://github.com/SaahilNotSahil/iitj-autoproxy/releases/download/${{ env.TAG }}/iitj-autoproxy_${{ env.TAG }}_linux_arm64.rpm + - name: Upload package PackageCloud.io + uses: danielmundi/upload-packagecloud@v1 + with: + packagecloud-token: ${{ secrets.PACKAGECLOUD_TOKEN }} + packagecloud-username: "SaahilNotSahil" + packagecloud-repo: "iitj-autoproxy" + package-name: iitj-autoproxy_${{ env.TAG }}_linux_arm64.rpm + packagecloud-distrib: rpm_any/rpm_any diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e8d24e6..21da298 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: with: distribution: goreleaser version: ${{ env.GITHUB_REF_NAME }} - args: release --clean + args: release --clean --config=.goreleaser.yml env: GITHUB_TOKEN: ${{ secrets.PUBLISHER_TOKEN }} AUR_KEY: ${{ secrets.AUR_KEY }} diff --git a/.goreleaser.yml b/.goreleaser.yml index 4ebd148..8142261 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -21,6 +21,8 @@ builds: {{- end }} flags: - -mod=vendor + ldflags: + - -X github.com/SaahilNotSahil/iitj-autoproxy/pkg.Version={{ .Version }} ignore: - goos: windows goarch: arm64 @@ -47,6 +49,8 @@ builds: {{- end }} flags: - -mod=vendor + ldflags: + - -X github.com/SaahilNotSahil/iitj-autoproxy/pkg.Version={{ .Version }} ignore: - goos: windows goarch: arm64 @@ -56,13 +60,14 @@ checksum: nfpms: - package_name: iitj-autoproxy - vendor: XanderWatson - homepage: https://github.com/XanderWatson/iitj-autoproxy + vendor: SaahilNotSahil + homepage: https://github.com/SaahilNotSahil/iitj-autoproxy maintainer: Saahil Bhavsar license: MIT formats: - deb - archlinux + - rpm release: "1" bindir: /usr contents: @@ -78,28 +83,26 @@ nfpms: dst: /usr/bin/autoproxyd-start - src: ./scripts/linux/daemon-stop.sh dst: /usr/bin/autoproxyd-stop - scripts: - postinstall: ./scripts/linux/daemon-start.sh + - src: ./service_files/linux/autoproxyd@.service + dst: /etc/systemd/system/autoproxyd@.service release: prerelease: auto github: - owner: XanderWatson + owner: SaahilNotSahil name: iitj-autoproxy name_template: "{{.ProjectName}}-v{{.Version}}" - extra_files: - - glob: autoproxy.config aurs: - name: iitj-autoproxy-bin - homepage: https://github.com/XanderWatson/iitj-autoproxy + homepage: https://github.com/SaahilNotSahil/iitj-autoproxy license: MIT maintainers: - "Saahil Bhavsar " contributors: - "Saahil Bhavsar " commit_author: - name: XanderWatson + name: SaahilNotSahil email: saahil_bhavsar@outlook.com private_key: "{{ .Env.AUR_KEY }}" git_url: "ssh://aur@aur.archlinux.org/iitj-autoproxy-bin.git" @@ -109,32 +112,11 @@ aurs: install -Dm755 "./scripts/linux/login.sh" "${pkgdir}/usr/bin/autoproxylogin" install -Dm755 "./scripts/linux/daemon-start.sh" "${pkgdir}/usr/bin/autoproxyd-start" install -Dm755 "./scripts/linux/daemon-stop.sh" "${pkgdir}/usr/bin/autoproxyd-stop" + install -Dm644 "./service_files/linux/autoproxyd@.service" "${pkgdir}/etc/systemd/system/autoproxyd@.service" install -Dm644 "./LICENSE" "${pkgdir}/usr/share/licenses/iitj-autoproxy/LICENSE" install -Dm644 "./autoproxy.config" "${pkgdir}/etc/iitj-autoproxy/autoproxy.config" install -Dm644 "./README.md" "${pkgdir}/usr/share/doc/iitj-autoproxy/README.md" -# chocolateys: -# - name: iitj-autoproxy -# owners: Saahil Bhavsar -# title: IITJ Autoproxy -# authors: Saahil Bhavsar -# project_url: https://github.com/XanderWatson/iitj-autoproxy -# url_template: "https://github.com/XanderWatson/iitj-autoproxy/releases/download/{{ .Tag }}/{{ .ArtifactName }}" -# copyright: 2023 Saahil Bhavsar -# license_url: https://github.com/XanderWatson/iitj-autoproxy/blob/main/LICENSE -# require_license_acceptance: false -# project_source_url: https://github.com/XanderWatson/iitj-autoproxy -# docs_url: https://github.com/XanderWatson/iitj-autoproxy/blob/main/README.md -# bug_tracker_url: https://github.com/XanderWatson/iitj-autoproxy/issues -# summary: A CLI tool to automatically login to IIT Jodhpur's network firewall. -# description: | -# IITJ Autoproxy installer package. -# A CLI tool to automatically login to IIT Jodhpur's network firewall. -# release_notes: "https://github.com/XanderWatson/iitj-autoproxy/releases/tag/v{{ .Version }}" -# api_key: '{{ .Env.CHOCOLATEY_API_KEY }}' -# source_repo: "https://push.chocolatey.org/" -# skip_publish: false - archives: - wrap_in_directory: false format_overrides: @@ -145,5 +127,55 @@ archives: - README.md - autoproxy.config - scripts/* + - install.sh - install.ps1 - autoproxy-uninstall.ps1 + +brews: + - name: iitj-autoproxy + url_template: "https://github.com/SaahilNotSahil/iitj-autoproxy/releases/download/{{ .Tag }}/{{ .ArtifactName }}" + download_strategy: CurlDownloadStrategy + commit_author: + name: SaahilNotSahil + email: saahil_bhavsar@outlook.com + commit_msg_template: "Brew formula update for iitj-autoproxy version {{ .Tag }}" + homepage: "https://github.com/SaahilNotSahil/iitj-autoproxy" + description: "A CLI tool to automatically login to IIT Jodhpur's network firewall." + license: "MIT" + skip_upload: false + service: | + run [opt_bin/"autoproxyd"] + keep_alive true + install: | + bin.install "bin/autoproxyd" + bin.install "bin/autoproxy" + + (etc/"iitj-autoproxy").install "autoproxy.config" + + bin.install "scripts/darwin/daemon-start.sh" => "autoproxyd-start" + bin.install "scripts/darwin/daemon-stop.sh" => "autoproxyd-stop" + bin.install "scripts/darwin/login.sh" => "autoproxylogin" + repository: + owner: SaahilNotSahil + name: homebrew-iitj-autoproxy + branch: main + pull_request: + enabled: false + +scoops: + - name: iitj-autoproxy + url_template: "https://github.com/SaahilNotSahil/iitj-autoproxy/releases/download/{{ .Tag }}/{{ .ArtifactName }}" + commit_author: + name: SaahilNotSahil + email: saahil_bhavsar@outlook.com + commit_msg_template: "Scoop update for {{ .ProjectName }} version {{ .Tag }}" + homepage: "https://github.com/SaahilNotSahil/iitj-autoproxy" + description: "A CLI tool to automatically login to IIT Jodhpur's network firewall." + license: MIT + skip_upload: false + repository: + owner: SaahilNotSahil + name: scoop-iitj-autoproxy + branch: main + pull_request: + enabled: false diff --git a/README.md b/README.md index 486b361..05559a8 100644 --- a/README.md +++ b/README.md @@ -1,65 +1,93 @@ -# IITJ Autoproxy (v0.1.1) +# IITJ Autoproxy (v0.1.2) A CLI tool to automatically login to IIT Jodhpur's network firewall. -#### (Currently only supports Windows and Linux) +## Installation -### Installation +### Windows: -#### Windows: +#### Scoop: -- Download the latest release from [here](https://github.com/SaahilNotSahil/iitj-autoproxy/releases). -- Unzip the file and open a powershell instance with administrator privileges in the unzipped directory: -- Run the following script to install autoproxy: +- First, you need to install [Scoop](https://scoop.sh/). +- Next, run the following commands in PowerShell +```shell +scoop bucket add org https://github.com/SaahilNotSahil/scoop-iitj-autoproxy.git +scoop install iitj-autoproxy ``` + +#### From archive: + +- Download the latest release (`iitj-autoproxy__windows_amd64.zip`) from [here](https://github.com/SaahilNotSahil/iitj-autoproxy/releases). +- Extract the zip file. +- Open Powershell as administrator and run the following commands + +```shell +cd .\install.ps1 ``` -This will install the autoproxy CLI and daemon in "C:\Program Files\IITJ Autoproxy\" and also add it to the PATH environmment variable. +- IITJ Autoproxy is now installed on your system in the `C:\Program Files\IITJ Autoproxy` directory, and is added to the PATH. -#### Debian-based Linux Distributions: -- Run the following commands to install the package: +### Linux: -``` -$ curl -s https://packagecloud.io/install/repositories/SaahilNotSahil/iitj-autoproxy/script.deb.sh | sudo bash -$ sudo apt update -$ sudo apt install iitj-autoproxy -``` +#### Debian-based Distros (Debian, Ubuntu, Linux Mint, etc.): -- The daemon service will be started automatically. Incase it doesn't, run the following command: +- You can install by running the following commands -``` -$ sudo autoproxyd-start +```bash +curl -s https://packagecloud.io/install/repositories/SaahilNotSahil/iitj-autoproxy/script.deb.sh?any=true | sudo bash +sudo apt update +sudo apt install iitj-autoproxy ``` -- To stop the daemon service, run the following command: +#### Arch-based Distros (Arch Linux, EndeavourOS, Manjaro, etc.): -``` -$ sudo autoproxyd-stop +- Download the AUR package for IITJ Autoproxy: + (You can install it with your favourite AUR helper) + +```bash +yay -S iitj-autoproxy-bin ``` -#### Arch-based Linux Distributions: -- Install the [AUR package](https://aur.archlinux.org/packages/iitj-autoproxy-bin/) using your favourite AUR helper. +#### RHEL-based Distros (RHEL, Fedora, CentOS, etc.): -For example, using `yay`: -``` -$ yay -S iitj-autoproxy-bin +- You can install by running the following commands + +```shell +curl -s https://packagecloud.io/install/repositories/SaahilNotSahil/iitj-autoproxy/script.rpm.sh?any=true | sudo bash +sudo yum install iitj-autoproxy ``` -- Start the daemon service: +#### From archive: +- Download the latest release (`iitj-autoproxy__linux_.tar.gz`) from [here](https://github.com/SaahilNotSahil/iitj-autoproxy/releases). +- Extract the `tar.gz` file and run the installer script +```shell +tar zxvf iitj-autoproxy__linux_.tar.gz +chmod +x install.sh +./install.sh ``` -$ sudo autoproxyd-start -``` +- IITJ Autoproxy is now installed on your system in the `/usr/bin` directory, which is already in the PATH. + +### Mac: -- To stop the daemon service, run the following command: +#### Homebrew: +- You can install by running the following commands + +```shell +brew tap SaahilNotSahil/iitj-autoproxy +brew install iitj-autoproxy ``` -$ sudo autoproxyd-stop + +- To upgrade the package: + +```shell +brew upgrade iitj-autoproxy ``` -### Usage +## Usage - First, you need to set your username and password. To do so, run the following command: @@ -89,5 +117,3 @@ Note: You need to be logged out before running the above command. ``` $ autoproxy logout ``` - -#### Support for other operating systems coming soon :) diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..d917d3e --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.1.2 diff --git a/autoproxy.config b/autoproxy.config index 7199d33..36d32c7 100644 --- a/autoproxy.config +++ b/autoproxy.config @@ -1,4 +1,9 @@ { "base_url": "http://www.gstatic.com/generate_204", "login_base_url": "https://gateway.iitj.ac.in:1003/" + "username": "", + "password": "", + "token": "", + "scheduler_running_state": false, + "dummy_scheduler_running_state": false } diff --git a/cli/cmd/cleanup.go b/cli/cmd/cleanup.go index cfb7cd9..29f3e00 100644 --- a/cli/cmd/cleanup.go +++ b/cli/cmd/cleanup.go @@ -5,7 +5,7 @@ import ( "github.com/spf13/cobra" - "github.com/XanderWatson/iitj-autoproxy/pkg" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" ) func init() { diff --git a/cli/cmd/config.go b/cli/cmd/config.go index 90d04d5..56bf5c1 100644 --- a/cli/cmd/config.go +++ b/cli/cmd/config.go @@ -7,7 +7,7 @@ import ( "github.com/spf13/cobra" "golang.org/x/term" - "github.com/XanderWatson/iitj-autoproxy/pkg/keystore" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg/keystore" ) func init() { @@ -20,6 +20,7 @@ var configCmd = &cobra.Command{ Long: "Set the username and password for authentication", Run: func(cmd *cobra.Command, args []string) { fmt.Println("Username:") + var username string fmt.Scanln(&username) @@ -27,11 +28,9 @@ var configCmd = &cobra.Command{ bytePassword, err := term.ReadPassword(int(syscall.Stdin)) cobra.CheckErr(err) - password := string(bytePassword) - cobra.CheckErr(keystore.Set("username", username)) - cobra.CheckErr(keystore.Set("password", password)) - cobra.CheckErr(keystore.Set("token", "")) + keystore.Set("username", username) + keystore.Set("password", password) }, } diff --git a/cli/cmd/health_check.go b/cli/cmd/health_check.go index 67f2cbd..146e5d3 100644 --- a/cli/cmd/health_check.go +++ b/cli/cmd/health_check.go @@ -3,7 +3,7 @@ package cmd import ( "fmt" - "github.com/XanderWatson/iitj-autoproxy/pkg/cli" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg/cli" "github.com/spf13/cobra" ) diff --git a/cli/cmd/login.go b/cli/cmd/login.go index 23026d2..e54119b 100644 --- a/cli/cmd/login.go +++ b/cli/cmd/login.go @@ -3,12 +3,13 @@ package cmd import ( "fmt" - "github.com/XanderWatson/iitj-autoproxy/pkg/cli" - "github.com/spf13/cobra" + + "github.com/SaahilNotSahil/iitj-autoproxy/pkg/cli" ) func init() { + loginCmd.Flags().BoolVarP(&isDummy, "dummy", "d", false, "") rootCmd.AddCommand(loginCmd) } @@ -17,7 +18,14 @@ var loginCmd = &cobra.Command{ Short: "Login to your firewall authentication", Long: "Login to your firewall authentication", Run: func(cmd *cobra.Command, args []string) { - cobra.CheckErr(cli.SendCommandToDaemon("login")) - fmt.Println(cli.CreateNamedPipeAndReceiveMessage(false)) + if isDummy { + fmt.Println("Dummy login invoked") + + cobra.CheckErr(cli.SendCommandToDaemon("loginDummy")) + fmt.Println(cli.CreateNamedPipeAndReceiveMessage(false)) + } else { + cobra.CheckErr(cli.SendCommandToDaemon("login")) + fmt.Println(cli.CreateNamedPipeAndReceiveMessage(false)) + } }, } diff --git a/cli/cmd/logout.go b/cli/cmd/logout.go index 3dcb4b6..a66c1b4 100644 --- a/cli/cmd/logout.go +++ b/cli/cmd/logout.go @@ -3,12 +3,13 @@ package cmd import ( "fmt" - "github.com/XanderWatson/iitj-autoproxy/pkg/cli" - "github.com/spf13/cobra" + + "github.com/SaahilNotSahil/iitj-autoproxy/pkg/cli" ) func init() { + logoutCmd.Flags().BoolVarP(&isDummy, "dummy", "d", false, "") rootCmd.AddCommand(logoutCmd) } @@ -17,7 +18,14 @@ var logoutCmd = &cobra.Command{ Short: "Logout of your firewall authentication", Long: "Logout of your firewall authentication", Run: func(cmd *cobra.Command, args []string) { - cobra.CheckErr(cli.SendCommandToDaemon("logout")) - fmt.Println(cli.CreateNamedPipeAndReceiveMessage(false)) + if isDummy { + fmt.Println("Dummy logout invoked") + + cobra.CheckErr(cli.SendCommandToDaemon("logoutDummy")) + fmt.Println(cli.CreateNamedPipeAndReceiveMessage(false)) + } else { + cobra.CheckErr(cli.SendCommandToDaemon("logout")) + fmt.Println(cli.CreateNamedPipeAndReceiveMessage(false)) + } }, } diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 72765a7..445e3ce 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -4,12 +4,14 @@ import ( "github.com/spf13/cobra" ) +var isDummy bool + var rootCmd = &cobra.Command{ Use: "autoproxy", Short: "Use IITJ internet hassle-free", Long: `A Fast CLI Autoproxy Tool built for IITJ fraternity. - With love, by XanderWatson.`, + With love, by SaahilNotSahil.`, Run: func(cmd *cobra.Command, args []string) { cobra.CheckErr(cmd.Help()) }, diff --git a/cli/cmd/schedule.go b/cli/cmd/schedule.go index d4cf433..eb2bfa9 100644 --- a/cli/cmd/schedule.go +++ b/cli/cmd/schedule.go @@ -3,12 +3,13 @@ package cmd import ( "fmt" - "github.com/XanderWatson/iitj-autoproxy/pkg/cli" - "github.com/spf13/cobra" + + "github.com/SaahilNotSahil/iitj-autoproxy/pkg/cli" ) func init() { + scheduleCmd.Flags().BoolVarP(&isDummy, "dummy", "d", false, "") rootCmd.AddCommand(scheduleCmd) } @@ -17,7 +18,14 @@ var scheduleCmd = &cobra.Command{ Short: "Schedule your firewall authentication", Long: "Schedule your firewall authentication", Run: func(cmd *cobra.Command, args []string) { - cobra.CheckErr(cli.SendCommandToDaemon("schedule")) - fmt.Println(cli.CreateNamedPipeAndReceiveMessage(false)) + if isDummy { + fmt.Println("Dummy schedule invoked") + + cobra.CheckErr(cli.SendCommandToDaemon("scheduleDummy")) + fmt.Println(cli.CreateNamedPipeAndReceiveMessage(false)) + } else { + cobra.CheckErr(cli.SendCommandToDaemon("schedule")) + fmt.Println(cli.CreateNamedPipeAndReceiveMessage(false)) + } }, } diff --git a/cli/cmd/version.go b/cli/cmd/version.go new file mode 100644 index 0000000..23d07ec --- /dev/null +++ b/cli/cmd/version.go @@ -0,0 +1,22 @@ +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" +) + +var versionCmd = &cobra.Command{ + Use: "version", + Short: "IITJ Autoproxy version", + Long: `IITJ Autoproxy version`, + Run: func(cmd *cobra.Command, args []string) { + fmt.Printf("IITJ Autoproxy Version - v%s\n", pkg.Version) + }, +} + +func init() { + rootCmd.AddCommand(versionCmd) +} diff --git a/cli/main.go b/cli/main.go index bce40a7..4d56254 100644 --- a/cli/main.go +++ b/cli/main.go @@ -1,7 +1,7 @@ package main import ( - "github.com/XanderWatson/iitj-autoproxy/cli/cmd" + "github.com/SaahilNotSahil/iitj-autoproxy/cli/cmd" ) func main() { diff --git a/daemon/commands/health_check.go b/daemon/commands/health_check.go index 4d2cd37..cd74448 100644 --- a/daemon/commands/health_check.go +++ b/daemon/commands/health_check.go @@ -3,8 +3,8 @@ package commands import ( "log" - "github.com/XanderWatson/iitj-autoproxy/pkg" - "github.com/XanderWatson/iitj-autoproxy/pkg/daemon" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg/daemon" ) func HealthCheckCmd() { diff --git a/daemon/commands/login.go b/daemon/commands/login.go index ee9ba7d..010ed8c 100644 --- a/daemon/commands/login.go +++ b/daemon/commands/login.go @@ -3,11 +3,11 @@ package commands import ( "log" - "github.com/XanderWatson/iitj-autoproxy/pkg" - "github.com/XanderWatson/iitj-autoproxy/pkg/daemon" - "github.com/XanderWatson/iitj-autoproxy/pkg/keystore" - "github.com/spf13/viper" + + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg/daemon" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg/keystore" ) func LoginCmd() { @@ -29,13 +29,16 @@ func LoginCmd() { return } - username, err := keystore.Get("username") + var username string + var password string + + username, err = keystore.Get("username") if err != nil { pkg.Logger.Println(err) log.Println(err) err = daemon.SendMessageToCLI( - "Error fetching the username from the OS keyring", + err.Error(), ) if err != nil { pkg.Logger.Println(err) @@ -47,13 +50,13 @@ func LoginCmd() { return } - password, err := keystore.Get("password") + password, err = keystore.Get("password") if err != nil { pkg.Logger.Println(err) log.Println(err) err = daemon.SendMessageToCLI( - "Error fetching the password from the OS keyring", + err.Error(), ) if err != nil { pkg.Logger.Println(err) @@ -65,16 +68,36 @@ func LoginCmd() { return } - if username == "" || password == "" { - pkg.Logger.Println( - "Please configure the application using the config command", - ) - log.Println( - "Please configure the application using the config command", - ) + err = pkg.Login(viper.GetString("base_url"), username, password) + if err != nil { + pkg.Logger.Println(err) + log.Println(err) + + err = daemon.SendMessageToCLI("Login failed") + if err != nil { + pkg.Logger.Println(err) + log.Println(err) + } + } else { + pkg.Logger.Println("Login successful") + log.Println("Login successful") + + err = daemon.SendMessageToCLI("Login successful") + if err != nil { + pkg.Logger.Println(err) + log.Println(err) + } + } +} + +func LoginDummyCmd() { + err := viper.ReadInConfig() + if err != nil { + pkg.Logger.Println(err) + log.Println(err) err = daemon.SendMessageToCLI( - "Please configure the application using the config command", + "Error reading config file. Please make sure the file exists and is valid", ) if err != nil { pkg.Logger.Println(err) @@ -86,24 +109,47 @@ func LoginCmd() { return } - err = daemon.Login(viper.GetString("base_url"), username, password) + _, err = keystore.Get("username") if err != nil { pkg.Logger.Println(err) log.Println(err) - err = daemon.SendMessageToCLI("Login failed") + err = daemon.SendMessageToCLI( + err.Error(), + ) if err != nil { pkg.Logger.Println(err) log.Println(err) + + return } - } else { - pkg.Logger.Println("Login successful") - log.Println("Login successful") - err = daemon.SendMessageToCLI("Login successful") + return + } + + _, err = keystore.Get("password") + if err != nil { + pkg.Logger.Println(err) + log.Println(err) + + err = daemon.SendMessageToCLI( + err.Error(), + ) if err != nil { pkg.Logger.Println(err) log.Println(err) + + return } + + return + } + + err = daemon.SendMessageToCLI("Dummy login successful") + if err != nil { + pkg.Logger.Println(err) + log.Println(err) + + return } } diff --git a/daemon/commands/logout.go b/daemon/commands/logout.go index 9780f01..9e1b609 100644 --- a/daemon/commands/logout.go +++ b/daemon/commands/logout.go @@ -3,12 +3,12 @@ package commands import ( "log" - "github.com/XanderWatson/iitj-autoproxy/pkg" - "github.com/XanderWatson/iitj-autoproxy/pkg/daemon" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg/daemon" ) func LogoutCmd() { - token, err := daemon.GetCurrentKeepaliveToken() + token, err := pkg.GetCurrentKeepaliveToken() if err != nil { pkg.Logger.Println(err) log.Println(err) @@ -37,7 +37,7 @@ func LogoutCmd() { return } - err = daemon.Logout(token) + err = pkg.Logout(token) if err != nil { pkg.Logger.Println(err) log.Println(err) @@ -60,3 +60,15 @@ func LogoutCmd() { KillScheduler() } } + +func LogoutDummyCmd() { + err := daemon.SendMessageToCLI("Dummy logout successful") + if err != nil { + pkg.Logger.Println(err) + log.Println(err) + + return + } + + KillDummyScheduler() +} diff --git a/daemon/commands/schedule.go b/daemon/commands/schedule.go index 8755e71..13777ae 100644 --- a/daemon/commands/schedule.go +++ b/daemon/commands/schedule.go @@ -3,15 +3,19 @@ package commands import ( "log" - "github.com/XanderWatson/iitj-autoproxy/pkg" - "github.com/XanderWatson/iitj-autoproxy/pkg/daemon" - "github.com/XanderWatson/iitj-autoproxy/pkg/daemon/scheduler" - "github.com/XanderWatson/iitj-autoproxy/pkg/keystore" - "github.com/spf13/viper" + + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg/daemon" + ds "github.com/SaahilNotSahil/iitj-autoproxy/pkg/dummy/scheduler" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg/keystore" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg/scheduler" ) -var kill = make(chan bool) +var ( + kill = make(chan bool) + killDummy = make(chan bool) +) func ScheduleCmd() { err := viper.ReadInConfig() @@ -25,38 +29,82 @@ func ScheduleCmd() { if err != nil { pkg.Logger.Println(err) log.Println(err) - - return } return } - username, err := keystore.Get("username") + var username string + var password string + + username, err = keystore.Get("username") if err != nil { pkg.Logger.Println(err) log.Println(err) err = daemon.SendMessageToCLI( - "Error fetching the username from the OS keyring", + err.Error(), ) if err != nil { pkg.Logger.Println(err) log.Println(err) + } - return + return + } + + password, err = keystore.Get("password") + if err != nil { + pkg.Logger.Println(err) + log.Println(err) + + err = daemon.SendMessageToCLI( + err.Error(), + ) + if err != nil { + pkg.Logger.Println(err) + log.Println(err) } return } - password, err := keystore.Get("password") + base_url := viper.GetString("base_url") + + scheduler_running_state := scheduler.RunLoginScheduler( + base_url, username, password, kill, + ) + if !scheduler_running_state { + pkg.Logger.Println("Scheduler already running") + log.Println("Scheduler already running") + + err = daemon.SendMessageToCLI("Scheduler already running") + if err != nil { + pkg.Logger.Println(err) + log.Println(err) + } + } else { + pkg.Logger.Println("Scheduler started") + log.Println("Scheduler started") + + viper.Set("scheduler_running_state", scheduler_running_state) + + err = daemon.SendMessageToCLI("Scheduler started") + if err != nil { + pkg.Logger.Println(err) + log.Println(err) + } + } +} + +func ScheduleDummyCmd() { + err := viper.ReadInConfig() if err != nil { pkg.Logger.Println(err) log.Println(err) err = daemon.SendMessageToCLI( - "Error fetching the password from the OS keyring", + "Error reading config file. Please make sure the file exists and is valid", ) if err != nil { pkg.Logger.Println(err) @@ -68,18 +116,31 @@ func ScheduleCmd() { return } - base_url := viper.GetString("base_url") + _, err = keystore.Get("username") + if err != nil { + pkg.Logger.Println(err) + log.Println(err) - if username == "" || password == "" { - pkg.Logger.Println( - "Please configure the application using the config command", - ) - log.Println( - "Please configure the application using the config command", + err = daemon.SendMessageToCLI( + err.Error(), ) + if err != nil { + pkg.Logger.Println(err) + log.Println(err) + + return + } + + return + } + + _, err = keystore.Get("password") + if err != nil { + pkg.Logger.Println(err) + log.Println(err) err = daemon.SendMessageToCLI( - "Please configure the application using the config command", + err.Error(), ) if err != nil { pkg.Logger.Println(err) @@ -91,11 +152,14 @@ func ScheduleCmd() { return } - if !scheduler.RunLoginScheduler(base_url, username, password, kill) { - pkg.Logger.Println("Scheduler already running") - log.Println("Scheduler already running") + _ = viper.GetString("base_url") - err = daemon.SendMessageToCLI("Scheduler already running") + scheduler_running_state := ds.RunLoginScheduler(killDummy) + if !scheduler_running_state { + pkg.Logger.Println("Dummy scheduler already running") + log.Println("Dummy scheduler already running") + + err = daemon.SendMessageToCLI("Dummy scheduler already running") if err != nil { pkg.Logger.Println(err) log.Println(err) @@ -104,7 +168,9 @@ func ScheduleCmd() { pkg.Logger.Println("Scheduler started") log.Println("Scheduler started") - err = daemon.SendMessageToCLI("Scheduler started") + viper.Set("dummy_scheduler_running_state", scheduler_running_state) + + err = daemon.SendMessageToCLI("Dummy scheduler started") if err != nil { pkg.Logger.Println(err) log.Println(err) @@ -125,6 +191,27 @@ func KillScheduler() { scheduler.SchedulerRunning = false + viper.Set("scheduler_running_state", false) + kill <- true } } + +func KillDummyScheduler() { + if ds.SchedulerRunning { + pkg.Logger.Println("Stopping the dummy scheduler...") + log.Println("Stopping the dummy scheduler...") + + err := daemon.SendMessageToCLI("Stopping the dummy scheduler...") + if err != nil { + pkg.Logger.Println(err) + log.Println(err) + } + + ds.SchedulerRunning = false + + viper.Set("dummy_scheduler_running_state", false) + + killDummy <- true + } +} diff --git a/daemon/main_unix.go b/daemon/main_unix.go index 44dfbb7..c6f02c2 100644 --- a/daemon/main_unix.go +++ b/daemon/main_unix.go @@ -9,12 +9,13 @@ import ( "log" "os" "os/signal" + "runtime" "syscall" "github.com/spf13/viper" - "github.com/XanderWatson/iitj-autoproxy/daemon/commands" - "github.com/XanderWatson/iitj-autoproxy/pkg" + "github.com/SaahilNotSahil/iitj-autoproxy/daemon/commands" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" ) func main() { @@ -38,6 +39,13 @@ func main() { defer pipe.Close() buf := make([]byte, 1024) + + scheduler_running_state := viper.GetBool("scheduler_running_state") + + if scheduler_running_state { + commands.ScheduleCmd() + } + for { num_bytes, _ := pipe.Read(buf) command := string(buf[:num_bytes]) @@ -54,10 +62,16 @@ func execute(command string) { switch command { case "login": commands.LoginCmd() + case "loginDummy": + commands.LoginDummyCmd() case "logout": commands.LogoutCmd() + case "logoutDummy": + commands.LogoutDummyCmd() case "schedule": commands.ScheduleCmd() + case "scheduleDummy": + commands.ScheduleDummyCmd() case "hc": commands.HealthCheckCmd() } @@ -72,7 +86,11 @@ func initConfig() { var baseConfigPath string - baseConfigPath = "/etc/iitj-autoproxy/autoproxy.config" + if runtime.GOOS == "darwin" { + baseConfigPath = "/opt/homebrew/etc/iitj-autoproxy/autoproxy.config" + } else { + baseConfigPath = "/etc/iitj-autoproxy/autoproxy.config" + } configName := ".autoproxy.config" diff --git a/daemon/main_windows.go b/daemon/main_windows.go index 31be084..df83753 100644 --- a/daemon/main_windows.go +++ b/daemon/main_windows.go @@ -14,8 +14,8 @@ import ( "github.com/spf13/viper" "gopkg.in/natefinch/npipe.v2" - "github.com/XanderWatson/iitj-autoproxy/daemon/commands" - "github.com/XanderWatson/iitj-autoproxy/pkg" + "github.com/SaahilNotSahil/iitj-autoproxy/daemon/commands" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" ) func main() { @@ -30,6 +30,12 @@ func main() { log.Fatal(err) } + scheduler_running_state := viper.GetBool("scheduler_running_state") + + if scheduler_running_state { + commands.ScheduleCmd() + } + buf := make([]byte, 1024) for { conn, err := ln.Accept() @@ -57,10 +63,16 @@ func execute(command string) { switch command { case "login": commands.LoginCmd() + case "loginDummy": + commands.LoginDummyCmd() case "logout": commands.LogoutCmd() + case "logoutDummy": + commands.LogoutDummyCmd() case "schedule": commands.ScheduleCmd() + case "scheduleDummy": + commands.ScheduleDummyCmd() case "hc": commands.HealthCheckCmd() } diff --git a/go.mod b/go.mod index 555c1af..a8551f7 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/XanderWatson/iitj-autoproxy +module github.com/SaahilNotSahil/iitj-autoproxy go 1.18 @@ -10,16 +10,11 @@ require ( require golang.org/x/term v0.6.0 require ( - github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect - github.com/danieljoos/wincred v1.1.2 // indirect - github.com/dvsekhvalnov/jose2go v1.5.0 // indirect - github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect - github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect - github.com/mtibben/percent v0.2.1 // indirect + github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect + gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect ) require ( - github.com/99designs/keyring v1.2.2 github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect @@ -32,7 +27,7 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.8.2 // indirect github.com/subosito/gotenv v1.4.2 // indirect - golang.org/x/sys v0.6.0 // indirect + golang.org/x/sys v0.17.0 // indirect golang.org/x/text v0.8.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce diff --git a/go.sum b/go.sum index 51db657..7bdd65f 100644 --- a/go.sum +++ b/go.sum @@ -36,10 +36,6 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= -github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= -github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= -github.com/99designs/keyring v1.2.2/go.mod h1:wes/FrByc8j7lFOAGLGSNEg8f/PaI3cgTBqhFkHUrPk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -51,13 +47,9 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/danieljoos/wincred v1.1.2 h1:QLdCxFs1/Yl4zduvBdcHB8goaYk9RARS2SgLLRuAyr0= -github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= -github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -70,8 +62,6 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= -github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -127,8 +117,6 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= -github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -151,8 +139,6 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= -github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= @@ -179,7 +165,6 @@ github.com/spf13/viper v1.15.0 h1:js3yy885G8xwJa6iOISGFwd+qlUo5AvyXb7CiihdtiU= github.com/spf13/viper v1.15.0/go.mod h1:fFcTBJxvhhzSJiZy8n+PeW6t8l+KeT/uTARa0jHOQLA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -326,10 +311,9 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= diff --git a/install.ps1 b/install.ps1 index ddfc440..183eb23 100644 --- a/install.ps1 +++ b/install.ps1 @@ -11,6 +11,11 @@ $configDir = "." $installDir = "C:\Program Files\IITJ Autoproxy" $configInstallDir = "C:\ProgramData\IITJ Autoproxy" +# Define service parameters +$serviceName = "IITJAutoproxy" +$displayName = "IITJ Autoproxy Daemon" +$exePath = "$installDir\autoproxyd.exe" # Update this if the executable has a different name + # Create installation directories if they don't exist if (-Not (Test-Path $installDir)) { New-Item -Path $installDir -ItemType Directory @@ -35,4 +40,12 @@ if (-Not ($envPath -like "*$installDir*")) { [Environment]::SetEnvironmentVariable("Path", $envPath + ";$installDir", [EnvironmentVariableTarget]::Machine) } -Write-Host "Installation of IITJ Autoproxy completed successfully!" +# Create the service +Write-Host "Creating background service..." +sc.exe create $serviceName binPath= "$exePath" DisplayName= "$displayName" start= auto type= own + +# Start the service +Write-Host "Starting the service..." +sc.exe start $serviceName + +Write-Host "Installation of IITJ Autoproxy and service setup completed successfully!" diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..d616f24 --- /dev/null +++ b/install.sh @@ -0,0 +1,44 @@ + +# Check if script is run as root +if [ "$(id -u)" -ne 0 ]; then + echo "This script must be run as root. Restarting as root..." + sudo "$0" "$@" + exit $? +fi + +# Define directories +binDir="bin" +scriptsDir="scripts" +serviceFilesDir="service_files" +installDir="/usr/bin" +serviceDir="/etc/systemd/system" +configInstallDir="/etc/iitj-autoproxy" +readmeDir="/usr/share/doc/iitj-autoproxy" +licenseDir="/usr/share/licenses/iitj-autoproxy" + +# Create installation directories if they don't exist +mkdir -p "$configInstallDir" +mkdir -p "$readmeDir" +mkdir -p "$licenseDir" + +# Copy binaries +cp "$binDir/autoproxy" "$installDir" +cp "$binDir/autoproxyd" "$installDir" +cp "$scriptsDir/linux/daemon-start.sh" "$installDir/autoproxyd-start" +cp "$scriptsDir/linux/daemon-stop.sh" "$installDir/autoproxyd-stop" +cp "$scriptsDir/linux/login.sh" "$installDir/autoproxylogin" +cp "$serviceFilesDir/linux/autoproxyd@.service" "$serviceDir/autoproxyd@.service" +cp "autoproxy.config" "$configInstallDir" +cp "README.md" "$readmeDir" +cp "LICENSE" "$licenseDir" + +# Manage permissions +chmod +x "$installDir/autoproxyd-start" +chmod +x "$installDir/autoproxyd-stop" +chmod +x "$installDir/autoproxylogin" + +# Starting service +systemctl daemon-reload +systemctl enable --now autoproxyd@$(whoami).service + +echo "Installation of IITJ Autoproxy completed successfully!" diff --git a/pkg/cli/daemon.go b/pkg/cli/daemon.go index c2da408..ed3b89a 100644 --- a/pkg/cli/daemon.go +++ b/pkg/cli/daemon.go @@ -4,7 +4,7 @@ import ( "log" "os" - "github.com/XanderWatson/iitj-autoproxy/pkg" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" ) func SendCommandToDaemon(command string) error { diff --git a/pkg/cli/daemon_unix.go b/pkg/cli/daemon_unix.go index 3e76e2f..22c04aa 100644 --- a/pkg/cli/daemon_unix.go +++ b/pkg/cli/daemon_unix.go @@ -8,7 +8,7 @@ import ( "os" "syscall" - "github.com/XanderWatson/iitj-autoproxy/pkg" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" ) func CreateNamedPipeAndReceiveMessage(isHealthCheck bool) string { @@ -19,7 +19,7 @@ func CreateNamedPipeAndReceiveMessage(isHealthCheck bool) string { if isHealthCheck { return "Unhealthy" } - + pkg.Logger.Println(err) log.Fatal(err) } diff --git a/pkg/cli/daemon_windows.go b/pkg/cli/daemon_windows.go index 03d8a58..66cd03e 100644 --- a/pkg/cli/daemon_windows.go +++ b/pkg/cli/daemon_windows.go @@ -8,7 +8,7 @@ import ( "gopkg.in/natefinch/npipe.v2" - "github.com/XanderWatson/iitj-autoproxy/pkg" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" ) func CreateNamedPipeAndReceiveMessage(isHealthCheck bool) string { diff --git a/pkg/daemon/cli.go b/pkg/daemon/cli.go index 39c7891..5c15198 100644 --- a/pkg/daemon/cli.go +++ b/pkg/daemon/cli.go @@ -4,7 +4,7 @@ import ( "log" "os" - "github.com/XanderWatson/iitj-autoproxy/pkg" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" ) func SendMessageToCLI(message string) error { diff --git a/pkg/dummy/scheduler/scheduler.go b/pkg/dummy/scheduler/scheduler.go new file mode 100644 index 0000000..4e7b1e0 --- /dev/null +++ b/pkg/dummy/scheduler/scheduler.go @@ -0,0 +1,69 @@ +package scheduler + +import ( + "time" + + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" +) + +var SchedulerRunning = false + +func ping(pingChannel chan bool, kill chan bool) { + for { + select { + case <-kill: + return + default: + internet := pkg.InternetAvailable() + + if !internet { + pingChannel <- internet + } + + time.Sleep(5 * time.Second) + } + } +} + +func login( + pingChannel chan bool, + logChannel chan string, + kill chan bool, +) { + for { + select { + case <-kill: + return + case <-pingChannel: + logChannel <- "Logged in successfully" + } + } +} + +func logToFile(logChannel chan string, kill chan bool) { + for { + select { + case <-kill: + return + case <-logChannel: + pkg.Logger.Printf("No internet; %s", <-logChannel) + } + } +} + +func RunLoginScheduler(kill chan bool) bool { + if SchedulerRunning { + return false + } + + SchedulerRunning = true + + pingChannel := make(chan bool) + logChannel := make(chan string) + + go ping(pingChannel, kill) + go login(pingChannel, logChannel, kill) + go logToFile(logChannel, kill) + + return true +} diff --git a/pkg/keystore/keystore.go b/pkg/keystore/keystore.go index 76f9997..82df589 100644 --- a/pkg/keystore/keystore.go +++ b/pkg/keystore/keystore.go @@ -1,53 +1,53 @@ package keystore import ( - "github.com/99designs/keyring" -) + "errors" + "log" + "os" -var kr keyring.Keyring + "github.com/spf13/viper" -func init() { - kr, _ = keyring.Open(keyring.Config{ - ServiceName: "iitj-autoproxy", - }) -} + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" +) -func Get(key string) (string, error) { - item, err := kr.Get(key) +func init() { + home, err := os.UserHomeDir() if err != nil { - return "", err + pkg.Logger.Println(err) + log.Fatal(err) } - return string(item.Data), nil -} + configName := ".autoproxy.config" -func Set(key string, value string) error { - return kr.Set(keyring.Item{ - Key: key, - Data: []byte(value), - }) -} + viper.AddConfigPath(home) -func Remove(key string) error { - return kr.Remove(key) -} + viper.SetConfigType("json") + viper.SetConfigName(configName) -func Keys() ([]string, error) { - return kr.Keys() -} - -func Reset() error { - keys, err := kr.Keys() + err = viper.ReadInConfig() if err != nil { - return err + pkg.Logger.Println(err) + log.Fatal(err) } +} - for _, key := range keys { - err := kr.Remove(key) - if err != nil { - return err - } +func Get(key string) (string, error) { + item := viper.GetString(key) + if item != "" { + return "", errors.New("Please set the value for " + key) } - return nil + return item, nil +} + +func Set(key string, value string) { + viper.Set(key, value) +} + +func Remove(key string) { + viper.Set(key, "") +} + +func Keys() []string { + return viper.AllKeys() } diff --git a/pkg/named_pipe.go b/pkg/named_pipe.go index 97c069a..e09d021 100644 --- a/pkg/named_pipe.go +++ b/pkg/named_pipe.go @@ -9,15 +9,15 @@ import ( func GetCTDNamedPipe() string { var pipeName string - homeDir, err := os.UserHomeDir() - if err != nil { - Logger.Println(err) - log.Fatal(err) - } - if runtime.GOOS == "windows" { pipeName = `\\.\pipe\autoproxy-ctd` } else { + homeDir, err := os.UserHomeDir() + if err != nil { + Logger.Println(err) + log.Fatal(err) + } + pipeName = homeDir + "/autoproxy-ctd" } @@ -27,15 +27,15 @@ func GetCTDNamedPipe() string { func GetDTCNamedPipe() string { var pipeName string - homeDir, err := os.UserHomeDir() - if err != nil { - Logger.Println(err) - log.Fatal(err) - } - if runtime.GOOS == "windows" { pipeName = `\\.\pipe\autoproxy-dtc` } else { + homeDir, err := os.UserHomeDir() + if err != nil { + Logger.Println(err) + log.Fatal(err) + } + pipeName = homeDir + "/autoproxy-dtc" } diff --git a/pkg/daemon/scheduler/scheduler.go b/pkg/scheduler/scheduler.go similarity index 85% rename from pkg/daemon/scheduler/scheduler.go rename to pkg/scheduler/scheduler.go index d929329..5f8a16c 100644 --- a/pkg/daemon/scheduler/scheduler.go +++ b/pkg/scheduler/scheduler.go @@ -3,8 +3,7 @@ package scheduler import ( "time" - "github.com/XanderWatson/iitj-autoproxy/pkg" - "github.com/XanderWatson/iitj-autoproxy/pkg/daemon" + "github.com/SaahilNotSahil/iitj-autoproxy/pkg" ) var SchedulerRunning = false @@ -15,7 +14,7 @@ func ping(pingChannel chan bool, kill chan bool) { case <-kill: return default: - internet := daemon.InternetAvailable() + internet := pkg.InternetAvailable() if !internet { pingChannel <- internet @@ -39,7 +38,7 @@ func login( case <-kill: return case <-pingChannel: - err := daemon.Login(url, username, password) + err := pkg.Login(url, username, password) if err == nil { logChannel <- "Logged in successfully" } else { diff --git a/pkg/daemon/utils.go b/pkg/utils.go similarity index 90% rename from pkg/daemon/utils.go rename to pkg/utils.go index 4987f6e..d02f3cd 100644 --- a/pkg/daemon/utils.go +++ b/pkg/utils.go @@ -1,14 +1,13 @@ -package daemon +package pkg import ( - "io/ioutil" + "io" "log" "net/http" u "net/url" "strings" "time" - "github.com/XanderWatson/iitj-autoproxy/pkg/keystore" "github.com/spf13/viper" ) @@ -27,7 +26,7 @@ func Login(url string, username string, password string) error { return err } - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { return err } @@ -72,7 +71,7 @@ func Login(url string, username string, password string) error { return err } - body, err = ioutil.ReadAll(res.Body) + body, err = io.ReadAll(res.Body) res.Body.Close() if err != nil { return err @@ -93,18 +92,17 @@ func Login(url string, username string, password string) error { } } - return keystore.Set("token", token) + viper.Set("token", token) + + return nil } func Logout(token string) error { url := viper.GetString("login_base_url") + "logout?" + token _, err := http.Get(url) - if err != nil { - return err - } - - return nil + + return err } func GetToken(url string) (string, error) { @@ -115,7 +113,7 @@ func GetToken(url string) (string, error) { return "", err } - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) res.Body.Close() if err != nil { return "", err @@ -149,7 +147,7 @@ func GetCurrentKeepaliveToken() (string, error) { return "", err } - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { return "", err } diff --git a/pkg/version.go b/pkg/version.go new file mode 100644 index 0000000..16a7add --- /dev/null +++ b/pkg/version.go @@ -0,0 +1,3 @@ +package pkg + +var Version string diff --git a/scripts/darwin/daemon-start.sh b/scripts/darwin/daemon-start.sh index 26a036a..e213a91 100644 --- a/scripts/darwin/daemon-start.sh +++ b/scripts/darwin/daemon-start.sh @@ -12,7 +12,7 @@ fi TARGET_USER=$(who | awk '{if ($1 != "root") print $1; exit;}') # Run the daemon as the target user -su - $TARGET_USER -c /usr/bin/autoproxyd > /dev/null 2>&1 & +su - $TARGET_USER -c /opt/homebrew/bin/autoproxyd > /dev/null 2>&1 & # Get the PID of the last background command APP_PID=$! diff --git a/scripts/darwin/login.sh b/scripts/darwin/login.sh index 7e289fc..472456d 100644 --- a/scripts/darwin/login.sh +++ b/scripts/darwin/login.sh @@ -1,6 +1,6 @@ #!/bin/bash -AUTOPROXY_DIR=/usr/bin +AUTOPROXY_DIR=/opt/homebrew/bin # Start the daemon and redirect output to a log file nohup $AUTOPROXY_DIR/autoproxyd > $HOME/autoproxyd.log & diff --git a/service_files/linux/autoproxyd@.service b/service_files/linux/autoproxyd@.service new file mode 100644 index 0000000..aa0e79c --- /dev/null +++ b/service_files/linux/autoproxyd@.service @@ -0,0 +1,12 @@ +[Unit] +Description=IITJ Autoproxy Daemon for user %i +After=network.target + +[Service] +Type=simple +ExecStart=/usr/bin/autoproxyd +User=%i +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/vendor/github.com/99designs/go-keychain/.gitignore b/vendor/github.com/99designs/go-keychain/.gitignore deleted file mode 100644 index daf913b..0000000 --- a/vendor/github.com/99designs/go-keychain/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof diff --git a/vendor/github.com/99designs/go-keychain/.golangci.yml b/vendor/github.com/99designs/go-keychain/.golangci.yml deleted file mode 100644 index 23aaf43..0000000 --- a/vendor/github.com/99designs/go-keychain/.golangci.yml +++ /dev/null @@ -1,11 +0,0 @@ -linters-settings: - gocritic: - disabled-checks: - - ifElseChain - - elseif - -linters: - enable: - - gofmt - - gocritic - - unconvert diff --git a/vendor/github.com/99designs/go-keychain/.travis.yml b/vendor/github.com/99designs/go-keychain/.travis.yml deleted file mode 100644 index 2fba239..0000000 --- a/vendor/github.com/99designs/go-keychain/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: go - -os: - - osx - - linux - -before_install: - - go get golang.org/x/lint/golint - -script: - - go vet ./... - - golint ./... - - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.16.0 - - golangci-lint run - - go test -tags skipsecretserviceintegrationtests ./... - -go: - - 1.10.x - - 1.11.x - - 1.12.x diff --git a/vendor/github.com/99designs/go-keychain/LICENSE b/vendor/github.com/99designs/go-keychain/LICENSE deleted file mode 100644 index 2d54c65..0000000 --- a/vendor/github.com/99designs/go-keychain/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Keybase - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/vendor/github.com/99designs/go-keychain/README.md b/vendor/github.com/99designs/go-keychain/README.md deleted file mode 100644 index 4a9eeb2..0000000 --- a/vendor/github.com/99designs/go-keychain/README.md +++ /dev/null @@ -1,159 +0,0 @@ -# Go Keychain - -[![Travis CI](https://travis-ci.org/keybase/go-keychain.svg?branch=master)](https://travis-ci.org/keybase/go-keychain) - -A library for accessing the Keychain for macOS, iOS, and Linux in Go (golang). - -Requires macOS 10.9 or greater and iOS 8 or greater. On Linux, communicates to -a provider of the DBUS SecretService spec like gnome-keyring or ksecretservice. - -```go -import "github.com/keybase/go-keychain" -``` - - -## Mac/iOS Usage - -The API is meant to mirror the macOS/iOS Keychain API and is not necessarily idiomatic go. - -#### Add Item - -```go -item := keychain.NewItem() -item.SetSecClass(keychain.SecClassGenericPassword) -item.SetService("MyService") -item.SetAccount("gabriel") -item.SetLabel("A label") -item.SetAccessGroup("A123456789.group.com.mycorp") -item.SetData([]byte("toomanysecrets")) -item.SetSynchronizable(keychain.SynchronizableNo) -item.SetAccessible(keychain.AccessibleWhenUnlocked) -err := keychain.AddItem(item) - -if err == keychain.ErrorDuplicateItem { - // Duplicate -} -``` - -#### Query Item - -Query for multiple results, returning attributes: - -```go -query := keychain.NewItem() -query.SetSecClass(keychain.SecClassGenericPassword) -query.SetService(service) -query.SetAccount(account) -query.SetAccessGroup(accessGroup) -query.SetMatchLimit(keychain.MatchLimitAll) -query.SetReturnAttributes(true) -results, err := keychain.QueryItem(query) -if err != nil { - // Error -} else { - for _, r := range results { - fmt.Printf("%#v\n", r) - } -} -``` - -Query for a single result, returning data: - -```go -query := keychain.NewItem() -query.SetSecClass(keychain.SecClassGenericPassword) -query.SetService(service) -query.SetAccount(account) -query.SetAccessGroup(accessGroup) -query.SetMatchLimit(keychain.MatchLimitOne) -query.SetReturnData(true) -results, err := keychain.QueryItem(query) -if err != nil { - // Error -} else if len(results) != 1 { - // Not found -} else { - password := string(results[0].Data) -} -``` - -#### Delete Item - -Delete a generic password item with service and account: - -```go -item := keychain.NewItem() -item.SetSecClass(keychain.SecClassGenericPassword) -item.SetService(service) -item.SetAccount(account) -err := keychain.DeleteItem(item) -``` - -### Other - -There are some convenience methods for generic password: - -```go -// Create generic password item with service, account, label, password, access group -item := keychain.NewGenericPassword("MyService", "gabriel", "A label", []byte("toomanysecrets"), "A123456789.group.com.mycorp") -item.SetSynchronizable(keychain.SynchronizableNo) -item.SetAccessible(keychain.AccessibleWhenUnlocked) -err := keychain.AddItem(item) -if err == keychain.ErrorDuplicateItem { - // Duplicate -} - -accounts, err := keychain.GetGenericPasswordAccounts("MyService") -// Should have 1 account == "gabriel" - -err := keychain.DeleteGenericPasswordItem("MyService", "gabriel") -if err == keychain.ErrorNotFound { - // Not found -} -``` - -### OS X - -Creating a new keychain and add an item to it: - -```go - -// Add a new key chain into ~/Application Support/Keychains, with the provided password -k, err := keychain.NewKeychain("mykeychain.keychain", "my keychain password") -if err != nil { - // Error creating -} - -// Create generic password item with service, account, label, password, access group -item := keychain.NewGenericPassword("MyService", "gabriel", "A label", []byte("toomanysecrets"), "A123456789.group.com.mycorp") -item.UseKeychain(k) -err := keychain.AddItem(item) -if err != nil { - // Error creating -} -``` - -Using a Keychain at path: - -```go -k, err := keychain.NewWithPath("mykeychain.keychain") -``` - -Set a trusted applications for item (OS X only): - -```go -item := keychain.NewGenericPassword("MyService", "gabriel", "A label", []byte("toomanysecrets"), "A123456789.group.com.mycorp") -trustedApplications := []string{"/Applications/Mail.app"} -item.SetAccess(&keychain.Access{Label: "Mail", TrustedApplications: trustedApplications}) -err := keychain.AddItem(item) -``` - -## iOS - -Bindable package in `bind`. iOS project in `ios`. Run that project to test iOS. - -To re-generate framework: - -``` -(cd bind && gomobile bind -target=ios -tags=ios -o ../ios/bind.framework) -``` diff --git a/vendor/github.com/99designs/go-keychain/corefoundation.go b/vendor/github.com/99designs/go-keychain/corefoundation.go deleted file mode 100644 index c45ee7a..0000000 --- a/vendor/github.com/99designs/go-keychain/corefoundation.go +++ /dev/null @@ -1,359 +0,0 @@ -// +build darwin ios - -package keychain - -/* -#cgo LDFLAGS: -framework CoreFoundation - -#include - -// Can't cast a *uintptr to *unsafe.Pointer in Go, and casting -// C.CFTypeRef to unsafe.Pointer is unsafe in Go, so have shim functions to -// do the casting in C (where it's safe). - -// We add a suffix to the C functions below, because we copied this -// file from go-kext, which means that any project that depends on this -// package and go-kext would run into duplicate symbol errors otherwise. -// -// TODO: Move this file into its own package depended on by go-kext -// and this package. - -CFDictionaryRef CFDictionaryCreateSafe2(CFAllocatorRef allocator, const uintptr_t *keys, const uintptr_t *values, CFIndex numValues, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks) { - return CFDictionaryCreate(allocator, (const void **)keys, (const void **)values, numValues, keyCallBacks, valueCallBacks); -} - -CFArrayRef CFArrayCreateSafe2(CFAllocatorRef allocator, const uintptr_t *values, CFIndex numValues, const CFArrayCallBacks *callBacks) { - return CFArrayCreate(allocator, (const void **)values, numValues, callBacks); -} -*/ -import "C" -import ( - "errors" - "fmt" - "math" - "reflect" - "unicode/utf8" - "unsafe" -) - -// Release releases memory pointed to by a CFTypeRef. -func Release(ref C.CFTypeRef) { - C.CFRelease(ref) -} - -// BytesToCFData will return a CFDataRef and if non-nil, must be released with -// Release(ref). -func BytesToCFData(b []byte) (C.CFDataRef, error) { - if uint64(len(b)) > math.MaxUint32 { - return 0, errors.New("Data is too large") - } - var p *C.UInt8 - if len(b) > 0 { - p = (*C.UInt8)(&b[0]) - } - cfData := C.CFDataCreate(C.kCFAllocatorDefault, p, C.CFIndex(len(b))) - if cfData == 0 { - return 0, fmt.Errorf("CFDataCreate failed") - } - return cfData, nil -} - -// CFDataToBytes converts CFData to bytes. -func CFDataToBytes(cfData C.CFDataRef) ([]byte, error) { - return C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(cfData)), C.int(C.CFDataGetLength(cfData))), nil -} - -// MapToCFDictionary will return a CFDictionaryRef and if non-nil, must be -// released with Release(ref). -func MapToCFDictionary(m map[C.CFTypeRef]C.CFTypeRef) (C.CFDictionaryRef, error) { - var keys, values []C.uintptr_t - for key, value := range m { - keys = append(keys, C.uintptr_t(key)) - values = append(values, C.uintptr_t(value)) - } - numValues := len(values) - var keysPointer, valuesPointer *C.uintptr_t - if numValues > 0 { - keysPointer = &keys[0] - valuesPointer = &values[0] - } - cfDict := C.CFDictionaryCreateSafe2(C.kCFAllocatorDefault, keysPointer, valuesPointer, C.CFIndex(numValues), - &C.kCFTypeDictionaryKeyCallBacks, &C.kCFTypeDictionaryValueCallBacks) //nolint - if cfDict == 0 { - return 0, fmt.Errorf("CFDictionaryCreate failed") - } - return cfDict, nil -} - -// CFDictionaryToMap converts CFDictionaryRef to a map. -func CFDictionaryToMap(cfDict C.CFDictionaryRef) (m map[C.CFTypeRef]C.CFTypeRef) { - count := C.CFDictionaryGetCount(cfDict) - if count > 0 { - keys := make([]C.CFTypeRef, count) - values := make([]C.CFTypeRef, count) - C.CFDictionaryGetKeysAndValues(cfDict, (*unsafe.Pointer)(unsafe.Pointer(&keys[0])), (*unsafe.Pointer)(unsafe.Pointer(&values[0]))) - m = make(map[C.CFTypeRef]C.CFTypeRef, count) - for i := C.CFIndex(0); i < count; i++ { - m[keys[i]] = values[i] - } - } - return -} - -// StringToCFString will return a CFStringRef and if non-nil, must be released with -// Release(ref). -func StringToCFString(s string) (C.CFStringRef, error) { - if !utf8.ValidString(s) { - return 0, errors.New("Invalid UTF-8 string") - } - if uint64(len(s)) > math.MaxUint32 { - return 0, errors.New("String is too large") - } - - bytes := []byte(s) - var p *C.UInt8 - if len(bytes) > 0 { - p = (*C.UInt8)(&bytes[0]) - } - return C.CFStringCreateWithBytes(C.kCFAllocatorDefault, p, C.CFIndex(len(s)), C.kCFStringEncodingUTF8, C.false), nil -} - -// CFStringToString converts a CFStringRef to a string. -func CFStringToString(s C.CFStringRef) string { - p := C.CFStringGetCStringPtr(s, C.kCFStringEncodingUTF8) - if p != nil { - return C.GoString(p) - } - length := C.CFStringGetLength(s) - if length == 0 { - return "" - } - maxBufLen := C.CFStringGetMaximumSizeForEncoding(length, C.kCFStringEncodingUTF8) - if maxBufLen == 0 { - return "" - } - buf := make([]byte, maxBufLen) - var usedBufLen C.CFIndex - _ = C.CFStringGetBytes(s, C.CFRange{0, length}, C.kCFStringEncodingUTF8, C.UInt8(0), C.false, (*C.UInt8)(&buf[0]), maxBufLen, &usedBufLen) - return string(buf[:usedBufLen]) -} - -// ArrayToCFArray will return a CFArrayRef and if non-nil, must be released with -// Release(ref). -func ArrayToCFArray(a []C.CFTypeRef) C.CFArrayRef { - var values []C.uintptr_t - for _, value := range a { - values = append(values, C.uintptr_t(value)) - } - numValues := len(values) - var valuesPointer *C.uintptr_t - if numValues > 0 { - valuesPointer = &values[0] - } - return C.CFArrayCreateSafe2(C.kCFAllocatorDefault, valuesPointer, C.CFIndex(numValues), &C.kCFTypeArrayCallBacks) //nolint -} - -// CFArrayToArray converts a CFArrayRef to an array of CFTypes. -func CFArrayToArray(cfArray C.CFArrayRef) (a []C.CFTypeRef) { - count := C.CFArrayGetCount(cfArray) - if count > 0 { - a = make([]C.CFTypeRef, count) - C.CFArrayGetValues(cfArray, C.CFRange{0, count}, (*unsafe.Pointer)(unsafe.Pointer(&a[0]))) - } - return -} - -// Convertable knows how to convert an instance to a CFTypeRef. -type Convertable interface { - Convert() (C.CFTypeRef, error) -} - -// ConvertMapToCFDictionary converts a map to a CFDictionary and if non-nil, -// must be released with Release(ref). -func ConvertMapToCFDictionary(attr map[string]interface{}) (C.CFDictionaryRef, error) { - m := make(map[C.CFTypeRef]C.CFTypeRef) - for key, i := range attr { - var valueRef C.CFTypeRef - switch val := i.(type) { - default: - return 0, fmt.Errorf("Unsupported value type: %v", reflect.TypeOf(i)) - case C.CFTypeRef: - valueRef = val - case bool: - if val { - valueRef = C.CFTypeRef(C.kCFBooleanTrue) - } else { - valueRef = C.CFTypeRef(C.kCFBooleanFalse) - } - case []byte: - bytesRef, err := BytesToCFData(val) - if err != nil { - return 0, err - } - valueRef = C.CFTypeRef(bytesRef) - defer Release(valueRef) - case string: - stringRef, err := StringToCFString(val) - if err != nil { - return 0, err - } - valueRef = C.CFTypeRef(stringRef) - defer Release(valueRef) - case Convertable: - convertedRef, err := val.Convert() - if err != nil { - return 0, err - } - valueRef = convertedRef - defer Release(valueRef) - } - keyRef, err := StringToCFString(key) - if err != nil { - return 0, err - } - m[C.CFTypeRef(keyRef)] = valueRef - defer Release(C.CFTypeRef(keyRef)) - } - - cfDict, err := MapToCFDictionary(m) - if err != nil { - return 0, err - } - return cfDict, nil -} - -// CFTypeDescription returns type string for CFTypeRef. -func CFTypeDescription(ref C.CFTypeRef) string { - typeID := C.CFGetTypeID(ref) - typeDesc := C.CFCopyTypeIDDescription(typeID) - defer Release(C.CFTypeRef(typeDesc)) - return CFStringToString(typeDesc) -} - -// Convert converts a CFTypeRef to a go instance. -func Convert(ref C.CFTypeRef) (interface{}, error) { - typeID := C.CFGetTypeID(ref) - if typeID == C.CFStringGetTypeID() { - return CFStringToString(C.CFStringRef(ref)), nil - } else if typeID == C.CFDictionaryGetTypeID() { - return ConvertCFDictionary(C.CFDictionaryRef(ref)) - } else if typeID == C.CFArrayGetTypeID() { - arr := CFArrayToArray(C.CFArrayRef(ref)) - results := make([]interface{}, 0, len(arr)) - for _, ref := range arr { - v, err := Convert(ref) - if err != nil { - return nil, err - } - results = append(results, v) - } - return results, nil - } else if typeID == C.CFDataGetTypeID() { - b, err := CFDataToBytes(C.CFDataRef(ref)) - if err != nil { - return nil, err - } - return b, nil - } else if typeID == C.CFNumberGetTypeID() { - return CFNumberToInterface(C.CFNumberRef(ref)), nil - } else if typeID == C.CFBooleanGetTypeID() { - if C.CFBooleanGetValue(C.CFBooleanRef(ref)) != 0 { - return true, nil - } - return false, nil - } - - return nil, fmt.Errorf("Invalid type: %s", CFTypeDescription(ref)) -} - -// ConvertCFDictionary converts a CFDictionary to map (deep). -func ConvertCFDictionary(d C.CFDictionaryRef) (map[interface{}]interface{}, error) { - m := CFDictionaryToMap(d) - result := make(map[interface{}]interface{}) - - for k, v := range m { - gk, err := Convert(k) - if err != nil { - return nil, err - } - gv, err := Convert(v) - if err != nil { - return nil, err - } - result[gk] = gv - } - return result, nil -} - -// CFNumberToInterface converts the CFNumberRef to the most appropriate numeric -// type. -// This code is from github.com/kballard/go-osx-plist. -func CFNumberToInterface(cfNumber C.CFNumberRef) interface{} { - typ := C.CFNumberGetType(cfNumber) - switch typ { - case C.kCFNumberSInt8Type: - var sint C.SInt8 - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&sint)) //nolint - return int8(sint) - case C.kCFNumberSInt16Type: - var sint C.SInt16 - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&sint)) //nolint - return int16(sint) - case C.kCFNumberSInt32Type: - var sint C.SInt32 - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&sint)) //nolint - return int32(sint) - case C.kCFNumberSInt64Type: - var sint C.SInt64 - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&sint)) //nolint - return int64(sint) - case C.kCFNumberFloat32Type: - var float C.Float32 - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&float)) //nolint - return float32(float) - case C.kCFNumberFloat64Type: - var float C.Float64 - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&float)) //nolint - return float64(float) - case C.kCFNumberCharType: - var char C.char - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&char)) //nolint - return byte(char) - case C.kCFNumberShortType: - var short C.short - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&short)) //nolint - return int16(short) - case C.kCFNumberIntType: - var i C.int - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&i)) //nolint - return int32(i) - case C.kCFNumberLongType: - var long C.long - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&long)) //nolint - return int(long) - case C.kCFNumberLongLongType: - // This is the only type that may actually overflow us - var longlong C.longlong - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&longlong)) //nolint - return int64(longlong) - case C.kCFNumberFloatType: - var float C.float - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&float)) //nolint - return float32(float) - case C.kCFNumberDoubleType: - var double C.double - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&double)) //nolint - return float64(double) - case C.kCFNumberCFIndexType: - // CFIndex is a long - var index C.CFIndex - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&index)) //nolint - return int(index) - case C.kCFNumberNSIntegerType: - // We don't have a definition of NSInteger, but we know it's either an int or a long - var nsInt C.long - C.CFNumberGetValue(cfNumber, typ, unsafe.Pointer(&nsInt)) //nolint - return int(nsInt) - } - panic("Unknown CFNumber type") -} diff --git a/vendor/github.com/99designs/go-keychain/datetime.go b/vendor/github.com/99designs/go-keychain/datetime.go deleted file mode 100644 index 8124a6e..0000000 --- a/vendor/github.com/99designs/go-keychain/datetime.go +++ /dev/null @@ -1,68 +0,0 @@ -// +build darwin ios - -package keychain - -/* -#cgo LDFLAGS: -framework CoreFoundation - -#include -*/ -import "C" -import ( - "math" - "time" -) - -const nsPerSec = 1000 * 1000 * 1000 - -// absoluteTimeIntervalSince1970() returns the number of seconds from -// the Unix epoch (1970-01-01T00:00:00+00:00) to the Core Foundation -// absolute reference date (2001-01-01T00:00:00+00:00). It should be -// exactly 978307200. -func absoluteTimeIntervalSince1970() int64 { - return int64(C.kCFAbsoluteTimeIntervalSince1970) -} - -func unixToAbsoluteTime(s int64, ns int64) C.CFAbsoluteTime { - // Subtract as int64s first before converting to floating - // point to minimize precision loss (assuming the given time - // isn't much earlier than the Core Foundation absolute - // reference date). - abs := s - absoluteTimeIntervalSince1970() - return C.CFAbsoluteTime(abs) + C.CFTimeInterval(ns)/nsPerSec -} - -func absoluteTimeToUnix(abs C.CFAbsoluteTime) (int64, int64) { - int, frac := math.Modf(float64(abs)) - return int64(int) + absoluteTimeIntervalSince1970(), int64(frac * nsPerSec) -} - -// TimeToCFDate will convert the given time.Time to a CFDateRef, which -// must be released with Release(ref). -func TimeToCFDate(t time.Time) C.CFDateRef { - s := t.Unix() - ns := int64(t.Nanosecond()) - abs := unixToAbsoluteTime(s, ns) - return C.CFDateCreate(C.kCFAllocatorDefault, abs) -} - -// CFDateToTime will convert the given CFDateRef to a time.Time. -func CFDateToTime(d C.CFDateRef) time.Time { - abs := C.CFDateGetAbsoluteTime(d) - s, ns := absoluteTimeToUnix(abs) - return time.Unix(s, ns) -} - -// Wrappers around C functions for testing. - -func cfDateToAbsoluteTime(d C.CFDateRef) C.CFAbsoluteTime { - return C.CFDateGetAbsoluteTime(d) -} - -func absoluteTimeToCFDate(abs C.CFAbsoluteTime) C.CFDateRef { - return C.CFDateCreate(C.kCFAllocatorDefault, abs) -} - -func releaseCFDate(d C.CFDateRef) { - Release(C.CFTypeRef(d)) -} diff --git a/vendor/github.com/99designs/go-keychain/ios.go b/vendor/github.com/99designs/go-keychain/ios.go deleted file mode 100644 index abbaf28..0000000 --- a/vendor/github.com/99designs/go-keychain/ios.go +++ /dev/null @@ -1,22 +0,0 @@ -// +build darwin,ios - -package keychain - -/* -#cgo LDFLAGS: -framework CoreFoundation -framework Security - -#include -#include -*/ -import "C" - -var AccessibleKey = attrKey(C.CFTypeRef(C.kSecAttrAccessible)) -var accessibleTypeRef = map[Accessible]C.CFTypeRef{ - AccessibleWhenUnlocked: C.CFTypeRef(C.kSecAttrAccessibleWhenUnlocked), - AccessibleAfterFirstUnlock: C.CFTypeRef(C.kSecAttrAccessibleAfterFirstUnlock), - AccessibleAlways: C.CFTypeRef(C.kSecAttrAccessibleAlways), - AccessibleWhenPasscodeSetThisDeviceOnly: C.CFTypeRef(C.kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly), - AccessibleWhenUnlockedThisDeviceOnly: C.CFTypeRef(C.kSecAttrAccessibleWhenUnlockedThisDeviceOnly), - AccessibleAfterFirstUnlockThisDeviceOnly: C.CFTypeRef(C.kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly), - AccessibleAccessibleAlwaysThisDeviceOnly: C.CFTypeRef(C.kSecAttrAccessibleAlwaysThisDeviceOnly), -} diff --git a/vendor/github.com/99designs/go-keychain/keychain.go b/vendor/github.com/99designs/go-keychain/keychain.go deleted file mode 100644 index f5d02ad..0000000 --- a/vendor/github.com/99designs/go-keychain/keychain.go +++ /dev/null @@ -1,531 +0,0 @@ -// +build darwin - -package keychain - -// See https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/index.html for the APIs used below. - -// Also see https://developer.apple.com/library/ios/documentation/Security/Conceptual/keychainServConcepts/01introduction/introduction.html . - -/* -#cgo LDFLAGS: -framework CoreFoundation -framework Security - -#include -#include -*/ -import "C" -import ( - "fmt" - "time" -) - -// Error defines keychain errors -type Error int - -var ( - // ErrorUnimplemented corresponds to errSecUnimplemented result code - ErrorUnimplemented = Error(C.errSecUnimplemented) - // ErrorParam corresponds to errSecParam result code - ErrorParam = Error(C.errSecParam) - // ErrorAllocate corresponds to errSecAllocate result code - ErrorAllocate = Error(C.errSecAllocate) - // ErrorNotAvailable corresponds to errSecNotAvailable result code - ErrorNotAvailable = Error(C.errSecNotAvailable) - // ErrorAuthFailed corresponds to errSecAuthFailed result code - ErrorAuthFailed = Error(C.errSecAuthFailed) - // ErrorDuplicateItem corresponds to errSecDuplicateItem result code - ErrorDuplicateItem = Error(C.errSecDuplicateItem) - // ErrorItemNotFound corresponds to errSecItemNotFound result code - ErrorItemNotFound = Error(C.errSecItemNotFound) - // ErrorInteractionNotAllowed corresponds to errSecInteractionNotAllowed result code - ErrorInteractionNotAllowed = Error(C.errSecInteractionNotAllowed) - // ErrorDecode corresponds to errSecDecode result code - ErrorDecode = Error(C.errSecDecode) - // ErrorNoSuchKeychain corresponds to errSecNoSuchKeychain result code - ErrorNoSuchKeychain = Error(C.errSecNoSuchKeychain) - // ErrorNoAcccessForItem corresponds to errSecNoAccessForItem result code - ErrorNoAccessForItem = Error(C.errSecNoAccessForItem) -) - -func checkError(errCode C.OSStatus) error { - if errCode == C.errSecSuccess { - return nil - } - return Error(errCode) -} - -func (k Error) Error() (msg string) { - // SecCopyErrorMessageString is only available on OSX, so derive manually. - // Messages derived from `$ security error $errcode`. - switch k { - case ErrorUnimplemented: - msg = "Function or operation not implemented." - case ErrorParam: - msg = "One or more parameters passed to the function were not valid." - case ErrorAllocate: - msg = "Failed to allocate memory." - case ErrorNotAvailable: - msg = "No keychain is available. You may need to restart your computer." - case ErrorAuthFailed: - msg = "The user name or passphrase you entered is not correct." - case ErrorDuplicateItem: - msg = "The specified item already exists in the keychain." - case ErrorItemNotFound: - msg = "The specified item could not be found in the keychain." - case ErrorInteractionNotAllowed: - msg = "User interaction is not allowed." - case ErrorDecode: - msg = "Unable to decode the provided data." - case ErrorNoSuchKeychain: - msg = "The specified keychain could not be found." - case ErrorNoAccessForItem: - msg = "The specified item has no access control." - default: - msg = "Keychain Error." - } - return fmt.Sprintf("%s (%d)", msg, k) -} - -// SecClass is the items class code -type SecClass int - -// Keychain Item Classes -var ( - /* - kSecClassGenericPassword item attributes: - kSecAttrAccess (OS X only) - kSecAttrAccessGroup (iOS; also OS X if kSecAttrSynchronizable specified) - kSecAttrAccessible (iOS; also OS X if kSecAttrSynchronizable specified) - kSecAttrAccount - kSecAttrService - */ - SecClassGenericPassword SecClass = 1 - SecClassInternetPassword SecClass = 2 -) - -// SecClassKey is the key type for SecClass -var SecClassKey = attrKey(C.CFTypeRef(C.kSecClass)) -var secClassTypeRef = map[SecClass]C.CFTypeRef{ - SecClassGenericPassword: C.CFTypeRef(C.kSecClassGenericPassword), - SecClassInternetPassword: C.CFTypeRef(C.kSecClassInternetPassword), -} - -var ( - // ServiceKey is for kSecAttrService - ServiceKey = attrKey(C.CFTypeRef(C.kSecAttrService)) - // LabelKey is for kSecAttrLabel - LabelKey = attrKey(C.CFTypeRef(C.kSecAttrLabel)) - // AccountKey is for kSecAttrAccount - AccountKey = attrKey(C.CFTypeRef(C.kSecAttrAccount)) - // AccessGroupKey is for kSecAttrAccessGroup - AccessGroupKey = attrKey(C.CFTypeRef(C.kSecAttrAccessGroup)) - // DataKey is for kSecValueData - DataKey = attrKey(C.CFTypeRef(C.kSecValueData)) - // DescriptionKey is for kSecAttrDescription - DescriptionKey = attrKey(C.CFTypeRef(C.kSecAttrDescription)) - // CreationDateKey is for kSecAttrCreationDate - CreationDateKey = attrKey(C.CFTypeRef(C.kSecAttrCreationDate)) - // ModificationDateKey is for kSecAttrModificationDate - ModificationDateKey = attrKey(C.CFTypeRef(C.kSecAttrModificationDate)) -) - -// Synchronizable is the items synchronizable status -type Synchronizable int - -const ( - // SynchronizableDefault is the default setting - SynchronizableDefault Synchronizable = 0 - // SynchronizableAny is for kSecAttrSynchronizableAny - SynchronizableAny = 1 - // SynchronizableYes enables synchronization - SynchronizableYes = 2 - // SynchronizableNo disables synchronization - SynchronizableNo = 3 -) - -// SynchronizableKey is the key type for Synchronizable -var SynchronizableKey = attrKey(C.CFTypeRef(C.kSecAttrSynchronizable)) -var syncTypeRef = map[Synchronizable]C.CFTypeRef{ - SynchronizableAny: C.CFTypeRef(C.kSecAttrSynchronizableAny), - SynchronizableYes: C.CFTypeRef(C.kCFBooleanTrue), - SynchronizableNo: C.CFTypeRef(C.kCFBooleanFalse), -} - -// Accessible is the items accessibility -type Accessible int - -const ( - // AccessibleDefault is the default - AccessibleDefault Accessible = 0 - // AccessibleWhenUnlocked is when unlocked - AccessibleWhenUnlocked = 1 - // AccessibleAfterFirstUnlock is after first unlock - AccessibleAfterFirstUnlock = 2 - // AccessibleAlways is always - AccessibleAlways = 3 - // AccessibleWhenPasscodeSetThisDeviceOnly is when passcode is set - AccessibleWhenPasscodeSetThisDeviceOnly = 4 - // AccessibleWhenUnlockedThisDeviceOnly is when unlocked for this device only - AccessibleWhenUnlockedThisDeviceOnly = 5 - // AccessibleAfterFirstUnlockThisDeviceOnly is after first unlock for this device only - AccessibleAfterFirstUnlockThisDeviceOnly = 6 - // AccessibleAccessibleAlwaysThisDeviceOnly is always for this device only - AccessibleAccessibleAlwaysThisDeviceOnly = 7 -) - -// MatchLimit is whether to limit results on query -type MatchLimit int - -const ( - // MatchLimitDefault is the default - MatchLimitDefault MatchLimit = 0 - // MatchLimitOne limits to one result - MatchLimitOne = 1 - // MatchLimitAll is no limit - MatchLimitAll = 2 -) - -// MatchLimitKey is key type for MatchLimit -var MatchLimitKey = attrKey(C.CFTypeRef(C.kSecMatchLimit)) -var matchTypeRef = map[MatchLimit]C.CFTypeRef{ - MatchLimitOne: C.CFTypeRef(C.kSecMatchLimitOne), - MatchLimitAll: C.CFTypeRef(C.kSecMatchLimitAll), -} - -// ReturnAttributesKey is key type for kSecReturnAttributes -var ReturnAttributesKey = attrKey(C.CFTypeRef(C.kSecReturnAttributes)) - -// ReturnDataKey is key type for kSecReturnData -var ReturnDataKey = attrKey(C.CFTypeRef(C.kSecReturnData)) - -// ReturnRefKey is key type for kSecReturnRef -var ReturnRefKey = attrKey(C.CFTypeRef(C.kSecReturnRef)) - -// Item for adding, querying or deleting. -type Item struct { - // Values can be string, []byte, Convertable or CFTypeRef (constant). - attr map[string]interface{} -} - -// SetSecClass sets the security class -func (k *Item) SetSecClass(sc SecClass) { - k.attr[SecClassKey] = secClassTypeRef[sc] -} - -// SetString sets a string attibute for a string key -func (k *Item) SetString(key string, s string) { - if s != "" { - k.attr[key] = s - } else { - delete(k.attr, key) - } -} - -// SetService sets the service attribute -func (k *Item) SetService(s string) { - k.SetString(ServiceKey, s) -} - -// SetAccount sets the account attribute -func (k *Item) SetAccount(a string) { - k.SetString(AccountKey, a) -} - -// SetLabel sets the label attribute -func (k *Item) SetLabel(l string) { - k.SetString(LabelKey, l) -} - -// SetDescription sets the description attribute -func (k *Item) SetDescription(s string) { - k.SetString(DescriptionKey, s) -} - -// SetData sets the data attribute -func (k *Item) SetData(b []byte) { - if b != nil { - k.attr[DataKey] = b - } else { - delete(k.attr, DataKey) - } -} - -// SetAccessGroup sets the access group attribute -func (k *Item) SetAccessGroup(ag string) { - k.SetString(AccessGroupKey, ag) -} - -// SetSynchronizable sets the synchronizable attribute -func (k *Item) SetSynchronizable(sync Synchronizable) { - if sync != SynchronizableDefault { - k.attr[SynchronizableKey] = syncTypeRef[sync] - } else { - delete(k.attr, SynchronizableKey) - } -} - -// SetAccessible sets the accessible attribute -func (k *Item) SetAccessible(accessible Accessible) { - if accessible != AccessibleDefault { - k.attr[AccessibleKey] = accessibleTypeRef[accessible] - } else { - delete(k.attr, AccessibleKey) - } -} - -// SetMatchLimit sets the match limit -func (k *Item) SetMatchLimit(matchLimit MatchLimit) { - if matchLimit != MatchLimitDefault { - k.attr[MatchLimitKey] = matchTypeRef[matchLimit] - } else { - delete(k.attr, MatchLimitKey) - } -} - -// SetReturnAttributes sets the return value type on query -func (k *Item) SetReturnAttributes(b bool) { - k.attr[ReturnAttributesKey] = b -} - -// SetReturnData enables returning data on query -func (k *Item) SetReturnData(b bool) { - k.attr[ReturnDataKey] = b -} - -// SetReturnRef enables returning references on query -func (k *Item) SetReturnRef(b bool) { - k.attr[ReturnRefKey] = b -} - -// NewItem is a new empty keychain item -func NewItem() Item { - return Item{make(map[string]interface{})} -} - -// NewGenericPassword creates a generic password item with the default keychain. This is a convenience method. -func NewGenericPassword(service string, account string, label string, data []byte, accessGroup string) Item { - item := NewItem() - item.SetSecClass(SecClassGenericPassword) - item.SetService(service) - item.SetAccount(account) - item.SetLabel(label) - item.SetData(data) - item.SetAccessGroup(accessGroup) - return item -} - -// AddItem adds a Item to a Keychain -func AddItem(item Item) error { - cfDict, err := ConvertMapToCFDictionary(item.attr) - if err != nil { - return err - } - defer Release(C.CFTypeRef(cfDict)) - - errCode := C.SecItemAdd(cfDict, nil) - err = checkError(errCode) - return err -} - -// UpdateItem updates the queryItem with the parameters from updateItem -func UpdateItem(queryItem Item, updateItem Item) error { - cfDict, err := ConvertMapToCFDictionary(queryItem.attr) - if err != nil { - return err - } - defer Release(C.CFTypeRef(cfDict)) - cfDictUpdate, err := ConvertMapToCFDictionary(updateItem.attr) - if err != nil { - return err - } - defer Release(C.CFTypeRef(cfDictUpdate)) - errCode := C.SecItemUpdate(cfDict, cfDictUpdate) - err = checkError(errCode) - return err -} - -// QueryResult stores all possible results from queries. -// Not all fields are applicable all the time. Results depend on query. -type QueryResult struct { - Service string - Account string - AccessGroup string - Label string - Description string - Data []byte - CreationDate time.Time - ModificationDate time.Time -} - -// QueryItemRef returns query result as CFTypeRef. You must release it when you are done. -func QueryItemRef(item Item) (C.CFTypeRef, error) { - cfDict, err := ConvertMapToCFDictionary(item.attr) - if err != nil { - return 0, err - } - defer Release(C.CFTypeRef(cfDict)) - - var resultsRef C.CFTypeRef - errCode := C.SecItemCopyMatching(cfDict, &resultsRef) //nolint - if Error(errCode) == ErrorItemNotFound { - return 0, nil - } - err = checkError(errCode) - if err != nil { - return 0, err - } - return resultsRef, nil -} - -// QueryItem returns a list of query results. -func QueryItem(item Item) ([]QueryResult, error) { - resultsRef, err := QueryItemRef(item) - if err != nil { - return nil, err - } - if resultsRef == 0 { - return nil, nil - } - defer Release(resultsRef) - - results := make([]QueryResult, 0, 1) - - typeID := C.CFGetTypeID(resultsRef) - if typeID == C.CFArrayGetTypeID() { - arr := CFArrayToArray(C.CFArrayRef(resultsRef)) - for _, ref := range arr { - elementTypeID := C.CFGetTypeID(ref) - if elementTypeID == C.CFDictionaryGetTypeID() { - item, err := convertResult(C.CFDictionaryRef(ref)) - if err != nil { - return nil, err - } - results = append(results, *item) - } else { - return nil, fmt.Errorf("invalid result type (If you SetReturnRef(true) you should use QueryItemRef directly)") - } - } - } else if typeID == C.CFDictionaryGetTypeID() { - item, err := convertResult(C.CFDictionaryRef(resultsRef)) - if err != nil { - return nil, err - } - results = append(results, *item) - } else if typeID == C.CFDataGetTypeID() { - b, err := CFDataToBytes(C.CFDataRef(resultsRef)) - if err != nil { - return nil, err - } - item := QueryResult{Data: b} - results = append(results, item) - } else { - return nil, fmt.Errorf("Invalid result type: %s", CFTypeDescription(resultsRef)) - } - - return results, nil -} - -func attrKey(ref C.CFTypeRef) string { - return CFStringToString(C.CFStringRef(ref)) -} - -func convertResult(d C.CFDictionaryRef) (*QueryResult, error) { - m := CFDictionaryToMap(d) - result := QueryResult{} - for k, v := range m { - switch attrKey(k) { - case ServiceKey: - result.Service = CFStringToString(C.CFStringRef(v)) - case AccountKey: - result.Account = CFStringToString(C.CFStringRef(v)) - case AccessGroupKey: - result.AccessGroup = CFStringToString(C.CFStringRef(v)) - case LabelKey: - result.Label = CFStringToString(C.CFStringRef(v)) - case DescriptionKey: - result.Description = CFStringToString(C.CFStringRef(v)) - case DataKey: - b, err := CFDataToBytes(C.CFDataRef(v)) - if err != nil { - return nil, err - } - result.Data = b - case CreationDateKey: - result.CreationDate = CFDateToTime(C.CFDateRef(v)) - case ModificationDateKey: - result.ModificationDate = CFDateToTime(C.CFDateRef(v)) - // default: - // fmt.Printf("Unhandled key in conversion: %v = %v\n", cfTypeValue(k), cfTypeValue(v)) - } - } - return &result, nil -} - -// DeleteGenericPasswordItem removes a generic password item. -func DeleteGenericPasswordItem(service string, account string) error { - item := NewItem() - item.SetSecClass(SecClassGenericPassword) - item.SetService(service) - item.SetAccount(account) - return DeleteItem(item) -} - -// DeleteItem removes a Item -func DeleteItem(item Item) error { - cfDict, err := ConvertMapToCFDictionary(item.attr) - if err != nil { - return err - } - defer Release(C.CFTypeRef(cfDict)) - - errCode := C.SecItemDelete(cfDict) - return checkError(errCode) -} - -// GetAccountsForService is deprecated -func GetAccountsForService(service string) ([]string, error) { - return GetGenericPasswordAccounts(service) -} - -// GetGenericPasswordAccounts returns generic password accounts for service. This is a convenience method. -func GetGenericPasswordAccounts(service string) ([]string, error) { - query := NewItem() - query.SetSecClass(SecClassGenericPassword) - query.SetService(service) - query.SetMatchLimit(MatchLimitAll) - query.SetReturnAttributes(true) - results, err := QueryItem(query) - if err != nil { - return nil, err - } - - accounts := make([]string, 0, len(results)) - for _, r := range results { - accounts = append(accounts, r.Account) - } - - return accounts, nil -} - -// GetGenericPassword returns password data for service and account. This is a convenience method. -// If item is not found returns nil, nil. -func GetGenericPassword(service string, account string, label string, accessGroup string) ([]byte, error) { - query := NewItem() - query.SetSecClass(SecClassGenericPassword) - query.SetService(service) - query.SetAccount(account) - query.SetLabel(label) - query.SetAccessGroup(accessGroup) - query.SetMatchLimit(MatchLimitOne) - query.SetReturnData(true) - results, err := QueryItem(query) - if err != nil { - return nil, err - } - if len(results) > 1 { - return nil, fmt.Errorf("Too many results") - } - if len(results) == 1 { - return results[0].Data, nil - } - return nil, nil -} diff --git a/vendor/github.com/99designs/go-keychain/macos.go b/vendor/github.com/99designs/go-keychain/macos.go deleted file mode 100644 index 4004349..0000000 --- a/vendor/github.com/99designs/go-keychain/macos.go +++ /dev/null @@ -1,272 +0,0 @@ -// +build darwin,!ios - -package keychain - -/* -#cgo LDFLAGS: -framework CoreFoundation -framework Security -#cgo CFLAGS: -w - -#include -#include -*/ -import "C" -import ( - "os" - "unsafe" -) - -// AccessibleKey is key for kSecAttrAccessible -var AccessibleKey = attrKey(C.CFTypeRef(C.kSecAttrAccessible)) -var accessibleTypeRef = map[Accessible]C.CFTypeRef{ - AccessibleWhenUnlocked: C.CFTypeRef(C.kSecAttrAccessibleWhenUnlocked), - AccessibleAfterFirstUnlock: C.CFTypeRef(C.kSecAttrAccessibleAfterFirstUnlock), - AccessibleAlways: C.CFTypeRef(C.kSecAttrAccessibleAlways), - AccessibleWhenUnlockedThisDeviceOnly: C.CFTypeRef(C.kSecAttrAccessibleWhenUnlockedThisDeviceOnly), - AccessibleAfterFirstUnlockThisDeviceOnly: C.CFTypeRef(C.kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly), - AccessibleAccessibleAlwaysThisDeviceOnly: C.CFTypeRef(C.kSecAttrAccessibleAlwaysThisDeviceOnly), - - // Only available in 10.10 - //AccessibleWhenPasscodeSetThisDeviceOnly: C.CFTypeRef(C.kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly), -} - -var ( - // AccessKey is key for kSecAttrAccess - AccessKey = attrKey(C.CFTypeRef(C.kSecAttrAccess)) -) - -// createAccess creates a SecAccessRef as CFTypeRef. -// The returned SecAccessRef, if non-nil, must be released via CFRelease. -func createAccess(label string, trustedApplications []string) (C.CFTypeRef, error) { - var err error - var labelRef C.CFStringRef - if labelRef, err = StringToCFString(label); err != nil { - return 0, err - } - defer C.CFRelease(C.CFTypeRef(labelRef)) - - var trustedApplicationsArray C.CFArrayRef - if trustedApplications != nil { - if len(trustedApplications) > 0 { - // Always prepend with empty string which signifies that we - // include a NULL application, which means ourselves. - trustedApplications = append([]string{""}, trustedApplications...) - } - - var trustedApplicationsRefs []C.CFTypeRef - for _, trustedApplication := range trustedApplications { - trustedApplicationRef, createErr := createTrustedApplication(trustedApplication) - if createErr != nil { - return 0, createErr - } - defer C.CFRelease(trustedApplicationRef) - trustedApplicationsRefs = append(trustedApplicationsRefs, trustedApplicationRef) - } - - trustedApplicationsArray = ArrayToCFArray(trustedApplicationsRefs) - defer C.CFRelease(C.CFTypeRef(trustedApplicationsArray)) - } - - var access C.SecAccessRef - errCode := C.SecAccessCreate(labelRef, trustedApplicationsArray, &access) //nolint - err = checkError(errCode) - if err != nil { - return 0, err - } - - return C.CFTypeRef(access), nil -} - -// createTrustedApplication creates a SecTrustedApplicationRef as a CFTypeRef. -// The returned SecTrustedApplicationRef, if non-nil, must be released via CFRelease. -func createTrustedApplication(trustedApplication string) (C.CFTypeRef, error) { - var trustedApplicationCStr *C.char - if trustedApplication != "" { - trustedApplicationCStr = C.CString(trustedApplication) - defer C.free(unsafe.Pointer(trustedApplicationCStr)) - } - - var trustedApplicationRef C.SecTrustedApplicationRef - errCode := C.SecTrustedApplicationCreateFromPath(trustedApplicationCStr, &trustedApplicationRef) //nolint - err := checkError(errCode) - if err != nil { - return 0, err - } - - return C.CFTypeRef(trustedApplicationRef), nil -} - -// Access defines whats applications can use the keychain item -type Access struct { - Label string - TrustedApplications []string -} - -// Convert converts Access to CFTypeRef. -// The returned CFTypeRef, if non-nil, must be released via CFRelease. -func (a Access) Convert() (C.CFTypeRef, error) { - return createAccess(a.Label, a.TrustedApplications) -} - -// SetAccess sets Access on Item -func (k *Item) SetAccess(a *Access) { - if a != nil { - k.attr[AccessKey] = a - } else { - delete(k.attr, AccessKey) - } -} - -// DeleteItemRef deletes a keychain item reference. -func DeleteItemRef(ref C.CFTypeRef) error { - errCode := C.SecKeychainItemDelete(C.SecKeychainItemRef(ref)) - return checkError(errCode) -} - -var ( - // KeychainKey is key for kSecUseKeychain - KeychainKey = attrKey(C.CFTypeRef(C.kSecUseKeychain)) - // MatchSearchListKey is key for kSecMatchSearchList - MatchSearchListKey = attrKey(C.CFTypeRef(C.kSecMatchSearchList)) -) - -// Keychain represents the path to a specific OSX keychain -type Keychain struct { - path string -} - -// NewKeychain creates a new keychain file with a password -func NewKeychain(path string, password string) (Keychain, error) { - return newKeychain(path, password, false) -} - -// NewKeychainWithPrompt creates a new Keychain and prompts user for password -func NewKeychainWithPrompt(path string) (Keychain, error) { - return newKeychain(path, "", true) -} - -func newKeychain(path, password string, promptUser bool) (Keychain, error) { - pathRef := C.CString(path) - defer C.free(unsafe.Pointer(pathRef)) - - var errCode C.OSStatus - var kref C.SecKeychainRef - - if promptUser { - errCode = C.SecKeychainCreate(pathRef, C.UInt32(0), nil, C.Boolean(1), 0, &kref) //nolint - } else { - passwordRef := C.CString(password) - defer C.free(unsafe.Pointer(passwordRef)) - errCode = C.SecKeychainCreate(pathRef, C.UInt32(len(password)), unsafe.Pointer(passwordRef), C.Boolean(0), 0, &kref) //nolint - } - - if err := checkError(errCode); err != nil { - return Keychain{}, err - } - - // TODO: Without passing in kref I get 'One or more parameters passed to the function were not valid (-50)' - defer Release(C.CFTypeRef(kref)) - - return Keychain{ - path: path, - }, nil -} - -// NewWithPath to use an existing keychain -func NewWithPath(path string) Keychain { - return Keychain{ - path: path, - } -} - -// Status returns the status of the keychain -func (kc Keychain) Status() error { - // returns no error even if it doesn't exist - kref, err := openKeychainRef(kc.path) - if err != nil { - return err - } - defer C.CFRelease(C.CFTypeRef(kref)) - - var status C.SecKeychainStatus - return checkError(C.SecKeychainGetStatus(kref, &status)) -} - -// The returned SecKeychainRef, if non-nil, must be released via CFRelease. -func openKeychainRef(path string) (C.SecKeychainRef, error) { - pathName := C.CString(path) - defer C.free(unsafe.Pointer(pathName)) - - var kref C.SecKeychainRef - if err := checkError(C.SecKeychainOpen(pathName, &kref)); err != nil { //nolint - return 0, err - } - - return kref, nil -} - -// UnlockAtPath unlocks keychain at path -func UnlockAtPath(path string, password string) error { - kref, err := openKeychainRef(path) - defer Release(C.CFTypeRef(kref)) - if err != nil { - return err - } - passwordRef := C.CString(password) - defer C.free(unsafe.Pointer(passwordRef)) - return checkError(C.SecKeychainUnlock(kref, C.UInt32(len(password)), unsafe.Pointer(passwordRef), C.Boolean(1))) -} - -// LockAtPath locks keychain at path -func LockAtPath(path string) error { - kref, err := openKeychainRef(path) - defer Release(C.CFTypeRef(kref)) - if err != nil { - return err - } - return checkError(C.SecKeychainLock(kref)) -} - -// Delete the Keychain -func (kc *Keychain) Delete() error { - return os.Remove(kc.path) -} - -// Convert Keychain to CFTypeRef. -// The returned CFTypeRef, if non-nil, must be released via CFRelease. -func (kc Keychain) Convert() (C.CFTypeRef, error) { - keyRef, err := openKeychainRef(kc.path) - return C.CFTypeRef(keyRef), err -} - -type keychainArray []Keychain - -// Convert the keychainArray to a CFTypeRef. -// The returned CFTypeRef, if non-nil, must be released via CFRelease. -func (ka keychainArray) Convert() (C.CFTypeRef, error) { - var refs = make([]C.CFTypeRef, len(ka)) - var err error - - for idx, kc := range ka { - if refs[idx], err = kc.Convert(); err != nil { - // If we error trying to convert lets release any we converted before - for _, ref := range refs { - if ref != 0 { - Release(ref) - } - } - return 0, err - } - } - - return C.CFTypeRef(ArrayToCFArray(refs)), nil -} - -// SetMatchSearchList sets match type on keychains -func (k *Item) SetMatchSearchList(karr ...Keychain) { - k.attr[MatchSearchListKey] = keychainArray(karr) -} - -// UseKeychain tells item to use the specified Keychain -func (k *Item) UseKeychain(kc Keychain) { - k.attr[KeychainKey] = kc -} diff --git a/vendor/github.com/99designs/go-keychain/util.go b/vendor/github.com/99designs/go-keychain/util.go deleted file mode 100644 index 29cbfc6..0000000 --- a/vendor/github.com/99designs/go-keychain/util.go +++ /dev/null @@ -1,31 +0,0 @@ -package keychain - -import ( - "crypto/rand" - "encoding/base32" - "strings" -) - -var randRead = rand.Read - -// RandomID returns random ID (base32) string with prefix, using 256 bits as -// recommended by tptacek: https://gist.github.com/tqbf/be58d2d39690c3b366ad -func RandomID(prefix string) (string, error) { - buf, err := RandBytes(32) - if err != nil { - return "", err - } - str := base32.StdEncoding.EncodeToString(buf) - str = strings.Replace(str, "=", "", -1) - str = prefix + str - return str, nil -} - -// RandBytes returns random bytes of length -func RandBytes(length int) ([]byte, error) { - buf := make([]byte, length) - if _, err := randRead(buf); err != nil { - return nil, err - } - return buf, nil -} diff --git a/vendor/github.com/99designs/keyring/.gitattributes b/vendor/github.com/99designs/keyring/.gitattributes deleted file mode 100644 index d207b18..0000000 --- a/vendor/github.com/99designs/keyring/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.go text eol=lf diff --git a/vendor/github.com/99designs/keyring/.gitignore b/vendor/github.com/99designs/keyring/.gitignore deleted file mode 100644 index 8000dd9..0000000 --- a/vendor/github.com/99designs/keyring/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.vagrant diff --git a/vendor/github.com/99designs/keyring/.golangci.yml b/vendor/github.com/99designs/keyring/.golangci.yml deleted file mode 100644 index f83428e..0000000 --- a/vendor/github.com/99designs/keyring/.golangci.yml +++ /dev/null @@ -1,29 +0,0 @@ -linters: - enable: - - bodyclose - - contextcheck - - depguard - - durationcheck - - dupl - - errchkjson - - errname - - exhaustive - - exportloopref - - gocritic - - gofmt - - goimports - - makezero - - misspell - - nakedret - - nilerr - - nilnil - - noctx - - prealloc - - revive - # - rowserrcheck - - thelper - - tparallel - - unconvert - - unparam - # - wastedassign - - whitespace diff --git a/vendor/github.com/99designs/keyring/LICENSE b/vendor/github.com/99designs/keyring/LICENSE deleted file mode 100644 index 0fe9e46..0000000 --- a/vendor/github.com/99designs/keyring/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 99designs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/vendor/github.com/99designs/keyring/README.md b/vendor/github.com/99designs/keyring/README.md deleted file mode 100644 index 629a6aa..0000000 --- a/vendor/github.com/99designs/keyring/README.md +++ /dev/null @@ -1,67 +0,0 @@ -Keyring -======= -[![Build Status](https://github.com/99designs/keyring/workflows/Continuous%20Integration/badge.svg)](https://github.com/99designs/keyring/actions) -[![Documentation](https://godoc.org/github.com/99designs/keyring?status.svg)](https://godoc.org/github.com/99designs/keyring) - -Keyring provides a common interface to a range of secure credential storage services. Originally developed as part of [AWS Vault](https://github.com/99designs/aws-vault), a command line tool for securely managing AWS access from developer workstations. - -Currently Keyring supports the following backends - * [macOS Keychain](https://support.apple.com/en-au/guide/keychain-access/welcome/mac) - * [Windows Credential Manager](https://support.microsoft.com/en-au/help/4026814/windows-accessing-credential-manager) - * Secret Service ([Gnome Keyring](https://wiki.gnome.org/Projects/GnomeKeyring), [KWallet](https://kde.org/applications/system/org.kde.kwalletmanager5)) - * [KWallet](https://kde.org/applications/system/org.kde.kwalletmanager5) - * [Pass](https://www.passwordstore.org/) - * [Encrypted file (JWT)](https://datatracker.ietf.org/doc/html/rfc7519) - * [KeyCtl](https://linux.die.net/man/1/keyctl) - - -## Usage - -The short version of how to use keyring is shown below. - -```go -ring, _ := keyring.Open(keyring.Config{ - ServiceName: "example", -}) - -_ = ring.Set(keyring.Item{ - Key: "foo", - Data: []byte("secret-bar"), -}) - -i, _ := ring.Get("foo") - -fmt.Printf("%s", i.Data) -``` - -For more detail on the API please check [the keyring godocs](https://godoc.org/github.com/99designs/keyring) - - -## Testing - -[Vagrant](https://www.vagrantup.com/) is used to create linux and windows test environments. - -```bash -# Start vagrant -vagrant up - -# Run go tests on all platforms -./bin/go-test -``` - - -## Contributing - -Contributions to the keyring package are most welcome from engineers of all backgrounds and skill levels. In particular the addition of extra backends across popular operating systems would be appreciated. - -This project will adhere to the [Go Community Code of Conduct](https://golang.org/conduct) in the github provided discussion spaces, with the moderators being the 99designs engineering team. - -To make a contribution: - - * Fork the repository - * Make your changes on the fork - * Submit a pull request back to this repo with a clear description of the problem you're solving - * Ensure your PR passes all current (and new) tests - * Ideally verify that [aws-vault](https://github.com/99designs/aws-vault) works with your changes (optional) - -...and we'll do our best to get your work merged in diff --git a/vendor/github.com/99designs/keyring/Vagrantfile b/vendor/github.com/99designs/keyring/Vagrantfile deleted file mode 100644 index 7d30d2a..0000000 --- a/vendor/github.com/99designs/keyring/Vagrantfile +++ /dev/null @@ -1,85 +0,0 @@ -Vagrant.configure("2") do |config| - - config.vm.define "linux" do |linux| - linux.vm.box = "generic/fedora32" - - linux.vm.provider "virtualbox" do |vb| - vb.gui = true - vb.memory = 2048 - vb.cpus = 2 - - # VBoxVGA flickers constantly, use vmsvga instead which doesn't have that problem - vb.customize ["modifyvm", :id, "--graphicscontroller", "vmsvga"] - end - - # mount the project into /keyring - linux.vm.synced_folder ".", "/keyring" - - # install gnome desktop and auto login - linux.vm.provision "shell", inline: "sudo dnf install -y --exclude='gnome-initial-setup' @gnome-desktop langpacks-en" - linux.vm.provision "shell", inline: <<-SHELL - sudo sed -i -e 's/\\[daemon\\]/\\[daemon\\]\\nAutomaticLoginEnable=True\\nAutomaticLogin=vagrant\\n/' \ - /etc/gdm/custom.conf - SHELL - linux.vm.provision "shell", inline: "sudo systemctl set-default graphical.target" - linux.vm.provision "shell", inline: "sudo systemctl isolate graphical.target" - - # set the root password - sometimes prompts show up in gnome needing to install software - linux.vm.provision "shell", inline: "echo 'vagrant' | sudo passwd root --stdin" - - # install gnome keyring - linux.vm.provision "shell", inline: "sudo dnf install -y gnome-keyring seahorse" - - # install kwallet - linux.vm.provision "shell", inline: "sudo dnf install -y kwalletmanager5" - - # install pass - linux.vm.provision "shell", inline: "sudo dnf install -y pass" - - # install golang - linux.vm.provision "shell", inline: "sudo dnf install -y go" - end - - - config.vm.define "windows" do |windows| - windows.vm.box = "StefanScherer/windows_10" - - windows.vm.provider "virtualbox" do |vb| - vb.gui = true - vb.memory = 2048 - vb.cpus = 2 - end - - # mount the project into c:\keyring - windows.vm.synced_folder ".", "/keyring" - - # install chocolately - windows.vm.provision "shell", privileged: true, inline: <<-SHELL - Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) - choco feature disable -n=showDownloadProgress - SHELL - - # install golang - windows.vm.provision "shell", privileged: true, inline: "choco install -y git golang" - end - - config.vm.post_up_message = <<-MESSAGE - There are 2 vagrant boxes: - - linux - - OS: Fedora 32 with Gnome Desktop - - The keyring directory is mounted at /keyring - - Get a shell with 'vagrant ssh linux' - - When running go test, you'll need to use the GUI to click "Continue" on the prompts - - After provisioning, adjusting the virtualbox GUI window size doesn't cause the resolution to update. A 'vagrant reload linux' solves the problem - - windows - - OS: Windows 10 - - The keyring directory is mounted at C:\keyring - - Get a shell by starting PowerShell in the GUI - - You can run commands remotely using 'vagrant winrm -e windows CMD'. You'll need the -e (elevated privileges) if you want to interact with wincred - - Automated scripts for running go test on vagrant boxes (run these locally): - - ./bin/go-test-linux - Run tests on Linux - - ./bin/go-test-windows - Run tests on Windows - - ./bin/go-test - Run all tests - locally, linux and windows - MESSAGE -end diff --git a/vendor/github.com/99designs/keyring/array.go b/vendor/github.com/99designs/keyring/array.go deleted file mode 100644 index 3179cb5..0000000 --- a/vendor/github.com/99designs/keyring/array.go +++ /dev/null @@ -1,54 +0,0 @@ -package keyring - -// ArrayKeyring is a mock/non-secure backend that meets the Keyring interface. -// It is intended to be used to aid unit testing of code that relies on the package. -// NOTE: Do not use in production code. -type ArrayKeyring struct { - items map[string]Item -} - -// NewArrayKeyring returns an ArrayKeyring, optionally constructed with an initial slice -// of items. -func NewArrayKeyring(initial []Item) *ArrayKeyring { - kr := &ArrayKeyring{} - for _, i := range initial { - _ = kr.Set(i) - } - return kr -} - -// Get returns an Item matching Key. -func (k *ArrayKeyring) Get(key string) (Item, error) { - if i, ok := k.items[key]; ok { - return i, nil - } - return Item{}, ErrKeyNotFound -} - -// Set will store an item on the mock Keyring. -func (k *ArrayKeyring) Set(i Item) error { - if k.items == nil { - k.items = map[string]Item{} - } - k.items[i.Key] = i - return nil -} - -// Remove will delete an Item from the Keyring. -func (k *ArrayKeyring) Remove(key string) error { - delete(k.items, key) - return nil -} - -// Keys provides a slice of all Item keys on the Keyring. -func (k *ArrayKeyring) Keys() ([]string, error) { - var keys = []string{} - for key := range k.items { - keys = append(keys, key) - } - return keys, nil -} - -func (k *ArrayKeyring) GetMetadata(_ string) (Metadata, error) { - return Metadata{}, ErrMetadataNeedsCredentials -} diff --git a/vendor/github.com/99designs/keyring/config.go b/vendor/github.com/99designs/keyring/config.go deleted file mode 100644 index 590af7c..0000000 --- a/vendor/github.com/99designs/keyring/config.go +++ /dev/null @@ -1,58 +0,0 @@ -package keyring - -// Config contains configuration for keyring. -type Config struct { - // AllowedBackends is a whitelist of backend providers that can be used. Nil means all available. - AllowedBackends []BackendType - - // ServiceName is a generic service name that is used by backends that support the concept - ServiceName string - - // MacOSKeychainNameKeychainName is the name of the macOS keychain that is used - KeychainName string - - // KeychainTrustApplication is whether the calling application should be trusted by default by items - KeychainTrustApplication bool - - // KeychainSynchronizable is whether the item can be synchronized to iCloud - KeychainSynchronizable bool - - // KeychainAccessibleWhenUnlocked is whether the item is accessible when the device is locked - KeychainAccessibleWhenUnlocked bool - - // KeychainPasswordFunc is an optional function used to prompt the user for a password - KeychainPasswordFunc PromptFunc - - // FilePasswordFunc is a required function used to prompt the user for a password - FilePasswordFunc PromptFunc - - // FileDir is the directory that keyring files are stored in, ~/ is resolved to the users' home dir - FileDir string - - // KeyCtlScope is the scope of the kernel keyring (either "user", "session", "process" or "thread") - KeyCtlScope string - - // KeyCtlPerm is the permission mask to use for new keys - KeyCtlPerm uint32 - - // KWalletAppID is the application id for KWallet - KWalletAppID string - - // KWalletFolder is the folder for KWallet - KWalletFolder string - - // LibSecretCollectionName is the name collection in secret-service - LibSecretCollectionName string - - // PassDir is the pass password-store directory, ~/ is resolved to the users' home dir - PassDir string - - // PassCmd is the name of the pass executable - PassCmd string - - // PassPrefix is a string prefix to prepend to the item path stored in pass - PassPrefix string - - // WinCredPrefix is a string prefix to prepend to the key name - WinCredPrefix string -} diff --git a/vendor/github.com/99designs/keyring/docker-compose.yml b/vendor/github.com/99designs/keyring/docker-compose.yml deleted file mode 100644 index 9020220..0000000 --- a/vendor/github.com/99designs/keyring/docker-compose.yml +++ /dev/null @@ -1,7 +0,0 @@ -version: "3.9" -services: - keyring: - image: golang:1.19 - volumes: - - .:/usr/local/src/keyring - working_dir: /usr/local/src/keyring diff --git a/vendor/github.com/99designs/keyring/file.go b/vendor/github.com/99designs/keyring/file.go deleted file mode 100644 index 0d25b57..0000000 --- a/vendor/github.com/99designs/keyring/file.go +++ /dev/null @@ -1,180 +0,0 @@ -package keyring - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" - "time" - - jose "github.com/dvsekhvalnov/jose2go" - "github.com/mtibben/percent" -) - -func init() { - supportedBackends[FileBackend] = opener(func(cfg Config) (Keyring, error) { - return &fileKeyring{ - dir: cfg.FileDir, - passwordFunc: cfg.FilePasswordFunc, - }, nil - }) -} - -var filenameEscape = func(s string) string { - return percent.Encode(s, "/") -} -var filenameUnescape = percent.Decode - -type fileKeyring struct { - dir string - passwordFunc PromptFunc - password string -} - -func (k *fileKeyring) resolveDir() (string, error) { - if k.dir == "" { - return "", fmt.Errorf("No directory provided for file keyring") - } - - dir, err := ExpandTilde(k.dir) - if err != nil { - return "", err - } - - stat, err := os.Stat(dir) - if os.IsNotExist(err) { - err = os.MkdirAll(dir, 0700) - } else if err != nil && stat != nil && !stat.IsDir() { - err = fmt.Errorf("%s is a file, not a directory", dir) - } - - return dir, err -} - -func (k *fileKeyring) unlock() error { - dir, err := k.resolveDir() - if err != nil { - return err - } - - if k.password == "" { - pwd, err := k.passwordFunc(fmt.Sprintf("Enter passphrase to unlock %q", dir)) - if err != nil { - return err - } - k.password = pwd - } - - return nil -} - -func (k *fileKeyring) Get(key string) (Item, error) { - filename, err := k.filename(key) - if err != nil { - return Item{}, err - } - - bytes, err := os.ReadFile(filename) - if os.IsNotExist(err) { - return Item{}, ErrKeyNotFound - } else if err != nil { - return Item{}, err - } - - if err = k.unlock(); err != nil { - return Item{}, err - } - - payload, _, err := jose.Decode(string(bytes), k.password) - if err != nil { - return Item{}, err - } - - var decoded Item - err = json.Unmarshal([]byte(payload), &decoded) - - return decoded, err -} - -func (k *fileKeyring) GetMetadata(key string) (Metadata, error) { - filename, err := k.filename(key) - if err != nil { - return Metadata{}, err - } - - stat, err := os.Stat(filename) - if os.IsNotExist(err) { - return Metadata{}, ErrKeyNotFound - } else if err != nil { - return Metadata{}, err - } - - // For the File provider, all internal data is encrypted, not just the - // credentials. Thus we only have the timestamps. Return a nil *Item. - // - // If we want to change this ... how portable are extended file attributes - // these days? Would it break user expectations of the security model to - // leak data into those? I'm hesitant to do so. - - return Metadata{ - ModificationTime: stat.ModTime(), - }, nil -} - -func (k *fileKeyring) Set(i Item) error { - bytes, err := json.Marshal(i) - if err != nil { - return err - } - - if err = k.unlock(); err != nil { - return err - } - - token, err := jose.Encrypt(string(bytes), jose.PBES2_HS256_A128KW, jose.A256GCM, k.password, - jose.Headers(map[string]interface{}{ - "created": time.Now().String(), - })) - if err != nil { - return err - } - - filename, err := k.filename(i.Key) - if err != nil { - return err - } - return os.WriteFile(filename, []byte(token), 0600) -} - -func (k *fileKeyring) filename(key string) (string, error) { - dir, err := k.resolveDir() - if err != nil { - return "", err - } - - return filepath.Join(dir, filenameEscape(key)), nil -} - -func (k *fileKeyring) Remove(key string) error { - filename, err := k.filename(key) - if err != nil { - return err - } - - return os.Remove(filename) -} - -func (k *fileKeyring) Keys() ([]string, error) { - dir, err := k.resolveDir() - if err != nil { - return nil, err - } - - var keys = []string{} - files, _ := os.ReadDir(dir) - for _, f := range files { - keys = append(keys, filenameUnescape(f.Name())) - } - - return keys, nil -} diff --git a/vendor/github.com/99designs/keyring/keychain.go b/vendor/github.com/99designs/keyring/keychain.go deleted file mode 100644 index d4e634e..0000000 --- a/vendor/github.com/99designs/keyring/keychain.go +++ /dev/null @@ -1,301 +0,0 @@ -//go:build darwin && cgo -// +build darwin,cgo - -package keyring - -import ( - "errors" - "fmt" - - gokeychain "github.com/99designs/go-keychain" -) - -type keychain struct { - path string - service string - - passwordFunc PromptFunc - - isSynchronizable bool - isAccessibleWhenUnlocked bool - isTrusted bool -} - -func init() { - supportedBackends[KeychainBackend] = opener(func(cfg Config) (Keyring, error) { - kc := &keychain{ - service: cfg.ServiceName, - passwordFunc: cfg.KeychainPasswordFunc, - - // Set the isAccessibleWhenUnlocked to the boolean value of - // KeychainAccessibleWhenUnlocked is a shorthand for setting the accessibility value. - // See: https://developer.apple.com/documentation/security/ksecattraccessiblewhenunlocked - isAccessibleWhenUnlocked: cfg.KeychainAccessibleWhenUnlocked, - } - if cfg.KeychainName != "" { - kc.path = cfg.KeychainName + ".keychain" - } - if cfg.KeychainTrustApplication { - kc.isTrusted = true - } - return kc, nil - }) -} - -func (k *keychain) Get(key string) (Item, error) { - query := gokeychain.NewItem() - query.SetSecClass(gokeychain.SecClassGenericPassword) - query.SetService(k.service) - query.SetAccount(key) - query.SetMatchLimit(gokeychain.MatchLimitOne) - query.SetReturnAttributes(true) - query.SetReturnData(true) - - if k.path != "" { - // When we are querying, we don't create by default - query.SetMatchSearchList(gokeychain.NewWithPath(k.path)) - } - - debugf("Querying keychain for service=%q, account=%q, keychain=%q", k.service, key, k.path) - results, err := gokeychain.QueryItem(query) - if err == gokeychain.ErrorItemNotFound || len(results) == 0 { - debugf("No results found") - return Item{}, ErrKeyNotFound - } - - if err != nil { - debugf("Error: %#v", err) - return Item{}, err - } - - item := Item{ - Key: key, - Data: results[0].Data, - Label: results[0].Label, - Description: results[0].Description, - } - - debugf("Found item %q", results[0].Label) - return item, nil -} - -func (k *keychain) GetMetadata(key string) (Metadata, error) { - query := gokeychain.NewItem() - query.SetSecClass(gokeychain.SecClassGenericPassword) - query.SetService(k.service) - query.SetAccount(key) - query.SetMatchLimit(gokeychain.MatchLimitOne) - query.SetReturnAttributes(true) - query.SetReturnData(false) - query.SetReturnRef(true) - - debugf("Querying keychain for metadata of service=%q, account=%q, keychain=%q", k.service, key, k.path) - results, err := gokeychain.QueryItem(query) - if err == gokeychain.ErrorItemNotFound || len(results) == 0 { - debugf("No results found") - return Metadata{}, ErrKeyNotFound - } else if err != nil { - debugf("Error: %#v", err) - return Metadata{}, err - } - - md := Metadata{ - Item: &Item{ - Key: key, - Label: results[0].Label, - Description: results[0].Description, - }, - ModificationTime: results[0].ModificationDate, - } - - debugf("Found metadata for %q", md.Item.Label) - - return md, nil -} - -func (k *keychain) updateItem(kc gokeychain.Keychain, kcItem gokeychain.Item, account string) error { - queryItem := gokeychain.NewItem() - queryItem.SetSecClass(gokeychain.SecClassGenericPassword) - queryItem.SetService(k.service) - queryItem.SetAccount(account) - queryItem.SetMatchLimit(gokeychain.MatchLimitOne) - queryItem.SetReturnAttributes(true) - - if k.path != "" { - queryItem.SetMatchSearchList(kc) - } - - results, err := gokeychain.QueryItem(queryItem) - if err != nil { - return fmt.Errorf("Failed to query keychain: %v", err) - } - if len(results) == 0 { - return errors.New("no results") - } - - // Don't call SetAccess() as this will cause multiple prompts on update, even when we are not updating the AccessList - kcItem.SetAccess(nil) - - if err := gokeychain.UpdateItem(queryItem, kcItem); err != nil { - return fmt.Errorf("Failed to update item in keychain: %v", err) - } - - return nil -} - -func (k *keychain) Set(item Item) error { - var kc gokeychain.Keychain - - // when we are setting a value, we create or open - if k.path != "" { - var err error - kc, err = k.createOrOpen() - if err != nil { - return err - } - } - - kcItem := gokeychain.NewItem() - kcItem.SetSecClass(gokeychain.SecClassGenericPassword) - kcItem.SetService(k.service) - kcItem.SetAccount(item.Key) - kcItem.SetLabel(item.Label) - kcItem.SetDescription(item.Description) - kcItem.SetData(item.Data) - - if k.path != "" { - kcItem.UseKeychain(kc) - } - - if k.isSynchronizable && !item.KeychainNotSynchronizable { - kcItem.SetSynchronizable(gokeychain.SynchronizableYes) - } - - if k.isAccessibleWhenUnlocked { - kcItem.SetAccessible(gokeychain.AccessibleWhenUnlocked) - } - - isTrusted := k.isTrusted && !item.KeychainNotTrustApplication - - if isTrusted { - debugf("Keychain item trusts keyring") - kcItem.SetAccess(&gokeychain.Access{ - Label: item.Label, - TrustedApplications: nil, - }) - } else { - debugf("Keychain item doesn't trust keyring") - kcItem.SetAccess(&gokeychain.Access{ - Label: item.Label, - TrustedApplications: []string{}, - }) - } - - debugf("Adding service=%q, label=%q, account=%q, trusted=%v to osx keychain %q", k.service, item.Label, item.Key, isTrusted, k.path) - - err := gokeychain.AddItem(kcItem) - - if err == gokeychain.ErrorDuplicateItem { - debugf("Item already exists, updating") - err = k.updateItem(kc, kcItem, item.Key) - } - - if err != nil { - return err - } - - return nil -} - -func (k *keychain) Remove(key string) error { - item := gokeychain.NewItem() - item.SetSecClass(gokeychain.SecClassGenericPassword) - item.SetService(k.service) - item.SetAccount(key) - - if k.path != "" { - kc := gokeychain.NewWithPath(k.path) - - if err := kc.Status(); err != nil { - if err == gokeychain.ErrorNoSuchKeychain { - return ErrKeyNotFound - } - return err - } - - item.SetMatchSearchList(kc) - } - - debugf("Removing keychain item service=%q, account=%q, keychain %q", k.service, key, k.path) - err := gokeychain.DeleteItem(item) - if err == gokeychain.ErrorItemNotFound { - return ErrKeyNotFound - } - - return err -} - -func (k *keychain) Keys() ([]string, error) { - query := gokeychain.NewItem() - query.SetSecClass(gokeychain.SecClassGenericPassword) - query.SetService(k.service) - query.SetMatchLimit(gokeychain.MatchLimitAll) - query.SetReturnAttributes(true) - - if k.path != "" { - kc := gokeychain.NewWithPath(k.path) - - if err := kc.Status(); err != nil { - if err == gokeychain.ErrorNoSuchKeychain { - return []string{}, nil - } - return nil, err - } - - query.SetMatchSearchList(kc) - } - - debugf("Querying keychain for service=%q, keychain=%q", k.service, k.path) - results, err := gokeychain.QueryItem(query) - if err != nil { - return nil, err - } - - debugf("Found %d results", len(results)) - accountNames := make([]string, len(results)) - for idx, r := range results { - accountNames[idx] = r.Account - } - - return accountNames, nil -} - -func (k *keychain) createOrOpen() (gokeychain.Keychain, error) { - kc := gokeychain.NewWithPath(k.path) - - debugf("Checking keychain status") - err := kc.Status() - if err == nil { - debugf("Keychain status returned nil, keychain exists") - return kc, nil - } - - debugf("Keychain status returned error: %v", err) - - if err != gokeychain.ErrorNoSuchKeychain { - return gokeychain.Keychain{}, err - } - - if k.passwordFunc == nil { - debugf("Creating keychain %s with prompt", k.path) - return gokeychain.NewKeychainWithPrompt(k.path) - } - - passphrase, err := k.passwordFunc("Enter passphrase for keychain") - if err != nil { - return gokeychain.Keychain{}, err - } - - debugf("Creating keychain %s with provided password", k.path) - return gokeychain.NewKeychain(k.path, passphrase) -} diff --git a/vendor/github.com/99designs/keyring/keyctl.go b/vendor/github.com/99designs/keyring/keyctl.go deleted file mode 100644 index bd8018a..0000000 --- a/vendor/github.com/99designs/keyring/keyctl.go +++ /dev/null @@ -1,327 +0,0 @@ -//go:build linux -// +build linux - -package keyring - -import ( - "errors" - "fmt" - "strings" - "syscall" - "unsafe" - - "golang.org/x/sys/unix" -) - -//nolint:revive -const ( - KEYCTL_PERM_VIEW = uint32(1 << 0) - KEYCTL_PERM_READ = uint32(1 << 1) - KEYCTL_PERM_WRITE = uint32(1 << 2) - KEYCTL_PERM_SEARCH = uint32(1 << 3) - KEYCTL_PERM_LINK = uint32(1 << 4) - KEYCTL_PERM_SETATTR = uint32(1 << 5) - KEYCTL_PERM_ALL = uint32((1 << 6) - 1) - - KEYCTL_PERM_OTHERS = 0 - KEYCTL_PERM_GROUP = 8 - KEYCTL_PERM_USER = 16 - KEYCTL_PERM_PROCESS = 24 -) - -// GetPermissions constructs the permission mask from the elements. -func GetPermissions(process, user, group, others uint32) uint32 { - perm := others << KEYCTL_PERM_OTHERS - perm |= group << KEYCTL_PERM_GROUP - perm |= user << KEYCTL_PERM_USER - perm |= process << KEYCTL_PERM_PROCESS - - return perm -} - -// GetKeyringIDForScope get the keyring ID for a given scope. -func GetKeyringIDForScope(scope string) (int32, error) { - ringRef, err := getKeyringForScope(scope) - if err != nil { - return 0, err - } - id, err := unix.KeyctlGetKeyringID(int(ringRef), false) - return int32(id), err -} - -type keyctlKeyring struct { - keyring int32 - perm uint32 -} - -func init() { - supportedBackends[KeyCtlBackend] = opener(func(cfg Config) (Keyring, error) { - keyring := keyctlKeyring{} - if cfg.KeyCtlPerm > 0 { - keyring.perm = cfg.KeyCtlPerm - } - - parent, err := getKeyringForScope(cfg.KeyCtlScope) - if err != nil { - return nil, fmt.Errorf("accessing %q keyring failed: %v", cfg.KeyCtlScope, err) - } - - // Check for named keyrings - keyring.keyring = parent - if cfg.ServiceName != "" { - namedKeyring, err := keyctlSearch(parent, "keyring", cfg.ServiceName) - if err != nil { - if !errors.Is(err, syscall.ENOKEY) { - return nil, fmt.Errorf("opening named %q keyring failed: %v", cfg.KeyCtlScope, err) - } - - // Keyring does not yet exist, create it - namedKeyring, err = keyring.createNamedKeyring(parent, cfg.ServiceName) - if err != nil { - return nil, fmt.Errorf("creating named %q keyring failed: %v", cfg.KeyCtlScope, err) - } - } - keyring.keyring = namedKeyring - } - - return &keyring, nil - }) -} - -func (k *keyctlKeyring) Get(name string) (Item, error) { - key, err := keyctlSearch(k.keyring, "user", name) - if err != nil { - if errors.Is(err, syscall.ENOKEY) { - return Item{}, ErrKeyNotFound - } - return Item{}, err - } - // data, err := key.Get() - data, err := keyctlRead(key) - if err != nil { - return Item{}, err - } - - item := Item{ - Key: name, - Data: data, - } - - return item, nil -} - -// GetMetadata for pass returns an error indicating that it's unsupported for this backend. -// TODO: We can deliver metadata different from the defined ones (e.g. permissions, expire-time, etc). -func (k *keyctlKeyring) GetMetadata(_ string) (Metadata, error) { - return Metadata{}, ErrMetadataNotSupported -} - -func (k *keyctlKeyring) Set(item Item) error { - if k.perm == 0 { - // Keep the default permissions (alswrv-----v------------) - _, err := keyctlAdd(k.keyring, "user", item.Key, item.Data) - return err - } - - // By default we loose possession of the key in anything above the session keyring. - // Together with the default permissions (which cannot be changed during creation) we - // cannot change the permissions without possessing the key. Therefore, create the - // key in the session keyring, change permissions and then link to the target - // keyring and unlink from the intermediate keyring again. - key, err := keyctlAdd(unix.KEY_SPEC_SESSION_KEYRING, "user", item.Key, item.Data) - if err != nil { - return fmt.Errorf("adding key to session failed: %v", err) - } - - if err := keyctlSetperm(key, k.perm); err != nil { - return fmt.Errorf("setting permission 0x%x failed: %v", k.perm, err) - } - - if err := keyctlLink(k.keyring, key); err != nil { - return fmt.Errorf("linking key to keyring failed: %v", err) - } - - if err := keyctlUnlink(unix.KEY_SPEC_SESSION_KEYRING, key); err != nil { - return fmt.Errorf("unlinking key from session failed: %v", err) - } - - return nil -} - -func (k *keyctlKeyring) Remove(name string) error { - key, err := keyctlSearch(k.keyring, "user", name) - if err != nil { - return ErrKeyNotFound - } - - return keyctlUnlink(k.keyring, key) -} - -func (k *keyctlKeyring) Keys() ([]string, error) { - results := []string{} - - data, err := keyctlRead(k.keyring) - if err != nil { - return nil, fmt.Errorf("reading keyring failed: %v", err) - } - ids, err := keyctlConvertKeyBuffer(data) - if err != nil { - return nil, fmt.Errorf("converting raw keylist failed: %v", err) - } - - for _, id := range ids { - info, err := keyctlDescribe(id) - if err != nil { - return nil, err - } - if info["type"] == "user" { - results = append(results, info["description"]) - } - } - - return results, nil -} - -func (k *keyctlKeyring) createNamedKeyring(parent int32, name string) (int32, error) { - if k.perm == 0 { - // Keep the default permissions (alswrv-----v------------) - return keyctlAdd(parent, "keyring", name, nil) - } - - // By default we loose possession of the keyring in anything above the session keyring. - // Together with the default permissions (which cannot be changed during creation) we - // cannot change the permissions without possessing the keyring. Therefore, create the - // keyring linked to the session keyring, change permissions and then link to the target - // keyring and unlink from the intermediate keyring again. - keyring, err := keyctlAdd(unix.KEY_SPEC_SESSION_KEYRING, "keyring", name, nil) - if err != nil { - return 0, fmt.Errorf("creating keyring failed: %v", err) - } - - if err := keyctlSetperm(keyring, k.perm); err != nil { - return 0, fmt.Errorf("setting permission 0x%x failed: %v", k.perm, err) - } - - if err := keyctlLink(k.keyring, keyring); err != nil { - return 0, fmt.Errorf("linking keyring failed: %v", err) - } - - if err := keyctlUnlink(unix.KEY_SPEC_SESSION_KEYRING, keyring); err != nil { - return 0, fmt.Errorf("unlinking keyring from session failed: %v", err) - } - - return keyring, nil -} - -func getKeyringForScope(scope string) (int32, error) { - switch scope { - case "user": - return int32(unix.KEY_SPEC_USER_KEYRING), nil - case "usersession": - return int32(unix.KEY_SPEC_USER_SESSION_KEYRING), nil - case "group": - // Not yet implemented in the kernel - // return int32(unix.KEY_SPEC_GROUP_KEYRING) - return 0, fmt.Errorf("scope %q not yet implemented", scope) - case "session": - return int32(unix.KEY_SPEC_SESSION_KEYRING), nil - case "process": - return int32(unix.KEY_SPEC_PROCESS_KEYRING), nil - case "thread": - return int32(unix.KEY_SPEC_THREAD_KEYRING), nil - } - return 0, fmt.Errorf("unknown scope %q", scope) -} - -func keyctlAdd(parent int32, keytype, key string, data []byte) (int32, error) { - id, err := unix.AddKey(keytype, key, data, int(parent)) - if err != nil { - return 0, err - } - return int32(id), nil -} - -func keyctlSearch(id int32, idtype, name string) (int32, error) { - key, err := unix.KeyctlSearch(int(id), idtype, name, 0) - if err != nil { - return 0, err - } - return int32(key), nil -} - -func keyctlRead(id int32) ([]byte, error) { - var buffer []byte - - for { - length, err := unix.KeyctlBuffer(unix.KEYCTL_READ, int(id), buffer, 0) - if err != nil { - return nil, err - } - - // Return the buffer if it was large enough - if length <= len(buffer) { - return buffer[:length], nil - } - - // Next try with a larger buffer - buffer = make([]byte, length) - } -} - -func keyctlDescribe(id int32) (map[string]string, error) { - description, err := unix.KeyctlString(unix.KEYCTL_DESCRIBE, int(id)) - if err != nil { - return nil, err - } - fields := strings.Split(description, ";") - if len(fields) < 1 { - return nil, fmt.Errorf("no data") - } - - data := make(map[string]string) - names := []string{"type", "uid", "gid", "perm"} // according to keyctlDescribe(3) new fields are added at the end - data["description"] = fields[len(fields)-1] // according to keyctlDescribe(3) description is always last - for i, f := range fields[:len(fields)-1] { - if i >= len(names) { - // Do not stumble upon unknown fields - break - } - data[names[i]] = f - } - - return data, nil -} - -func keyctlLink(parent, child int32) error { - _, _, errno := syscall.Syscall(syscall.SYS_KEYCTL, uintptr(unix.KEYCTL_LINK), uintptr(child), uintptr(parent)) - if errno != 0 { - return errno - } - return nil -} - -func keyctlUnlink(parent, child int32) error { - _, _, errno := syscall.Syscall(syscall.SYS_KEYCTL, uintptr(unix.KEYCTL_UNLINK), uintptr(child), uintptr(parent)) - if errno != 0 { - return errno - } - return nil -} - -func keyctlSetperm(id int32, perm uint32) error { - return unix.KeyctlSetperm(int(id), perm) -} - -func keyctlConvertKeyBuffer(buffer []byte) ([]int32, error) { - if len(buffer)%4 != 0 { - return nil, fmt.Errorf("buffer size %d not a multiple of 4", len(buffer)) - } - - results := make([]int32, 0, len(buffer)/4) - for i := 0; i < len(buffer); i += 4 { - // We need to case in host-native endianess here as this is what we get from the kernel. - r := *((*int32)(unsafe.Pointer(&buffer[i]))) - results = append(results, r) - } - return results, nil -} diff --git a/vendor/github.com/99designs/keyring/keyring.go b/vendor/github.com/99designs/keyring/keyring.go deleted file mode 100644 index 12161b7..0000000 --- a/vendor/github.com/99designs/keyring/keyring.go +++ /dev/null @@ -1,134 +0,0 @@ -// Package keyring provides a uniform API over a range of desktop credential storage engines. -package keyring - -import ( - "errors" - "log" - "time" -) - -// BackendType is an identifier for a credential storage service. -type BackendType string - -// All currently supported secure storage backends. -const ( - InvalidBackend BackendType = "" - SecretServiceBackend BackendType = "secret-service" - KeychainBackend BackendType = "keychain" - KeyCtlBackend BackendType = "keyctl" - KWalletBackend BackendType = "kwallet" - WinCredBackend BackendType = "wincred" - FileBackend BackendType = "file" - PassBackend BackendType = "pass" -) - -// This order makes sure the OS-specific backends -// are picked over the more generic backends. -var backendOrder = []BackendType{ - // Windows - WinCredBackend, - // MacOS - KeychainBackend, - // Linux - SecretServiceBackend, - KWalletBackend, - KeyCtlBackend, - // General - PassBackend, - FileBackend, -} - -var supportedBackends = map[BackendType]opener{} - -// AvailableBackends provides a slice of all available backend keys on the current OS. -func AvailableBackends() []BackendType { - b := []BackendType{} - for _, k := range backendOrder { - _, ok := supportedBackends[k] - if ok { - b = append(b, k) - } - } - return b -} - -type opener func(cfg Config) (Keyring, error) - -// Open will open a specific keyring backend. -func Open(cfg Config) (Keyring, error) { - if cfg.AllowedBackends == nil { - cfg.AllowedBackends = AvailableBackends() - } - debugf("Considering backends: %v", cfg.AllowedBackends) - for _, backend := range cfg.AllowedBackends { - if opener, ok := supportedBackends[backend]; ok { - openBackend, err := opener(cfg) - if err != nil { - debugf("Failed backend %s: %s", backend, err) - continue - } - return openBackend, nil - } - } - return nil, ErrNoAvailImpl -} - -// Item is a thing stored on the keyring. -type Item struct { - Key string - Data []byte - Label string - Description string - - // Backend specific config - KeychainNotTrustApplication bool - KeychainNotSynchronizable bool -} - -// Metadata is information about a thing stored on the keyring; retrieving -// metadata must not require authentication. The embedded Item should be -// filled in with an empty Data field. -// It's allowed for Item to be a nil pointer, indicating that all we -// have is the timestamps. -type Metadata struct { - *Item - ModificationTime time.Time -} - -// Keyring provides the uniform interface over the underlying backends. -type Keyring interface { - // Returns an Item matching the key or ErrKeyNotFound - Get(key string) (Item, error) - // Returns the non-secret parts of an Item - GetMetadata(key string) (Metadata, error) - // Stores an Item on the keyring - Set(item Item) error - // Removes the item with matching key - Remove(key string) error - // Provides a slice of all keys stored on the keyring - Keys() ([]string, error) -} - -// ErrNoAvailImpl is returned by Open when a backend cannot be found. -var ErrNoAvailImpl = errors.New("Specified keyring backend not available") - -// ErrKeyNotFound is returned by Keyring Get when the item is not on the keyring. -var ErrKeyNotFound = errors.New("The specified item could not be found in the keyring") - -// ErrMetadataNeedsCredentials is returned when Metadata is called against a -// backend which requires credentials even to see metadata. -var ErrMetadataNeedsCredentials = errors.New("The keyring backend requires credentials for metadata access") - -// ErrMetadataNotSupported is returned when Metadata is not available for the backend. -var ErrMetadataNotSupported = errors.New("The keyring backend does not support metadata access") - -var ( - // Debug specifies whether to print debugging output. - Debug bool -) - -func debugf(pattern string, args ...interface{}) { - if Debug { - log.Printf("[keyring] "+pattern, args...) - } -} diff --git a/vendor/github.com/99designs/keyring/kwallet.go b/vendor/github.com/99designs/keyring/kwallet.go deleted file mode 100644 index 771baba..0000000 --- a/vendor/github.com/99designs/keyring/kwallet.go +++ /dev/null @@ -1,237 +0,0 @@ -//go:build linux -// +build linux - -package keyring - -import ( - "encoding/json" - "os" - - "github.com/godbus/dbus" -) - -const ( - dbusServiceName = "org.kde.kwalletd5" - dbusPath = "/modules/kwalletd5" -) - -func init() { - if os.Getenv("DISABLE_KWALLET") == "1" { - return - } - - // silently fail if dbus isn't available - _, err := dbus.SessionBus() - if err != nil { - return - } - - supportedBackends[KWalletBackend] = opener(func(cfg Config) (Keyring, error) { - if cfg.ServiceName == "" { - cfg.ServiceName = "kdewallet" - } - - if cfg.KWalletAppID == "" { - cfg.KWalletAppID = "keyring" - } - - if cfg.KWalletFolder == "" { - cfg.KWalletFolder = "keyring" - } - - wallet, err := newKwallet() - if err != nil { - return nil, err - } - - ring := &kwalletKeyring{ - wallet: *wallet, - name: cfg.ServiceName, - appID: cfg.KWalletAppID, - folder: cfg.KWalletFolder, - } - - return ring, ring.openWallet() - }) -} - -type kwalletKeyring struct { - wallet kwalletBinding - name string - handle int32 - appID string - folder string -} - -func (k *kwalletKeyring) openWallet() error { - isOpen, err := k.wallet.IsOpen(k.handle) - if err != nil { - return err - } - - if !isOpen { - handle, err := k.wallet.Open(k.name, 0, k.appID) - if err != nil { - return err - } - k.handle = handle - } - - return nil -} - -func (k *kwalletKeyring) Get(key string) (Item, error) { - err := k.openWallet() - if err != nil { - return Item{}, err - } - - data, err := k.wallet.ReadEntry(k.handle, k.folder, key, k.appID) - if err != nil { - return Item{}, err - } - if len(data) == 0 { - return Item{}, ErrKeyNotFound - } - - item := Item{} - err = json.Unmarshal(data, &item) - if err != nil { - return Item{}, err - } - - return item, nil -} - -// GetMetadata for kwallet returns an error indicating that it's unsupported -// for this backend. -// -// The only APIs found around KWallet are for retrieving content, no indication -// found in docs for methods to use to retrieve metadata without needing unlock -// credentials. -func (k *kwalletKeyring) GetMetadata(_ string) (Metadata, error) { - return Metadata{}, ErrMetadataNeedsCredentials -} - -func (k *kwalletKeyring) Set(item Item) error { - err := k.openWallet() - if err != nil { - return err - } - - data, err := json.Marshal(item) - if err != nil { - return err - } - - err = k.wallet.WriteEntry(k.handle, k.folder, item.Key, data, k.appID) - if err != nil { - return err - } - - return nil -} - -func (k *kwalletKeyring) Remove(key string) error { - err := k.openWallet() - if err != nil { - return err - } - - err = k.wallet.RemoveEntry(k.handle, k.folder, key, k.appID) - if err != nil { - return err - } - - return nil -} - -func (k *kwalletKeyring) Keys() ([]string, error) { - err := k.openWallet() - if err != nil { - return []string{}, err - } - - entries, err := k.wallet.EntryList(k.handle, k.folder, k.appID) - if err != nil { - return []string{}, err - } - - return entries, nil -} - -func newKwallet() (*kwalletBinding, error) { - conn, err := dbus.SessionBus() - if err != nil { - return nil, err - } - - return &kwalletBinding{ - conn.Object(dbusServiceName, dbusPath), - }, nil -} - -// Dumb Dbus bindings for kwallet bindings with types. -type kwalletBinding struct { - dbus dbus.BusObject -} - -// method bool org.kde.KWallet.isOpen(int handle) -func (k *kwalletBinding) IsOpen(handle int32) (bool, error) { - call := k.dbus.Call("org.kde.KWallet.isOpen", 0, handle) - if call.Err != nil { - return false, call.Err - } - - return call.Body[0].(bool), call.Err -} - -// method int org.kde.KWallet.open(QString wallet, qlonglong wId, QString appid) -func (k *kwalletBinding) Open(name string, wID int64, appid string) (int32, error) { - call := k.dbus.Call("org.kde.KWallet.open", 0, name, wID, appid) - if call.Err != nil { - return 0, call.Err - } - - return call.Body[0].(int32), call.Err -} - -// method QStringList org.kde.KWallet.entryList(int handle, QString folder, QString appid) -func (k *kwalletBinding) EntryList(handle int32, folder string, appid string) ([]string, error) { - call := k.dbus.Call("org.kde.KWallet.entryList", 0, handle, folder, appid) - if call.Err != nil { - return []string{}, call.Err - } - - return call.Body[0].([]string), call.Err -} - -// method int org.kde.KWallet.writeEntry(int handle, QString folder, QString key, QByteArray value, QString appid) -func (k *kwalletBinding) WriteEntry(handle int32, folder string, key string, value []byte, appid string) error { - call := k.dbus.Call("org.kde.KWallet.writeEntry", 0, handle, folder, key, value, appid) - if call.Err != nil { - return call.Err - } - - return call.Err -} - -// method int org.kde.KWallet.removeEntry(int handle, QString folder, QString key, QString appid) -func (k *kwalletBinding) RemoveEntry(handle int32, folder string, key string, appid string) error { - call := k.dbus.Call("org.kde.KWallet.removeEntry", 0, handle, folder, key, appid) - if call.Err != nil { - return call.Err - } - - return call.Err -} - -// method QByteArray org.kde.KWallet.readEntry(int handle, QString folder, QString key, QString appid) -func (k *kwalletBinding) ReadEntry(handle int32, folder string, key string, appid string) ([]byte, error) { - call := k.dbus.Call("org.kde.KWallet.readEntry", 0, handle, folder, key, appid) - if call.Err != nil { - return []byte{}, call.Err - } - - return call.Body[0].([]byte), call.Err -} diff --git a/vendor/github.com/99designs/keyring/pass.go b/vendor/github.com/99designs/keyring/pass.go deleted file mode 100644 index 5ca0bf0..0000000 --- a/vendor/github.com/99designs/keyring/pass.go +++ /dev/null @@ -1,166 +0,0 @@ -//go:build !windows -// +build !windows - -package keyring - -import ( - "encoding/json" - "errors" - "fmt" - "os" - "os/exec" - "path/filepath" - "strings" -) - -func init() { - supportedBackends[PassBackend] = opener(func(cfg Config) (Keyring, error) { - var err error - - pass := &passKeyring{ - passcmd: cfg.PassCmd, - dir: cfg.PassDir, - prefix: cfg.PassPrefix, - } - - if pass.passcmd == "" { - pass.passcmd = "pass" - } - - if pass.dir == "" { - if passDir, found := os.LookupEnv("PASSWORD_STORE_DIR"); found { - pass.dir = passDir - } else { - homeDir, err := os.UserHomeDir() - if err != nil { - return nil, err - } - pass.dir = filepath.Join(homeDir, ".password-store") - } - } - - pass.dir, err = ExpandTilde(pass.dir) - if err != nil { - return nil, err - } - - // fail if the pass program is not available - _, err = exec.LookPath(pass.passcmd) - if err != nil { - return nil, errors.New("The pass program is not available") - } - - return pass, nil - }) -} - -type passKeyring struct { - dir string - passcmd string - prefix string -} - -func (k *passKeyring) pass(args ...string) *exec.Cmd { - cmd := exec.Command(k.passcmd, args...) - if k.dir != "" { - cmd.Env = append(os.Environ(), fmt.Sprintf("PASSWORD_STORE_DIR=%s", k.dir)) - } - cmd.Stderr = os.Stderr - - return cmd -} - -func (k *passKeyring) Get(key string) (Item, error) { - if !k.itemExists(key) { - return Item{}, ErrKeyNotFound - } - - name := filepath.Join(k.prefix, key) - cmd := k.pass("show", name) - output, err := cmd.Output() - if err != nil { - return Item{}, err - } - - var decoded Item - err = json.Unmarshal(output, &decoded) - - return decoded, err -} - -func (k *passKeyring) GetMetadata(key string) (Metadata, error) { - return Metadata{}, nil -} - -func (k *passKeyring) Set(i Item) error { - bytes, err := json.Marshal(i) - if err != nil { - return err - } - - name := filepath.Join(k.prefix, i.Key) - cmd := k.pass("insert", "-m", "-f", name) - cmd.Stdin = strings.NewReader(string(bytes)) - - err = cmd.Run() - if err != nil { - return err - } - - return nil -} - -func (k *passKeyring) Remove(key string) error { - if !k.itemExists(key) { - return ErrKeyNotFound - } - - name := filepath.Join(k.prefix, key) - cmd := k.pass("rm", "-f", name) - err := cmd.Run() - if err != nil { - return err - } - - return nil -} - -func (k *passKeyring) itemExists(key string) bool { - var path = filepath.Join(k.dir, k.prefix, key+".gpg") - _, err := os.Stat(path) - - return err == nil -} - -func (k *passKeyring) Keys() ([]string, error) { - var keys = []string{} - var path = filepath.Join(k.dir, k.prefix) - - info, err := os.Stat(path) - if err != nil { - if os.IsNotExist(err) { - return keys, nil - } - return keys, err - } - if !info.IsDir() { - return keys, fmt.Errorf("%s is not a directory", path) - } - - err = filepath.Walk(path, func(p string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if !info.IsDir() && filepath.Ext(p) == ".gpg" { - name := strings.TrimPrefix(p, path) - if name[0] == os.PathSeparator { - name = name[1:] - } - keys = append(keys, name[:len(name)-4]) - } - return nil - }) - - return keys, err -} diff --git a/vendor/github.com/99designs/keyring/prompt.go b/vendor/github.com/99designs/keyring/prompt.go deleted file mode 100644 index 59ad81c..0000000 --- a/vendor/github.com/99designs/keyring/prompt.go +++ /dev/null @@ -1,27 +0,0 @@ -package keyring - -import ( - "fmt" - "os" - - "golang.org/x/term" -) - -// PromptFunc is a function used to prompt the user for a password. -type PromptFunc func(string) (string, error) - -func TerminalPrompt(prompt string) (string, error) { - fmt.Printf("%s: ", prompt) - b, err := term.ReadPassword(int(os.Stdin.Fd())) - if err != nil { - return "", err - } - fmt.Println() - return string(b), nil -} - -func FixedStringPrompt(value string) PromptFunc { - return func(_ string) (string, error) { - return value, nil - } -} diff --git a/vendor/github.com/99designs/keyring/secretservice.go b/vendor/github.com/99designs/keyring/secretservice.go deleted file mode 100644 index 2a1f9d9..0000000 --- a/vendor/github.com/99designs/keyring/secretservice.go +++ /dev/null @@ -1,293 +0,0 @@ -//go:build linux -// +build linux - -package keyring - -import ( - "encoding/hex" - "encoding/json" - "errors" - - "strings" - - "github.com/godbus/dbus" - "github.com/gsterjov/go-libsecret" -) - -func init() { - // silently fail if dbus isn't available - _, err := dbus.SessionBus() - if err != nil { - return - } - - supportedBackends[SecretServiceBackend] = opener(func(cfg Config) (Keyring, error) { - if cfg.ServiceName == "" { - cfg.ServiceName = "secret-service" - } - if cfg.LibSecretCollectionName == "" { - cfg.LibSecretCollectionName = cfg.ServiceName - } - - service, err := libsecret.NewService() - if err != nil { - return &secretsKeyring{}, err - } - - ring := &secretsKeyring{ - name: cfg.LibSecretCollectionName, - service: service, - } - - return ring, ring.openSecrets() - }) -} - -type secretsKeyring struct { - name string - service *libsecret.Service - collection *libsecret.Collection - session *libsecret.Session -} - -var errCollectionNotFound = errors.New("The collection does not exist. Please add a key first") - -func decodeKeyringString(src string) string { - var dst strings.Builder - for i := 0; i < len(src); i++ { - if src[i] != '_' { - dst.WriteString(string(src[i])) - } else { - if i+3 > len(src) { - return src - } - hexstring := src[i+1 : i+3] - decoded, err := hex.DecodeString(hexstring) - if err != nil { - return src - } - dst.Write(decoded) - i += 2 - } - } - return dst.String() -} - -func (k *secretsKeyring) openSecrets() error { - session, err := k.service.Open() - if err != nil { - return err - } - k.session = session - - // get the collection if it already exists - collections, err := k.service.Collections() - if err != nil { - return err - } - - path := libsecret.DBusPath + "/collection/" + k.name - - for _, collection := range collections { - if decodeKeyringString(string(collection.Path())) == path { - c := collection // fix variable into the local variable to ensure it's referenced correctly, see https://github.com/kyoh86/exportloopref - k.collection = &c - return nil - } - } - - return nil -} - -func (k *secretsKeyring) openCollection() error { - if err := k.openSecrets(); err != nil { - return err - } - - if k.collection == nil { - return errCollectionNotFound - // return &secretsError{fmt.Sprintf( - // "The collection %q does not exist. Please add a key first", - // k.name, - // )} - } - - return nil -} - -func (k *secretsKeyring) Get(key string) (Item, error) { - if err := k.openCollection(); err != nil { - if err == errCollectionNotFound { - return Item{}, ErrKeyNotFound - } - return Item{}, err - } - - items, err := k.collection.SearchItems(key) - if err != nil { - return Item{}, err - } - - if len(items) == 0 { - return Item{}, ErrKeyNotFound - } - - // use the first item whenever there are multiples - // with the same profile name - item := items[0] - - locked, err := item.Locked() - if err != nil { - return Item{}, err - } - - if locked { - if err := k.service.Unlock(item); err != nil { - return Item{}, err - } - } - - secret, err := item.GetSecret(k.session) - if err != nil { - return Item{}, err - } - - // pack the secret into the item - var ret Item - if err = json.Unmarshal(secret.Value, &ret); err != nil { - return Item{}, err - } - - return ret, err -} - -// GetMetadata for libsecret returns an error indicating that it's unsupported -// for this backend. -// -// libsecret actually implements a metadata system which we could use, "Secret -// Attributes"; I found no indication in documentation of anything like an -// automatically maintained last-modification timestamp, so to use this we'd -// need to have a SetMetadata API too. Which we're not yet doing, but feel -// free to contribute patches. -func (k *secretsKeyring) GetMetadata(key string) (Metadata, error) { - return Metadata{}, ErrMetadataNeedsCredentials -} - -func (k *secretsKeyring) Set(item Item) error { - err := k.openSecrets() - if err != nil { - return err - } - - // create the collection if it doesn't already exist - if k.collection == nil { - collection, err := k.service.CreateCollection(k.name) - if err != nil { - return err - } - - k.collection = collection - } - - if err := k.ensureCollectionUnlocked(); err != nil { - return err - } - - // create the new item - data, err := json.Marshal(item) - if err != nil { - return err - } - - secret := libsecret.NewSecret(k.session, []byte{}, data, "application/json") - - if _, err := k.collection.CreateItem(item.Key, secret, true); err != nil { - return err - } - - return nil -} - -func (k *secretsKeyring) Remove(key string) error { - if err := k.openCollection(); err != nil { - if err == errCollectionNotFound { - return ErrKeyNotFound - } - return err - } - - items, err := k.collection.SearchItems(key) - if err != nil { - return err - } - - // nothing to delete - if len(items) == 0 { - return nil - } - - // we dont want to delete more than one anyway - // so just get the first item found - item := items[0] - - locked, err := item.Locked() - if err != nil { - return err - } - - if locked { - if err := k.service.Unlock(item); err != nil { - return err - } - } - - if err := item.Delete(); err != nil { - return err - } - - return nil -} - -func (k *secretsKeyring) Keys() ([]string, error) { - if err := k.openCollection(); err != nil { - if err == errCollectionNotFound { - return []string{}, nil - } - return nil, err - } - if err := k.ensureCollectionUnlocked(); err != nil { - return nil, err - } - items, err := k.collection.Items() - if err != nil { - return nil, err - } - keys := []string{} - for _, item := range items { - label, err := item.Label() // FIXME: err is being silently ignored - if err == nil { - keys = append(keys, label) - } - } - return keys, nil -} - -// deleteCollection deletes the keyring's collection if it exists. This is mainly to support testing. -func (k *secretsKeyring) deleteCollection() error { - if err := k.openCollection(); err != nil { - return err - } - return k.collection.Delete() -} - -// unlock the collection if it's locked -func (k *secretsKeyring) ensureCollectionUnlocked() error { - locked, err := k.collection.Locked() - if err != nil { - return err - } - if !locked { - return nil - } - return k.service.Unlock(k.collection) -} diff --git a/vendor/github.com/99designs/keyring/tilde.go b/vendor/github.com/99designs/keyring/tilde.go deleted file mode 100644 index c1847a6..0000000 --- a/vendor/github.com/99designs/keyring/tilde.go +++ /dev/null @@ -1,22 +0,0 @@ -package keyring - -import ( - "os" - "path/filepath" - "strings" -) - -var tildePrefix = string([]rune{'~', filepath.Separator}) - -// ExpandTilde will expand tilde (~/ or ~\ depending on OS) for the user home directory. -func ExpandTilde(dir string) (string, error) { - if strings.HasPrefix(dir, tildePrefix) { - homeDir, err := os.UserHomeDir() - if err != nil { - return "", err - } - dir = strings.Replace(dir, "~", homeDir, 1) - debugf("Expanded file dir to %s", dir) - } - return dir, nil -} diff --git a/vendor/github.com/99designs/keyring/wincred.go b/vendor/github.com/99designs/keyring/wincred.go deleted file mode 100644 index 2ed43f2..0000000 --- a/vendor/github.com/99designs/keyring/wincred.go +++ /dev/null @@ -1,98 +0,0 @@ -//go:build windows -// +build windows - -package keyring - -import ( - "strings" - "syscall" - - "github.com/danieljoos/wincred" -) - -// ERROR_NOT_FOUND from https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--1000-1299- -const elementNotFoundError = syscall.Errno(1168) - -type windowsKeyring struct { - name string - prefix string -} - -func init() { - supportedBackends[WinCredBackend] = opener(func(cfg Config) (Keyring, error) { - name := cfg.ServiceName - if name == "" { - name = "default" - } - - prefix := cfg.WinCredPrefix - if prefix == "" { - prefix = "keyring" - } - - return &windowsKeyring{ - name: name, - prefix: prefix, - }, nil - }) -} - -func (k *windowsKeyring) Get(key string) (Item, error) { - cred, err := wincred.GetGenericCredential(k.credentialName(key)) - if err != nil { - if err == elementNotFoundError { - return Item{}, ErrKeyNotFound - } - return Item{}, err - } - - item := Item{ - Key: key, - Data: cred.CredentialBlob, - } - - return item, nil -} - -// GetMetadata for pass returns an error indicating that it's unsupported -// for this backend. -// TODO: This is a stub. Look into whether pass would support metadata in a usable way for keyring. -func (k *windowsKeyring) GetMetadata(_ string) (Metadata, error) { - return Metadata{}, ErrMetadataNotSupported -} - -func (k *windowsKeyring) Set(item Item) error { - cred := wincred.NewGenericCredential(k.credentialName(item.Key)) - cred.CredentialBlob = item.Data - return cred.Write() -} - -func (k *windowsKeyring) Remove(key string) error { - cred, err := wincred.GetGenericCredential(k.credentialName(key)) - if err != nil { - if err == elementNotFoundError { - return ErrKeyNotFound - } - return err - } - return cred.Delete() -} - -func (k *windowsKeyring) Keys() ([]string, error) { - results := []string{} - - if creds, err := wincred.List(); err == nil { - for _, cred := range creds { - prefix := k.credentialName("") - if strings.HasPrefix(cred.TargetName, prefix) { - results = append(results, strings.TrimPrefix(cred.TargetName, prefix)) - } - } - } - - return results, nil -} - -func (k *windowsKeyring) credentialName(key string) string { - return k.prefix + ":" + k.name + ":" + key -} diff --git a/vendor/github.com/danieljoos/wincred/.gitattributes b/vendor/github.com/danieljoos/wincred/.gitattributes deleted file mode 100644 index d207b18..0000000 --- a/vendor/github.com/danieljoos/wincred/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.go text eol=lf diff --git a/vendor/github.com/danieljoos/wincred/.gitignore b/vendor/github.com/danieljoos/wincred/.gitignore deleted file mode 100644 index 6142c06..0000000 --- a/vendor/github.com/danieljoos/wincred/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test - -coverage.txt diff --git a/vendor/github.com/danieljoos/wincred/LICENSE b/vendor/github.com/danieljoos/wincred/LICENSE deleted file mode 100644 index 2f436f1..0000000 --- a/vendor/github.com/danieljoos/wincred/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Daniel Joos - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/danieljoos/wincred/README.md b/vendor/github.com/danieljoos/wincred/README.md deleted file mode 100644 index 14f2862..0000000 --- a/vendor/github.com/danieljoos/wincred/README.md +++ /dev/null @@ -1,145 +0,0 @@ -wincred -======= - -Go wrapper around the Windows Credential Manager API functions. - -[![GitHub release](https://img.shields.io/github/release/danieljoos/wincred.svg?style=flat-square)](https://github.com/danieljoos/wincred/releases/latest) -[![Test Status](https://img.shields.io/github/workflow/status/danieljoos/wincred/test?label=test&logo=github&style=flat-square)](https://github.com/danieljoos/wincred/actions?query=workflow%3Atest) -[![Go Report Card](https://goreportcard.com/badge/github.com/danieljoos/wincred)](https://goreportcard.com/report/github.com/danieljoos/wincred) -[![Codecov](https://img.shields.io/codecov/c/github/danieljoos/wincred?logo=codecov&style=flat-square)](https://codecov.io/gh/danieljoos/wincred) -[![PkgGoDev](https://img.shields.io/badge/go.dev-docs-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/danieljoos/wincred) - -Installation ------------- - -```Go -go get github.com/danieljoos/wincred -``` - - -Usage ------ - -See the following examples: - -### Create and store a new generic credential object -```Go -package main - -import ( - "fmt" - "github.com/danieljoos/wincred" -) - -func main() { - cred := wincred.NewGenericCredential("myGoApplication") - cred.CredentialBlob = []byte("my secret") - err := cred.Write() - - if err != nil { - fmt.Println(err) - } -} -``` - -### Retrieve a credential object -```Go -package main - -import ( - "fmt" - "github.com/danieljoos/wincred" -) - -func main() { - cred, err := wincred.GetGenericCredential("myGoApplication") - if err == nil { - fmt.Println(string(cred.CredentialBlob)) - } -} -``` - -### Remove a credential object -```Go -package main - -import ( - "fmt" - "github.com/danieljoos/wincred" -) - -func main() { - cred, err := wincred.GetGenericCredential("myGoApplication") - if err != nil { - fmt.Println(err) - return - } - cred.Delete() -} -``` - -### List all available credentials -```Go -package main - -import ( - "fmt" - "github.com/danieljoos/wincred" -) - -func main() { - creds, err := wincred.List() - if err != nil { - fmt.Println(err) - return - } - for i := range(creds) { - fmt.Println(creds[i].TargetName) - } -} -``` - -Hints ------ - -### Encoding - -The credential objects simply store byte arrays without specific meaning or encoding. -For sharing between different applications, it might make sense to apply an explicit string encoding - for example **UTF-16 LE** (used nearly everywhere in the Win32 API). - -```Go -package main - -import ( - "fmt" - "os" - - "github.com/danieljoos/wincred" - "golang.org/x/text/encoding/unicode" - "golang.org/x/text/transform" -) - -func main() { - cred := wincred.NewGenericCredential("myGoApplication") - - encoder := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder() - blob, _, err := transform.Bytes(encoder, []byte("mysecret")) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - cred.CredentialBlob = blob - err = cred.Write() - - if err != nil { - fmt.Println(err) - os.Exit(1) - } -} - -``` - -### Limitations - -The size of a credential blob is limited to **2560 Bytes** by the Windows API. diff --git a/vendor/github.com/danieljoos/wincred/conversion.go b/vendor/github.com/danieljoos/wincred/conversion.go deleted file mode 100644 index bc04f50..0000000 --- a/vendor/github.com/danieljoos/wincred/conversion.go +++ /dev/null @@ -1,116 +0,0 @@ -// +build windows - -package wincred - -import ( - "encoding/binary" - "reflect" - "time" - "unsafe" - - syscall "golang.org/x/sys/windows" -) - -// utf16ToByte creates a byte array from a given UTF 16 char array. -func utf16ToByte(wstr []uint16) (result []byte) { - result = make([]byte, len(wstr)*2) - for i := range wstr { - binary.LittleEndian.PutUint16(result[(i*2):(i*2)+2], wstr[i]) - } - return -} - -// utf16FromString creates a UTF16 char array from a string. -func utf16FromString(str string) []uint16 { - res, err := syscall.UTF16FromString(str) - if err != nil { - return []uint16{} - } - return res -} - -// goBytes copies the given C byte array to a Go byte array (see `C.GoBytes`). -// This function avoids having cgo as dependency. -func goBytes(src uintptr, len uint32) []byte { - if src == uintptr(0) { - return []byte{} - } - rv := make([]byte, len) - copy(rv, *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ - Data: src, - Len: int(len), - Cap: int(len), - }))) - return rv -} - -// Convert the given CREDENTIAL struct to a more usable structure -func sysToCredential(cred *sysCREDENTIAL) (result *Credential) { - if cred == nil { - return nil - } - result = new(Credential) - result.Comment = syscall.UTF16PtrToString(cred.Comment) - result.TargetName = syscall.UTF16PtrToString(cred.TargetName) - result.TargetAlias = syscall.UTF16PtrToString(cred.TargetAlias) - result.UserName = syscall.UTF16PtrToString(cred.UserName) - result.LastWritten = time.Unix(0, cred.LastWritten.Nanoseconds()) - result.Persist = CredentialPersistence(cred.Persist) - result.CredentialBlob = goBytes(cred.CredentialBlob, cred.CredentialBlobSize) - result.Attributes = make([]CredentialAttribute, cred.AttributeCount) - attrSlice := *(*[]sysCREDENTIAL_ATTRIBUTE)(unsafe.Pointer(&reflect.SliceHeader{ - Data: cred.Attributes, - Len: int(cred.AttributeCount), - Cap: int(cred.AttributeCount), - })) - for i, attr := range attrSlice { - resultAttr := &result.Attributes[i] - resultAttr.Keyword = syscall.UTF16PtrToString(attr.Keyword) - resultAttr.Value = goBytes(attr.Value, attr.ValueSize) - } - return result -} - -// Convert the given Credential object back to a CREDENTIAL struct, which can be used for calling the -// Windows APIs -func sysFromCredential(cred *Credential) (result *sysCREDENTIAL) { - if cred == nil { - return nil - } - result = new(sysCREDENTIAL) - result.Flags = 0 - result.Type = 0 - result.TargetName, _ = syscall.UTF16PtrFromString(cred.TargetName) - result.Comment, _ = syscall.UTF16PtrFromString(cred.Comment) - result.LastWritten = syscall.NsecToFiletime(cred.LastWritten.UnixNano()) - result.CredentialBlobSize = uint32(len(cred.CredentialBlob)) - if len(cred.CredentialBlob) > 0 { - result.CredentialBlob = uintptr(unsafe.Pointer(&cred.CredentialBlob[0])) - } else { - result.CredentialBlob = 0 - } - result.Persist = uint32(cred.Persist) - result.AttributeCount = uint32(len(cred.Attributes)) - attributes := make([]sysCREDENTIAL_ATTRIBUTE, len(cred.Attributes)) - if len(attributes) > 0 { - result.Attributes = uintptr(unsafe.Pointer(&attributes[0])) - } else { - result.Attributes = 0 - } - for i := range cred.Attributes { - inAttr := &cred.Attributes[i] - outAttr := &attributes[i] - outAttr.Keyword, _ = syscall.UTF16PtrFromString(inAttr.Keyword) - outAttr.Flags = 0 - outAttr.ValueSize = uint32(len(inAttr.Value)) - if len(inAttr.Value) > 0 { - outAttr.Value = uintptr(unsafe.Pointer(&inAttr.Value[0])) - } else { - outAttr.Value = 0 - } - } - result.TargetAlias, _ = syscall.UTF16PtrFromString(cred.TargetAlias) - result.UserName, _ = syscall.UTF16PtrFromString(cred.UserName) - - return -} diff --git a/vendor/github.com/danieljoos/wincred/conversion_unsupported.go b/vendor/github.com/danieljoos/wincred/conversion_unsupported.go deleted file mode 100644 index a1ea720..0000000 --- a/vendor/github.com/danieljoos/wincred/conversion_unsupported.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build !windows - -package wincred - -func utf16ToByte(...interface{}) []byte { - return nil -} - -func utf16FromString(...interface{}) []uint16 { - return nil -} diff --git a/vendor/github.com/danieljoos/wincred/sys.go b/vendor/github.com/danieljoos/wincred/sys.go deleted file mode 100644 index 033d3c4..0000000 --- a/vendor/github.com/danieljoos/wincred/sys.go +++ /dev/null @@ -1,143 +0,0 @@ -// +build windows - -package wincred - -import ( - "reflect" - "unsafe" - - syscall "golang.org/x/sys/windows" -) - -var ( - modadvapi32 = syscall.NewLazyDLL("advapi32.dll") - procCredRead proc = modadvapi32.NewProc("CredReadW") - procCredWrite proc = modadvapi32.NewProc("CredWriteW") - procCredDelete proc = modadvapi32.NewProc("CredDeleteW") - procCredFree proc = modadvapi32.NewProc("CredFree") - procCredEnumerate proc = modadvapi32.NewProc("CredEnumerateW") -) - -// Interface for syscall.Proc: helps testing -type proc interface { - Call(a ...uintptr) (r1, r2 uintptr, lastErr error) -} - -// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credentialw -type sysCREDENTIAL struct { - Flags uint32 - Type uint32 - TargetName *uint16 - Comment *uint16 - LastWritten syscall.Filetime - CredentialBlobSize uint32 - CredentialBlob uintptr - Persist uint32 - AttributeCount uint32 - Attributes uintptr - TargetAlias *uint16 - UserName *uint16 -} - -// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credential_attributew -type sysCREDENTIAL_ATTRIBUTE struct { - Keyword *uint16 - Flags uint32 - ValueSize uint32 - Value uintptr -} - -// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credentialw -type sysCRED_TYPE uint32 - -const ( - sysCRED_TYPE_GENERIC sysCRED_TYPE = 0x1 - sysCRED_TYPE_DOMAIN_PASSWORD sysCRED_TYPE = 0x2 - sysCRED_TYPE_DOMAIN_CERTIFICATE sysCRED_TYPE = 0x3 - sysCRED_TYPE_DOMAIN_VISIBLE_PASSWORD sysCRED_TYPE = 0x4 - sysCRED_TYPE_GENERIC_CERTIFICATE sysCRED_TYPE = 0x5 - sysCRED_TYPE_DOMAIN_EXTENDED sysCRED_TYPE = 0x6 - - // https://docs.microsoft.com/en-us/windows/desktop/Debug/system-error-codes - sysERROR_NOT_FOUND = syscall.Errno(1168) - sysERROR_INVALID_PARAMETER = syscall.Errno(87) -) - -// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credreadw -func sysCredRead(targetName string, typ sysCRED_TYPE) (*Credential, error) { - var pcred *sysCREDENTIAL - targetNamePtr, _ := syscall.UTF16PtrFromString(targetName) - ret, _, err := procCredRead.Call( - uintptr(unsafe.Pointer(targetNamePtr)), - uintptr(typ), - 0, - uintptr(unsafe.Pointer(&pcred)), - ) - if ret == 0 { - return nil, err - } - defer procCredFree.Call(uintptr(unsafe.Pointer(pcred))) - - return sysToCredential(pcred), nil -} - -// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credwritew -func sysCredWrite(cred *Credential, typ sysCRED_TYPE) error { - ncred := sysFromCredential(cred) - ncred.Type = uint32(typ) - ret, _, err := procCredWrite.Call( - uintptr(unsafe.Pointer(ncred)), - 0, - ) - if ret == 0 { - return err - } - - return nil -} - -// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-creddeletew -func sysCredDelete(cred *Credential, typ sysCRED_TYPE) error { - targetNamePtr, _ := syscall.UTF16PtrFromString(cred.TargetName) - ret, _, err := procCredDelete.Call( - uintptr(unsafe.Pointer(targetNamePtr)), - uintptr(typ), - 0, - ) - if ret == 0 { - return err - } - - return nil -} - -// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credenumeratew -func sysCredEnumerate(filter string, all bool) ([]*Credential, error) { - var count int - var pcreds uintptr - var filterPtr *uint16 - if !all { - filterPtr, _ = syscall.UTF16PtrFromString(filter) - } - ret, _, err := procCredEnumerate.Call( - uintptr(unsafe.Pointer(filterPtr)), - 0, - uintptr(unsafe.Pointer(&count)), - uintptr(unsafe.Pointer(&pcreds)), - ) - if ret == 0 { - return nil, err - } - defer procCredFree.Call(pcreds) - credsSlice := *(*[]*sysCREDENTIAL)(unsafe.Pointer(&reflect.SliceHeader{ - Data: pcreds, - Len: count, - Cap: count, - })) - creds := make([]*Credential, count, count) - for i, cred := range credsSlice { - creds[i] = sysToCredential(cred) - } - - return creds, nil -} diff --git a/vendor/github.com/danieljoos/wincred/sys_unsupported.go b/vendor/github.com/danieljoos/wincred/sys_unsupported.go deleted file mode 100644 index b47bccf..0000000 --- a/vendor/github.com/danieljoos/wincred/sys_unsupported.go +++ /dev/null @@ -1,36 +0,0 @@ -// +build !windows - -package wincred - -import ( - "errors" - "syscall" -) - -const ( - sysCRED_TYPE_GENERIC = 0 - sysCRED_TYPE_DOMAIN_PASSWORD = 0 - sysCRED_TYPE_DOMAIN_CERTIFICATE = 0 - sysCRED_TYPE_DOMAIN_VISIBLE_PASSWORD = 0 - sysCRED_TYPE_GENERIC_CERTIFICATE = 0 - sysCRED_TYPE_DOMAIN_EXTENDED = 0 - - sysERROR_NOT_FOUND = syscall.Errno(1) - sysERROR_INVALID_PARAMETER = syscall.Errno(1) -) - -func sysCredRead(...interface{}) (*Credential, error) { - return nil, errors.New("Operation not supported") -} - -func sysCredWrite(...interface{}) error { - return errors.New("Operation not supported") -} - -func sysCredDelete(...interface{}) error { - return errors.New("Operation not supported") -} - -func sysCredEnumerate(...interface{}) ([]*Credential, error) { - return nil, errors.New("Operation not supported") -} diff --git a/vendor/github.com/danieljoos/wincred/types.go b/vendor/github.com/danieljoos/wincred/types.go deleted file mode 100644 index 28debc9..0000000 --- a/vendor/github.com/danieljoos/wincred/types.go +++ /dev/null @@ -1,69 +0,0 @@ -package wincred - -import ( - "time" -) - -// CredentialPersistence describes one of three persistence modes of a credential. -// A detailed description of the available modes can be found on -// Docs: https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credentialw -type CredentialPersistence uint32 - -const ( - // PersistSession indicates that the credential only persists for the life - // of the current Windows login session. Such a credential is not visible in - // any other logon session, even from the same user. - PersistSession CredentialPersistence = 0x1 - - // PersistLocalMachine indicates that the credential persists for this and - // all subsequent logon sessions on this local machine/computer. It is - // however not visible for logon sessions of this user on a different - // machine. - PersistLocalMachine CredentialPersistence = 0x2 - - // PersistEnterprise indicates that the credential persists for this and all - // subsequent logon sessions for this user. It is also visible for logon - // sessions on different computers. - PersistEnterprise CredentialPersistence = 0x3 -) - -// CredentialAttribute represents an application-specific attribute of a credential. -type CredentialAttribute struct { - Keyword string - Value []byte -} - -// Credential is the basic credential structure. -// A credential is identified by its target name. -// The actual credential secret is available in the CredentialBlob field. -type Credential struct { - TargetName string - Comment string - LastWritten time.Time - CredentialBlob []byte - Attributes []CredentialAttribute - TargetAlias string - UserName string - Persist CredentialPersistence -} - -// GenericCredential holds a credential for generic usage. -// It is typically defined and used by applications that need to manage user -// secrets. -// -// More information about the available kinds of credentials of the Windows -// Credential Management API can be found on Docs: -// https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/kinds-of-credentials -type GenericCredential struct { - Credential -} - -// DomainPassword holds a domain credential that is typically used by the -// operating system for user logon. -// -// More information about the available kinds of credentials of the Windows -// Credential Management API can be found on Docs: -// https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/kinds-of-credentials -type DomainPassword struct { - Credential -} diff --git a/vendor/github.com/danieljoos/wincred/wincred.go b/vendor/github.com/danieljoos/wincred/wincred.go deleted file mode 100644 index 998de7b..0000000 --- a/vendor/github.com/danieljoos/wincred/wincred.go +++ /dev/null @@ -1,111 +0,0 @@ -// Package wincred provides primitives for accessing the Windows Credentials Management API. -// This includes functions for retrieval, listing and storage of credentials as well as Go structures for convenient access to the credential data. -// -// A more detailed description of Windows Credentials Management can be found on -// Docs: https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/credentials-management -package wincred - -import "errors" - -const ( - // ErrElementNotFound is the error that is returned if a requested element cannot be found. - // This error constant can be used to check if a credential could not be found. - ErrElementNotFound = sysERROR_NOT_FOUND - - // ErrInvalidParameter is the error that is returned for invalid parameters. - // This error constant can be used to check if the given function parameters were invalid. - // For example when trying to create a new generic credential with an empty target name. - ErrInvalidParameter = sysERROR_INVALID_PARAMETER -) - -// GetGenericCredential fetches the generic credential with the given name from Windows credential manager. -// It returns nil and an error if the credential could not be found or an error occurred. -func GetGenericCredential(targetName string) (*GenericCredential, error) { - cred, err := sysCredRead(targetName, sysCRED_TYPE_GENERIC) - if cred != nil { - return &GenericCredential{Credential: *cred}, err - } - return nil, err -} - -// NewGenericCredential creates a new generic credential object with the given name. -// The persist mode of the newly created object is set to a default value that indicates local-machine-wide storage. -// The credential object is NOT yet persisted to the Windows credential vault. -func NewGenericCredential(targetName string) (result *GenericCredential) { - result = new(GenericCredential) - result.TargetName = targetName - result.Persist = PersistLocalMachine - return -} - -// Write persists the generic credential object to Windows credential manager. -func (t *GenericCredential) Write() (err error) { - err = sysCredWrite(&t.Credential, sysCRED_TYPE_GENERIC) - return -} - -// Delete removes the credential object from Windows credential manager. -func (t *GenericCredential) Delete() (err error) { - err = sysCredDelete(&t.Credential, sysCRED_TYPE_GENERIC) - return -} - -// GetDomainPassword fetches the domain-password credential with the given target host name from Windows credential manager. -// It returns nil and an error if the credential could not be found or an error occurred. -func GetDomainPassword(targetName string) (*DomainPassword, error) { - cred, err := sysCredRead(targetName, sysCRED_TYPE_DOMAIN_PASSWORD) - if cred != nil { - return &DomainPassword{Credential: *cred}, err - } - return nil, err -} - -// NewDomainPassword creates a new domain-password credential used for login to the given target host name. -// The persist mode of the newly created object is set to a default value that indicates local-machine-wide storage. -// The credential object is NOT yet persisted to the Windows credential vault. -func NewDomainPassword(targetName string) (result *DomainPassword) { - result = new(DomainPassword) - result.TargetName = targetName - result.Persist = PersistLocalMachine - return -} - -// Write persists the domain-password credential to Windows credential manager. -func (t *DomainPassword) Write() (err error) { - err = sysCredWrite(&t.Credential, sysCRED_TYPE_DOMAIN_PASSWORD) - return -} - -// Delete removes the domain-password credential from Windows credential manager. -func (t *DomainPassword) Delete() (err error) { - err = sysCredDelete(&t.Credential, sysCRED_TYPE_DOMAIN_PASSWORD) - return -} - -// SetPassword sets the CredentialBlob field of a domain password credential to the given string. -func (t *DomainPassword) SetPassword(pw string) { - t.CredentialBlob = utf16ToByte(utf16FromString(pw)) -} - -// List retrieves all credentials of the Credentials store. -func List() ([]*Credential, error) { - creds, err := sysCredEnumerate("", true) - if err != nil && errors.Is(err, ErrElementNotFound) { - // Ignore ERROR_NOT_FOUND and return an empty list instead - creds = []*Credential{} - err = nil - } - return creds, err -} - -// FilteredList retrieves the list of credentials from the Credentials store that match the given filter. -// The filter string defines the prefix followed by an asterisk for the `TargetName` attribute of the credentials. -func FilteredList(filter string) ([]*Credential, error) { - creds, err := sysCredEnumerate(filter, false) - if err != nil && errors.Is(err, ErrElementNotFound) { - // Ignore ERROR_NOT_FOUND and return an empty list instead - creds = []*Credential{} - err = nil - } - return creds, err -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/.gitignore b/vendor/github.com/dvsekhvalnov/jose2go/.gitignore deleted file mode 100644 index 8365624..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test diff --git a/vendor/github.com/dvsekhvalnov/jose2go/LICENSE b/vendor/github.com/dvsekhvalnov/jose2go/LICENSE deleted file mode 100644 index 326fe25..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/dvsekhvalnov/jose2go/README.md b/vendor/github.com/dvsekhvalnov/jose2go/README.md deleted file mode 100644 index 9df801c..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/README.md +++ /dev/null @@ -1,938 +0,0 @@ -# Golang (GO) Javascript Object Signing and Encryption (JOSE) and JSON Web Token (JWT) implementation - -[![GoDoc](https://godoc.org/github.com/dvsekhvalnov/jose2go?status.svg)](http://godoc.org/github.com/dvsekhvalnov/jose2go) - -Pure Golang (GO) library for generating, decoding and encrypting [JSON Web Tokens](https://tools.ietf.org/html/rfc7519). Zero dependency, relies only -on standard library. - -Supports full suite of signing, encryption and compression algorithms defined by [JSON Web Algorithms](https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-31) as of July 4, 2014 version. - -Extensively unit tested and cross tested (100+ tests) for compatibility with [jose.4.j](https://bitbucket.org/b_c/jose4j/wiki/Home), [Nimbus-JOSE-JWT](https://bitbucket.org/nimbusds/nimbus-jose-jwt/wiki/Home), [json-jwt](https://github.com/nov/json-jwt) and -[jose-jwt](https://github.com/dvsekhvalnov/jose-jwt) libraries. - - -## Status -Used in production. GA ready. Current version is 1.5. - -## Important -v1.5 bug fix release - -v1.4 changes default behavior of inserting `typ=JWT` header if not overriden. As of 1.4 no -extra headers added by library automatically. To mimic pre 1.4 behaviour use: -```Go -token, err := jose.Sign(..., jose.Header("typ", "JWT")) - -//or - -token, err := jose.Encrypt(..., jose.Header("typ", "JWT")) -``` - -v1.3 fixed potential Invalid Curve Attack on NIST curves within ECDH key management. -Upgrade strongly recommended. - -v1.2 breaks `jose.Decode` interface by returning 3 values instead of 2. - -v1.2 deprecates `jose.Compress` method in favor of using configuration options to `jose.Encrypt`, -the method will be removed in next release. - -### Migration to v1.2 -Pre v1.2 decoding: - -```Go -payload,err := jose.Decode(token,sharedKey) -``` - -Should be updated to v1.2: - -```Go -payload, headers, err := jose.Decode(token,sharedKey) -``` - -Pre v1.2 compression: - -```Go -token,err := jose.Compress(payload,jose.DIR,jose.A128GCM,jose.DEF, key) -``` - -Should be update to v1.2: - -```Go -token, err := jose.Encrypt(payload, jose.DIR, jose.A128GCM, key, jose.Zip(jose.DEF)) -``` - -## Supported JWA algorithms - -**Signing** -- HMAC signatures with HS256, HS384 and HS512. -- RSASSA-PKCS1-V1_5 signatures with RS256, RS384 and RS512. -- RSASSA-PSS signatures (probabilistic signature scheme with appendix) with PS256, PS384 and PS512. -- ECDSA signatures with ES256, ES384 and ES512. -- NONE (unprotected) plain text algorithm without integrity protection - -**Encryption** -- RSAES OAEP (using SHA-1 and MGF1 with SHA-1) encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM -- RSAES OAEP 256 (using SHA-256 and MGF1 with SHA-256) encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM -- RSAES-PKCS1-V1_5 encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM -- A128KW, A192KW, A256KW encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM -- A128GCMKW, A192GCMKW, A256GCMKW encryption with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM -- ECDH-ES with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM -- ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM -- PBES2-HS256+A128KW, PBES2-HS384+A192KW, PBES2-HS512+A256KW with A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM, A256GCM -- Direct symmetric key encryption with pre-shared key A128CBC-HS256, A192CBC-HS384, A256CBC-HS512, A128GCM, A192GCM and A256GCM - -**Compression** -- DEFLATE compression - -## Installation -### Grab package from github -`go get github.com/dvsekhvalnov/jose2go` or `go get -u github.com/dvsekhvalnov/jose2go` to update to latest version - -### Import package -```Go -import ( - "github.com/dvsekhvalnov/jose2go" -) -``` - -## Usage -#### Creating Plaintext (unprotected) Tokens - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := `{"hello": "world"}` - - token,err := jose.Sign(payload,jose.NONE, nil) - - if(err==nil) { - //go use token - fmt.Printf("\nPlaintext = %v\n",token) - } -} -``` - -### Creating signed tokens -#### HS-256, HS-384 and HS-512 -Signing with HS256, HS384, HS512 expecting `[]byte` array key of corresponding length: - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := `{"hello": "world"}` - - key := []byte{97,48,97,50,97,98,100,56,45,54,49,54,50,45,52,49,99,51,45,56,51,100,54,45,49,99,102,53,53,57,98,52,54,97,102,99} - - token,err := jose.Sign(payload,jose.HS256,key) - - if(err==nil) { - //go use token - fmt.Printf("\nHS256 = %v\n",token) - } -} -``` - -#### RS-256, RS-384 and RS-512, PS-256, PS-384 and PS-512 -Signing with RS256, RS384, RS512, PS256, PS384, PS512 expecting `*rsa.PrivateKey` private key of corresponding length. **jose2go** [provides convenient utils](#dealing-with-keys) to construct `*rsa.PrivateKey` instance from PEM encoded PKCS1 or PKCS8 data: `Rsa.ReadPrivate([]byte)` under `jose2go/keys/rsa` package. - -```Go -package main - -import ( - "fmt" - "io/ioutil" - Rsa "github.com/dvsekhvalnov/jose2go/keys/rsa" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := `{"hello": "world"}` - - keyBytes,err := ioutil.ReadFile("private.key") - - if(err!=nil) { - panic("invalid key file") - } - - privateKey,e:=Rsa.ReadPrivate(keyBytes) - - if(e!=nil) { - panic("invalid key format") - } - - token,err := jose.Sign(payload,jose.RS256, privateKey) - - if(err==nil) { - //go use token - fmt.Printf("\nRS256 = %v\n",token) - } -} -``` - -#### ES-256, ES-384 and ES-512 -ES256, ES384, ES512 ECDSA signatures expecting `*ecdsa.PrivateKey` private elliptic curve key of corresponding length. **jose2go** [provides convenient utils](#dealing-with-keys) to construct `*ecdsa.PrivateKey` instance from PEM encoded PKCS1 or PKCS8 data: `ecc.ReadPrivate([]byte)` or directly from `X,Y,D` parameters: `ecc.NewPrivate(x,y,d []byte)` under `jose2go/keys/ecc` package. - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go/keys/ecc" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := `{"hello":"world"}` - - privateKey:=ecc.NewPrivate([]byte{4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9}, - []byte{131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53}, - []byte{ 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 }) - - token,err := jose.Sign(payload, jose.ES256, privateKey) - - if(err==nil) { - //go use token - fmt.Printf("\ntoken = %v\n",token) - } -} -``` - -### Creating encrypted tokens -#### RSA-OAEP-256, RSA-OAEP and RSA1\_5 key management algorithm -RSA-OAEP-256, RSA-OAEP and RSA1_5 key management expecting `*rsa.PublicKey` public key of corresponding length. - -```Go -package main - -import ( - "fmt" - "io/ioutil" - Rsa "github.com/dvsekhvalnov/jose2go/keys/rsa" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := `{"hello": "world"}` - - keyBytes,err := ioutil.ReadFile("public.key") - - if(err!=nil) { - panic("invalid key file") - } - - publicKey,e:=Rsa.ReadPublic(keyBytes) - - if(e!=nil) { - panic("invalid key format") - } - - //OR: - //token,err := jose.Encrypt(payload, jose.RSA1_5, jose.A256GCM, publicKey) - token,err := jose.Encrypt(payload, jose.RSA_OAEP, jose.A256GCM, publicKey) - - if(err==nil) { - //go use token - fmt.Printf("\ntoken = %v\n",token) - } -} -``` - -#### AES Key Wrap key management family of algorithms -AES128KW, AES192KW and AES256KW key management requires `[]byte` array key of corresponding length - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := `{"hello": "world"}` - - sharedKey :=[]byte{194,164,235,6,138,248,171,239,24,216,11,22,137,199,215,133} - - token,err := jose.Encrypt(payload,jose.A128KW,jose.A128GCM,sharedKey) - - if(err==nil) { - //go use token - fmt.Printf("\nA128KW A128GCM = %v\n",token) - } -} -``` - -#### AES GCM Key Wrap key management family of algorithms -AES128GCMKW, AES192GCMKW and AES256GCMKW key management requires `[]byte` array key of corresponding length - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := `{"hello": "world"}` - - sharedKey :=[]byte{194,164,235,6,138,248,171,239,24,216,11,22,137,199,215,133} - - token,err := jose.Encrypt(payload,jose.A128GCMKW,jose.A128GCM,sharedKey) - - if(err==nil) { - //go use token - fmt.Printf("\nA128GCMKW A128GCM = %v\n",token) - } -} -``` - -#### ECDH-ES and ECDH-ES with AES Key Wrap key management family of algorithms -ECDH-ES and ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW key management requires `*ecdsa.PublicKey` elliptic curve key of corresponding length. **jose2go** [provides convenient utils](#dealing-with-keys) to construct `*ecdsa.PublicKey` instance from PEM encoded PKCS1 X509 certificate or PKIX data: `ecc.ReadPublic([]byte)` or directly from `X,Y` parameters: `ecc.NewPublic(x,y []byte)`under `jose2go/keys/ecc` package: - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go/keys/ecc" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := `{"hello":"world"}` - - publicKey:=ecc.NewPublic([]byte{4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9}, - []byte{131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53}) - - token,err := jose.Encrypt(payload, jose.ECDH_ES, jose.A128CBC_HS256, publicKey) - - if(err==nil) { - //go use token - fmt.Printf("\ntoken = %v\n",token) - } -} -``` - -#### PBES2 using HMAC SHA with AES Key Wrap key management family of algorithms -PBES2-HS256+A128KW, PBES2-HS384+A192KW, PBES2-HS512+A256KW key management requires `string` passphrase from which actual key will be derived - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := `{"hello": "world"}` - - passphrase := `top secret` - - token,err := jose.Encrypt(payload,jose.PBES2_HS256_A128KW,jose.A256GCM,passphrase) - - if(err==nil) { - //go use token - fmt.Printf("\nPBES2_HS256_A128KW A256GCM = %v\n",token) - } -} -``` - -#### DIR direct pre-shared symmetric key management -Direct key management with pre-shared symmetric keys expecting `[]byte` array key of corresponding length: - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := `{"hello": "world"}` - - sharedKey :=[]byte{194,164,235,6,138,248,171,239,24,216,11,22,137,199,215,133} - - token,err := jose.Encrypt(payload,jose.DIR,jose.A128GCM,sharedKey) - - if(err==nil) { - //go use token - fmt.Printf("\nDIR A128GCM = %v\n",token) - } -} -``` - -### Creating compressed & encrypted tokens -#### DEFLATE compression -**jose2go** supports optional DEFLATE compression of payload before encrypting, can be used with all supported encryption and key management algorithms: - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := `{"hello": "world"}` - - sharedKey := []byte{194, 164, 235, 6, 138, 248, 171, 239, 24, 216, 11, 22, 137, 199, 215, 133} - - token, err := jose.Encrypt(payload, jose.DIR, jose.A128GCM, sharedKey, jose.Zip(jose.DEF)) - - if err == nil { - //go use token - fmt.Printf("\nDIR A128GCM DEFLATED= %v\n", token) - } -} -``` - -### Verifying, Decoding and Decompressing tokens -Decoding json web tokens is fully symmetric to creating signed or encrypted tokens (with respect to public/private cryptography), decompressing deflated payloads is handled automatically: - -As of v1.2 decode method defined as `jose.Decode() payload string, headers map[string]interface{}, err error` and returns both payload as unprocessed string and headers as map. - -**HS256, HS384, HS512** signatures, **A128KW, A192KW, A256KW**,**A128GCMKW, A192GCMKW, A256GCMKW** and **DIR** key management algorithm expecting `[]byte` array key: - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - token := "eyJhbGciOiJIUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9.chIoYWrQMA8XL5nFz6oLDJyvgHk2KA4BrFGrKymjC8E" - - sharedKey :=[]byte{97,48,97,50,97,98,100,56,45,54,49,54,50,45,52,49,99,51,45,56,51,100,54,45,49,99,102,53,53,57,98,52,54,97,102,99} - - payload, headers, err := jose.Decode(token,sharedKey) - - if(err==nil) { - //go use token - fmt.Printf("\npayload = %v\n",payload) - - //and/or use headers - fmt.Printf("\nheaders = %v\n",headers) - } -} -``` - -**RS256, RS384, RS512**,**PS256, PS384, PS512** signatures expecting `*rsa.PublicKey` public key of corresponding length. **jose2go** [provides convenient utils](#dealing-with-keys) to construct `*rsa.PublicKey` instance from PEM encoded PKCS1 X509 certificate or PKIX data: `Rsa.ReadPublic([]byte)` under `jose2go/keys/rsa` package: - -```Go -package main - -import ( - "fmt" - "io/ioutil" - Rsa "github.com/dvsekhvalnov/jose2go/keys/rsa" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - token := "eyJhbGciOiJSUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9.NL_dfVpZkhNn4bZpCyMq5TmnXbT4yiyecuB6Kax_lV8Yq2dG8wLfea-T4UKnrjLOwxlbwLwuKzffWcnWv3LVAWfeBxhGTa0c4_0TX_wzLnsgLuU6s9M2GBkAIuSMHY6UTFumJlEeRBeiqZNrlqvmAzQ9ppJHfWWkW4stcgLCLMAZbTqvRSppC1SMxnvPXnZSWn_Fk_q3oGKWw6Nf0-j-aOhK0S0Lcr0PV69ZE4xBYM9PUS1MpMe2zF5J3Tqlc1VBcJ94fjDj1F7y8twmMT3H1PI9RozO-21R0SiXZ_a93fxhE_l_dj5drgOek7jUN9uBDjkXUwJPAyp9YPehrjyLdw" - - keyBytes, err := ioutil.ReadFile("public.key") - - if(err!=nil) { - panic("invalid key file") - } - - publicKey, e:=Rsa.ReadPublic(keyBytes) - - if(e!=nil) { - panic("invalid key format") - } - - payload, headers, err := jose.Decode(token, publicKey) - - if(err==nil) { - //go use token - fmt.Printf("\npayload = %v\n",payload) - - //and/or use headers - fmt.Printf("\nheaders = %v\n",headers) - } -} -``` - -**RSA-OAEP-256**, **RSA-OAEP** and **RSA1_5** key management algorithms expecting `*rsa.PrivateKey` private key of corresponding length: - -```Go -package main - -import ( - "fmt" - "io/ioutil" - Rsa "github.com/dvsekhvalnov/jose2go/keys/rsa" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - token := "eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMjU2R0NNIn0.ixD3WVOkvaxeLKi0kyVqTzM6W2EW25SHHYCAr9473Xq528xSK0AVux6kUtv7QMkQKgkMvO8X4VdvonyGkDZTK2jgYUiI06dz7I1sjWJIbyNVrANbBsmBiwikwB-9DLEaKuM85Lwu6gnzbOF6B9R0428ckxmITCPDrzMaXwYZHh46FiSg9djChUTex0pHGhNDiEIgaINpsmqsOFX1L2Y7KM2ZR7wtpR3kidMV3JlxHdKheiPKnDx_eNcdoE-eogPbRGFdkhEE8Dyass1ZSxt4fP27NwsIer5pc0b922_3XWdi1r1TL_fLvGktHLvt6HK6IruXFHpU4x5Z2gTXWxEIog.zzTNmovBowdX2_hi.QSPSgXn0w25ugvzmu2TnhePn.0I3B9BE064HFNP2E0I7M9g" - - keyBytes, err := ioutil.ReadFile("private.key") - - if(err!=nil) { - panic("invalid key file") - } - - privateKey, e:=Rsa.ReadPrivate(keyBytes) - - if(e!=nil) { - panic("invalid key format") - } - - payload, headers, err := jose.Decode(token, privateKey) - - if(err==nil) { - //go use payload - fmt.Printf("\npayload = %v\n",payload) - - //and/or use headers - fmt.Printf("\nheaders = %v\n",headers) - } -} -``` - -**PBES2-HS256+A128KW, PBES2-HS384+A192KW, PBES2-HS512+A256KW** key management algorithms expects `string` passpharase as a key - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - token := `eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMjU2R0NNIiwicDJjIjo4MTkyLCJwMnMiOiJlZWpFZTF0YmJVbU5XV2s2In0.J2HTgltxH3p7A2zDgQWpZPgA2CHTSnDmMhlZWeSOMoZ0YvhphCeg-w.FzYG5AOptknu7jsG.L8jAxfxZhDNIqb0T96YWoznQ.yNeOfQWUbm8KuDGZ_5lL_g` - - passphrase := `top secret` - - payload, headers, err := jose.Decode(token,passphrase) - - if(err==nil) { - //go use token - fmt.Printf("\npayload = %v\n",payload) - - //and/or use headers - fmt.Printf("\nheaders = %v\n",headers) - } -} -``` - -**ES256, ES284, ES512** signatures expecting `*ecdsa.PublicKey` public elliptic curve key of corresponding length. **jose2go** [provides convenient utils](#dealing-with-keys) to construct `*ecdsa.PublicKey` instance from PEM encoded PKCS1 X509 certificate or PKIX data: `ecc.ReadPublic([]byte)` or directly from `X,Y` parameters: `ecc.NewPublic(x,y []byte)`under `jose2go/keys/ecc` package: - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go/keys/ecc" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - token := "eyJhbGciOiJFUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9.EVnmDMlz-oi05AQzts-R3aqWvaBlwVZddWkmaaHyMx5Phb2NSLgyI0kccpgjjAyo1S5KCB3LIMPfmxCX_obMKA" - - publicKey:=ecc.NewPublic([]byte{4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9}, - []byte{131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53}) - - payload, headers, err := jose.Decode(token, publicKey) - - if(err==nil) { - //go use token - fmt.Printf("\npayload = %v\n",payload) - - //and/or use headers - fmt.Printf("\nheaders = %v\n",headers) - } -} -``` - -**ECDH-ES** and **ECDH-ES+A128KW**, **ECDH-ES+A192KW**, **ECDH-ES+A256KW** key management expecting `*ecdsa.PrivateKey` private elliptic curve key of corresponding length. **jose2go** [provides convenient utils](#dealing-with-keys) to construct `*ecdsa.PrivateKey` instance from PEM encoded PKCS1 or PKCS8 data: `ecc.ReadPrivate([]byte)` or directly from `X,Y,D` parameters: `ecc.NewPrivate(x,y,d []byte)` under `jose2go/keys/ecc` package: - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go/keys/ecc" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - token := "eyJhbGciOiJFQ0RILUVTIiwiZW5jIjoiQTEyOENCQy1IUzI1NiIsImVwayI6eyJrdHkiOiJFQyIsIngiOiItVk1LTG5NeW9IVHRGUlpGNnFXNndkRm5BN21KQkdiNzk4V3FVMFV3QVhZIiwieSI6ImhQQWNReTgzVS01Qjl1U21xbnNXcFZzbHVoZGJSZE1nbnZ0cGdmNVhXTjgiLCJjcnYiOiJQLTI1NiJ9fQ..UA3N2j-TbYKKD361AxlXUA.XxFur_nY1GauVp5W_KO2DEHfof5s7kUwvOgghiNNNmnB4Vxj5j8VRS8vMOb51nYy2wqmBb2gBf1IHDcKZdACkCOMqMIcpBvhyqbuKiZPLHiilwSgVV6ubIV88X0vK0C8ZPe5lEyRudbgFjdlTnf8TmsvuAsdtPn9dXwDjUR23bD2ocp8UGAV0lKqKzpAw528vTfD0gwMG8gt_op8yZAxqqLLljMuZdTnjofAfsW2Rq3Z6GyLUlxR51DAUlQKi6UpsKMJoXTrm1Jw8sXBHpsRqA.UHCYOtnqk4SfhAknCnymaQ" - - privateKey:=ecc.NewPrivate([]byte{4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9}, - []byte{131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53}, - []byte{ 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 }) - - payload, headers, err := jose.Decode(token, privateKey) - - if(err==nil) { - //go use token - fmt.Printf("\npayload = %v\n",payload) - - //and/or use headers - fmt.Printf("\nheaders = %v\n",headers) - } -} -``` - -### Adding extra headers -It's possible to pass additional headers while encoding token. **jose2go** provides convenience configuration helpers: `Header(name string, value interface{})` and `Headers(headers map[string]interface{})` that can be passed to `Sign(..)` and `Encrypt(..)` calls. - -Note: **jose2go** do not allow to override `alg`, `enc` and `zip` headers. - -Example of signing with extra headers: -```Go - token, err := jose.Sign(payload, jose.ES256, key, - jose.Header("keyid", "111-222-333"), - jose.Header("trans-id", "aaa-bbb")) -``` - -Encryption with extra headers: -```Go -token, err := jose.Encrypt(payload, jose.DIR, jose.A128GCM, sharedKey, - jose.Headers(map[string]interface{}{"keyid": "111-22-33", "cty": "text/plain"})) -``` - -### Two phase validation -In some cases validation (decoding) key can be unknown prior to examining token content. For instance one can use different keys per token issuer or rely on headers information to determine which key to use, do logging or other things. - -**jose2go** allows to pass `func(headers map[string]interface{}, payload string) key interface{}` callback instead of key to `jose.Decode(..)`. Callback will be executed prior to decoding and integrity validation and will recieve parsed headers and payload as is (for encrypted tokens it will be cipher text). Callback should return key to be used for actual decoding process or `error` if decoding should be stopped, given error object will be returned from `jose.Decode(..)` call. - -Example of decoding token with callback: - -```Go -package main - -import ( - "crypto/rsa" - "fmt" - "github.com/dvsekhvalnov/jose2go" - "github.com/dvsekhvalnov/jose2go/keys/rsa" - "io/ioutil" - "errors" -) - -func main() { - - token := "eyJhbGciOiJSUzI1NiIsImN0eSI6InRleHRcL3BsYWluIn0.eyJoZWxsbyI6ICJ3b3JsZCJ9.NL_dfVpZkhNn4bZpCyMq5TmnXbT4yiyecuB6Kax_lV8Yq2dG8wLfea-T4UKnrjLOwxlbwLwuKzffWcnWv3LVAWfeBxhGTa0c4_0TX_wzLnsgLuU6s9M2GBkAIuSMHY6UTFumJlEeRBeiqZNrlqvmAzQ9ppJHfWWkW4stcgLCLMAZbTqvRSppC1SMxnvPXnZSWn_Fk_q3oGKWw6Nf0-j-aOhK0S0Lcr0PV69ZE4xBYM9PUS1MpMe2zF5J3Tqlc1VBcJ94fjDj1F7y8twmMT3H1PI9RozO-21R0SiXZ_a93fxhE_l_dj5drgOek7jUN9uBDjkXUwJPAyp9YPehrjyLdw" - - payload, _, err := jose.Decode(token, - func(headers map[string]interface{}, payload string) interface{} { - //log something - fmt.Printf("\nHeaders before decoding: %v\n", headers) - fmt.Printf("\nPayload before decoding: %v\n", payload) - - //lookup key based on keyid header as en example - //or lookup based on something from payload, e.g. 'iss' claim for instance - key := FindKey(headers['keyid']) - - if(key==nil) { - return errors.New("Key not found") - } - - return key; - }) - - if err == nil { - //go use token - fmt.Printf("\ndecoded payload = %v\n", payload) - } -} -``` - -### Working with binary payload -In addition to work with string payloads (typical use-case) `jose2go` supports -encoding and decoding of raw binary data. `jose.DecodeBytes`, `jose.SignBytes` -and `jose.EncryptBytes` functions provides similar interface but accepting -`[]byte` payloads. - -Examples: - -```Go -package main - -import ( - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - token := `eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJlbmMiOiJBMjU2R0NNIiwicDJjIjo4MTkyLCJwMnMiOiJlZWpFZTF0YmJVbU5XV2s2In0.J2HTgltxH3p7A2zDgQWpZPgA2CHTSnDmMhlZWeSOMoZ0YvhphCeg-w.FzYG5AOptknu7jsG.L8jAxfxZhDNIqb0T96YWoznQ.yNeOfQWUbm8KuDGZ_5lL_g` - - passphrase := `top secret` - - payload, headers, err := jose.DecodeBytes(token,passphrase) - - if(err==nil) { - //go use token - //payload = []byte{....} - } -} -``` - -```Go -package main - -import ( - "fmt" - "io/ioutil" - Rsa "github.com/dvsekhvalnov/jose2go/keys/rsa" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := []byte {0x01, 0x02, 0x03, 0x04} - - keyBytes,err := ioutil.ReadFile("private.key") - - if(err!=nil) { - panic("invalid key file") - } - - privateKey,e:=Rsa.ReadPrivate(keyBytes) - - if(e!=nil) { - panic("invalid key format") - } - - token,err := jose.SignBytes(payload,jose.RS256, privateKey) - - if(err==nil) { - //go use token - fmt.Printf("\nRS256 = %v\n",token) - } -} -``` - -```Go -package main - -import ( - "fmt" - "io/ioutil" - Rsa "github.com/dvsekhvalnov/jose2go/keys/rsa" - "github.com/dvsekhvalnov/jose2go" -) - -func main() { - - payload := []byte {0x01, 0x02, 0x03, 0x04} - - keyBytes,err := ioutil.ReadFile("public.key") - - if(err!=nil) { - panic("invalid key file") - } - - publicKey,e:=Rsa.ReadPublic(keyBytes) - - if(e!=nil) { - panic("invalid key format") - } - - token,err := jose.EncryptBytes(payload, jose.RSA_OAEP, jose.A256GCM, publicKey) - - if(err==nil) { - //go use token - fmt.Printf("\ntoken = %v\n",token) - } -} -``` -### Dealing with keys -**jose2go** provides several helper methods to simplify loading & importing of elliptic and rsa keys. Import `jose2go/keys/rsa` or `jose2go/keys/ecc` respectively: - -#### RSA keys -1. `Rsa.ReadPrivate(raw []byte) (key *rsa.PrivateKey,err error)` attempts to parse RSA private key from PKCS1 or PKCS8 format (`BEGIN RSA PRIVATE KEY` and `BEGIN PRIVATE KEY` headers) - -```Go -package main - -import ( - "fmt" - Rsa "github.com/dvsekhvalnov/jose2go/keys/rsa" - "io/ioutil" -) - -func main() { - - keyBytes, _ := ioutil.ReadFile("private.key") - - privateKey, err:=Rsa.ReadPrivate(keyBytes) - - if(err!=nil) { - panic("invalid key format") - } - - fmt.Printf("privateKey = %v\n",privateKey) -} -``` - -2. `Rsa.ReadPublic(raw []byte) (key *rsa.PublicKey,err error)` attempts to parse RSA public key from PKIX key format or PKCS1 X509 certificate (`BEGIN PUBLIC KEY` and `BEGIN CERTIFICATE` headers) - -```Go -package main - -import ( - "fmt" - Rsa "github.com/dvsekhvalnov/jose2go/keys/rsa" - "io/ioutil" -) - -func main() { - - keyBytes, _ := ioutil.ReadFile("public.cer") - - publicKey, err:=Rsa.ReadPublic(keyBytes) - - if(err!=nil) { - panic("invalid key format") - } - - fmt.Printf("publicKey = %v\n",publicKey) -} -``` - -#### ECC keys -1. `ecc.ReadPrivate(raw []byte) (key *ecdsa.PrivateKey,err error)` attemps to parse elliptic curve private key from PKCS1 or PKCS8 format (`BEGIN EC PRIVATE KEY` and `BEGIN PRIVATE KEY` headers) - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go/keys/ecc" - "io/ioutil" -) - -func main() { - - keyBytes, _ := ioutil.ReadFile("ec-private.pem") - - ecPrivKey, err:=ecc.ReadPrivate(keyBytes) - - if(err!=nil) { - panic("invalid key format") - } - - fmt.Printf("ecPrivKey = %v\n",ecPrivKey) -} -``` - -2. `ecc.ReadPublic(raw []byte) (key *ecdsa.PublicKey,err error)` attemps to parse elliptic curve public key from PKCS1 X509 or PKIX format (`BEGIN PUBLIC KEY` and `BEGIN CERTIFICATE` headers) - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go/keys/ecc" - "io/ioutil" -) - -func main() { - - keyBytes, _ := ioutil.ReadFile("ec-public.key") - - ecPubKey, err:=ecc.ReadPublic(keyBytes) - - if(err!=nil) { - panic("invalid key format") - } - - fmt.Printf("ecPubKey = %v\n",ecPubKey) -} -``` - -3. `ecc.NewPublic(x,y []byte) (*ecdsa.PublicKey)` constructs elliptic public key from (X,Y) represented as bytes. Supported are NIST curves P-256,P-384 and P-521. Curve detected automatically by input length. - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go/keys/ecc" -) - -func main() { - - ecPubKey:=ecc.NewPublic([]byte{4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9}, - []byte{131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53}) - - fmt.Printf("ecPubKey = %v\n",ecPubKey) -} -``` - -4. `ecc.NewPrivate(x,y,d []byte) (*ecdsa.PrivateKey)` constructs elliptic private key from (X,Y) and D represented as bytes. Supported are NIST curves P-256,P-384 and P-521. Curve detected automatically by input length. - -```Go -package main - -import ( - "fmt" - "github.com/dvsekhvalnov/jose2go/keys/ecc" -) - -func main() { - - ecPrivKey:=ecc.NewPrivate([]byte{4, 114, 29, 223, 58, 3, 191, 170, 67, 128, 229, 33, 242, 178, 157, 150, 133, 25, 209, 139, 166, 69, 55, 26, 84, 48, 169, 165, 67, 232, 98, 9}, - []byte{131, 116, 8, 14, 22, 150, 18, 75, 24, 181, 159, 78, 90, 51, 71, 159, 214, 186, 250, 47, 207, 246, 142, 127, 54, 183, 72, 72, 253, 21, 88, 53}, - []byte{ 42, 148, 231, 48, 225, 196, 166, 201, 23, 190, 229, 199, 20, 39, 226, 70, 209, 148, 29, 70, 125, 14, 174, 66, 9, 198, 80, 251, 95, 107, 98, 206 }) - - fmt.Printf("ecPrivKey = %v\n",ecPrivKey) -} -``` - -### More examples -Checkout `jose_test.go` for more examples. - -## Changelog -### 1.2 -- interface to access token headers after decoding -- interface to provide extra headers for token encoding -- two-phase validation support - -### 1.1 -- security and bug fixes - -### 1.0 -- initial stable version with full suite JOSE spec support diff --git a/vendor/github.com/dvsekhvalnov/jose2go/aes/ecb.go b/vendor/github.com/dvsekhvalnov/jose2go/aes/ecb.go deleted file mode 100644 index ec9af99..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/aes/ecb.go +++ /dev/null @@ -1,68 +0,0 @@ -// Package aes contains provides AES Key Wrap and ECB mode implementations -package aes - -import ( - "crypto/cipher" -) - -type ecb struct { - b cipher.Block -} - -type ecbEncrypter ecb -type ecbDecrypter ecb - -// NewECBEncrypter creates BlockMode for AES encryption in ECB mode -func NewECBEncrypter(b cipher.Block) cipher.BlockMode { - return &ecbEncrypter{b: b} -} - -// NewECBDecrypter creates BlockMode for AES decryption in ECB mode -func NewECBDecrypter(b cipher.Block) cipher.BlockMode { - return &ecbDecrypter{b: b} -} - -func (x *ecbEncrypter) BlockSize() int { return x.b.BlockSize() } -func (x *ecbDecrypter) BlockSize() int { return x.b.BlockSize() } - -func (x *ecbDecrypter) CryptBlocks(dst, src []byte) { - bs := x.BlockSize() - - if len(src)%bs != 0 { - panic("ecbDecrypter.CryptBlocks(): input not full blocks") - } - - if len(dst) < len(src) { - panic("ecbDecrypter.CryptBlocks(): output smaller than input") - } - - if len(src) == 0 { - return - } - - for len(src) > 0 { - x.b.Decrypt(dst, src) - src = src[bs:] - } -} - -func (x *ecbEncrypter) CryptBlocks(dst, src []byte) { - bs := x.BlockSize() - - if len(src)%bs != 0 { - panic("ecbEncrypter.CryptBlocks(): input not full blocks") - } - - if len(dst) < len(src) { - panic("ecbEncrypter.CryptBlocks(): output smaller than input") - } - - if len(src) == 0 { - return - } - - for len(src) > 0 { - x.b.Encrypt(dst, src) - src = src[bs:] - } -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/aes/key_wrap.go b/vendor/github.com/dvsekhvalnov/jose2go/aes/key_wrap.go deleted file mode 100644 index 8e5963e..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/aes/key_wrap.go +++ /dev/null @@ -1,113 +0,0 @@ -package aes - -import ( - "github.com/dvsekhvalnov/jose2go/arrays" - "crypto/cipher" - "crypto/aes" - "crypto/hmac" - "errors" -) - -var defaultIV=[]byte { 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 } - -// KeyWrap encrypts provided key (CEK) with KEK key using AES Key Wrap (rfc 3394) algorithm -func KeyWrap(cek,kek []byte) ([]byte,error) { - // 1) Initialize variables - a := defaultIV // Set A = IV, an initial value - r := arrays.Slice(cek, 8) // For i = 1 to n - // R[0][i] = P[i] - n := uint64(len(r)) - - // 2) Calculate intermediate values. - var j,i,t uint64 - - for j = 0; j < 6; j++ { // For j = 0 to 5 - for i = 0; i < n; i++ { // For i=1 to n - t = n * j + i + 1; - b,e := aesEnc(kek, arrays.Concat(a, r[i])) // B=AES(K, A | R[i]) - - if e!=nil { return nil, e } - - a = b[:len(b)/2] // A=MSB(64,B) ^ t where t = (n*j)+i - r[i] = b[len(b)/2:] // R[i] = LSB(64, B) - a = arrays.Xor(a, arrays.UInt64ToBytes(t)) - } - } - - // 3) Output the results - c := make([][]byte, n+1, n+1) - c[0] = a; // Set C[0] = A - for i = 1; i <= n; i++ { // For i = 1 to n - c[i] = r[i - 1] // C[i] = R[i] - } - - return arrays.Unwrap(c),nil -} - -// KeyUnwrap decrypts previously encrypted key (CEK) with KEK key using AES Key Wrap (rfc 3394) algorithm -func KeyUnwrap(encryptedCek, kek []byte) ([]byte,error) { - // 1) Initialize variables - c := arrays.Slice(encryptedCek, 8); - a := c[0]; // Set A = C[0] - r := make([][]byte,len(c) - 1); - - for i := 1; i < len(c); i++ { // For i = 1 to n - r[i - 1] = c[i]; // R[i] = C[i] - } - - n := uint64(len(r)) - - // 2) Calculate intermediate values - var t,j uint64 - - for j = 6; j > 0; j-- { // For j = 5 to 0 - for i := n; i > 0; i-- { // For i = n to 1 - t = n * (j-1) + i; - a = arrays.Xor(a, arrays.UInt64ToBytes(t)) - b,e := aesDec(kek, arrays.Concat(a, r[i-1])) // B = AES-1(K, (A ^ t) | R[i]) where t = n*j+i - - if e!=nil { return nil,e } - - a = b[:len(b)/2] // A = MSB(64, B) - r[i-1] = b[len(b)/2:] // R[i] = LSB(64, B) - } - } - - // 3) Output the results - if (!hmac.Equal(defaultIV, a)) { // If A is an appropriate initial value - return nil, errors.New("aes.KeyUnwrap(): integrity check failed.") - } - - // For i = 1 to n - return arrays.Unwrap(r),nil // P[i] = R[i] - -} - -func aesEnc(kek, plainText []byte) (cipherText []byte, err error) { - var block cipher.Block - - if block, err = aes.NewCipher(kek);err!=nil { - return nil,err - } - - cipherText = make([]byte, len(plainText)) - - NewECBEncrypter(block).CryptBlocks(cipherText,plainText) - - return cipherText,nil -} - -func aesDec(kek, cipherText []byte) (plainText []byte,err error) { - - var block cipher.Block - - if block, err = aes.NewCipher(kek);err!=nil { - return nil,err - } - - plainText = make([]byte, len(cipherText)) - - NewECBDecrypter(block).CryptBlocks(plainText,cipherText) - - return plainText,nil -} \ No newline at end of file diff --git a/vendor/github.com/dvsekhvalnov/jose2go/aes_cbc_hmac.go b/vendor/github.com/dvsekhvalnov/jose2go/aes_cbc_hmac.go deleted file mode 100644 index a2217e1..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/aes_cbc_hmac.go +++ /dev/null @@ -1,112 +0,0 @@ -package jose - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/hmac" - "errors" - "fmt" - "github.com/dvsekhvalnov/jose2go/arrays" - "github.com/dvsekhvalnov/jose2go/padding" -) - -// AES CBC with HMAC authenticated encryption algorithm implementation -type AesCbcHmac struct { - keySizeBits int -} - -func init() { - RegisterJwe(&AesCbcHmac{keySizeBits: 256}) - RegisterJwe(&AesCbcHmac{keySizeBits: 384}) - RegisterJwe(&AesCbcHmac{keySizeBits: 512}) -} - -func (alg *AesCbcHmac) Name() string { - switch alg.keySizeBits { - case 256: - return A128CBC_HS256 - case 384: - return A192CBC_HS384 - default: - return A256CBC_HS512 - } -} - -func (alg *AesCbcHmac) KeySizeBits() int { - return alg.keySizeBits -} - -func (alg *AesCbcHmac) SetKeySizeBits(bits int) { - alg.keySizeBits = bits -} - -func (alg *AesCbcHmac) Encrypt(aad, plainText, cek []byte) (iv, cipherText, authTag []byte, err error) { - - cekSizeBits := len(cek) << 3 - if cekSizeBits != alg.keySizeBits { - return nil, nil, nil, errors.New(fmt.Sprintf("AesCbcHmac.Encrypt(): expected key of size %v bits, but was given %v bits.", alg.keySizeBits, cekSizeBits)) - } - - hmacKey := cek[0 : len(cek)/2] - aesKey := cek[len(cek)/2:] - - if iv, err = arrays.Random(16); err != nil { - return nil, nil, nil, err - } - - var block cipher.Block - - if block, err = aes.NewCipher(aesKey); err != nil { - return nil, nil, nil, err - } - - padded := padding.AddPkcs7(plainText, 16) - - cipherText = make([]byte, len(padded), cap(padded)) - mode := cipher.NewCBCEncrypter(block, iv) - mode.CryptBlocks(cipherText, padded) - - authTag = alg.computeAuthTag(aad, iv, cipherText, hmacKey) - - return iv, cipherText, authTag, nil -} - -func (alg *AesCbcHmac) Decrypt(aad, cek, iv, cipherText, authTag []byte) (plainText []byte, err error) { - - cekSizeBits := len(cek) << 3 - - if cekSizeBits != alg.keySizeBits { - return nil, errors.New(fmt.Sprintf("AesCbcHmac.Decrypt(): expected key of size %v bits, but was given %v bits.", alg.keySizeBits, cekSizeBits)) - } - - hmacKey := cek[0 : len(cek)/2] - aesKey := cek[len(cek)/2:] - - // Check MAC - expectedAuthTag := alg.computeAuthTag(aad, iv, cipherText, hmacKey) - - if !hmac.Equal(expectedAuthTag, authTag) { - return nil, errors.New("AesCbcHmac.Decrypt(): Authentication tag do not match.") - } - - var block cipher.Block - - if block, err = aes.NewCipher(aesKey); err == nil { - mode := cipher.NewCBCDecrypter(block, iv) - - var padded []byte = make([]byte, len(cipherText), cap(cipherText)) - mode.CryptBlocks(padded, cipherText) - - return padding.RemovePkcs7(padded, 16), nil - } - - return nil, err -} - -func (alg *AesCbcHmac) computeAuthTag(aad []byte, iv []byte, cipherText []byte, hmacKey []byte) (signature []byte) { - al := arrays.UInt64ToBytes(uint64(len(aad) << 3)) - hmacInput := arrays.Concat(aad, iv, cipherText, al) - hmac := calculateHmac(alg.keySizeBits, hmacInput, hmacKey) - - return hmac[0 : len(hmac)/2] -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/aes_gcm.go b/vendor/github.com/dvsekhvalnov/jose2go/aes_gcm.go deleted file mode 100644 index 57fc861..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/aes_gcm.go +++ /dev/null @@ -1,98 +0,0 @@ -package jose - -import ( - "fmt" - "errors" - "crypto/aes" - "crypto/cipher" - "github.com/dvsekhvalnov/jose2go/arrays" -) - -// AES GCM authenticated encryption algorithm implementation -type AesGcm struct{ - keySizeBits int -} - -func init() { - RegisterJwe(&AesGcm{keySizeBits:128}) - RegisterJwe(&AesGcm{keySizeBits:192}) - RegisterJwe(&AesGcm{keySizeBits:256}) -} - -func (alg *AesGcm) Name() string { - switch alg.keySizeBits { - case 128: return A128GCM - case 192: return A192GCM - default: return A256GCM - } -} - -func (alg *AesGcm) KeySizeBits() int { - return alg.keySizeBits -} - -func (alg *AesGcm) Encrypt(aad, plainText, cek []byte) (iv, cipherText, authTag []byte, err error) { - - cekSizeBits := len(cek)<<3 - - if cekSizeBits != alg.keySizeBits { - return nil,nil,nil, errors.New(fmt.Sprintf("AesGcm.Encrypt(): expected key of size %v bits, but was given %v bits.",alg.keySizeBits, cekSizeBits)) - } - - if iv,err = arrays.Random(12);err!=nil { - return nil,nil,nil,err - } - - var block cipher.Block - - if block, err = aes.NewCipher(cek);err!=nil { - return nil,nil,nil,err - } - - var aesgcm cipher.AEAD - - if aesgcm,err = cipher.NewGCM(block);err!=nil { - return nil,nil,nil,err - } - - cipherWithTag := aesgcm.Seal(nil, iv, plainText, aad) - - cipherText=cipherWithTag[:len(cipherWithTag)-aesgcm.Overhead()] - authTag=cipherWithTag[len(cipherWithTag)-aesgcm.Overhead():] - - return iv, cipherText, authTag, nil -} - -func (alg *AesGcm) Decrypt(aad, cek, iv, cipherText, authTag []byte) (plainText []byte, err error) { - - cekSizeBits := len(cek)<<3 - - if cekSizeBits != alg.keySizeBits { - return nil, errors.New(fmt.Sprintf("AesGcm.Decrypt(): expected key of size %v bits, but was given %v bits.",alg.keySizeBits, cekSizeBits)) - } - - var block cipher.Block - - if block, err = aes.NewCipher(cek);err!=nil { - return nil,err - } - - var aesgcm cipher.AEAD - - if aesgcm,err = cipher.NewGCM(block);err!=nil { - return nil,err - } - - cipherWithTag:=append(cipherText,authTag...) - - if nonceSize := len(iv); nonceSize != aesgcm.NonceSize() { - return nil, errors.New(fmt.Sprintf("AesGcm.Decrypt(): expected nonce of size %v bits, but was given %v bits.", aesgcm.NonceSize()<<3, nonceSize<<3)) - } - - if plainText,err = aesgcm.Open(nil, iv, cipherWithTag, aad);err!=nil { - return nil,err - } - - return plainText,nil -} - diff --git a/vendor/github.com/dvsekhvalnov/jose2go/aes_gcm_kw.go b/vendor/github.com/dvsekhvalnov/jose2go/aes_gcm_kw.go deleted file mode 100644 index e6f5681..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/aes_gcm_kw.go +++ /dev/null @@ -1,128 +0,0 @@ -package jose - -import ( - "errors" - "fmt" - "github.com/dvsekhvalnov/jose2go/base64url" - "github.com/dvsekhvalnov/jose2go/arrays" - "crypto/aes" - "crypto/cipher" -) - -func init() { - RegisterJwa(&AesGcmKW{ keySizeBits: 128}) - RegisterJwa(&AesGcmKW{ keySizeBits: 192}) - RegisterJwa(&AesGcmKW{ keySizeBits: 256}) -} - -// AES GCM Key Wrap key management algorithm implementation -type AesGcmKW struct { - keySizeBits int -} - -func (alg *AesGcmKW) Name() string { - switch alg.keySizeBits { - case 128: return A128GCMKW - case 192: return A192GCMKW - default: return A256GCMKW - } -} - -func (alg *AesGcmKW) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) { - if kek,ok:=key.([]byte); ok { - - kekSizeBits := len(kek) << 3 - - if kekSizeBits != alg.keySizeBits { - return nil,nil, errors.New(fmt.Sprintf("AesGcmKW.WrapNewKey(): expected key of size %v bits, but was given %v bits.",alg.keySizeBits, kekSizeBits)) - } - - if cek,err = arrays.Random(cekSizeBits>>3);err!=nil { - return nil,nil,err - } - - var iv []byte - - if iv,err = arrays.Random(12);err!=nil { - return nil,nil,err - } - - var block cipher.Block - - if block, err = aes.NewCipher(kek);err!=nil { - return nil,nil,err - } - - var aesgcm cipher.AEAD - - if aesgcm,err = cipher.NewGCM(block);err!=nil { - return nil,nil,err - } - - cipherWithTag := aesgcm.Seal(nil, iv, cek, nil) - - cipherText := cipherWithTag[:len(cipherWithTag)-aesgcm.Overhead()] - authTag := cipherWithTag[len(cipherWithTag)-aesgcm.Overhead():] - - header["iv"]=base64url.Encode(iv) - header["tag"]=base64url.Encode(authTag) - - return cek,cipherText,nil - } - - return nil,nil,errors.New("AesGcmKW.WrapNewKey(): expected key to be '[]byte' array") -} - -func (alg *AesGcmKW) Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) { - if kek,ok:=key.([]byte); ok { - - kekSizeBits := len(kek) << 3 - - if kekSizeBits != alg.keySizeBits { - return nil,errors.New(fmt.Sprintf("AesGcmKW.Unwrap(): expected key of size %v bits, but was given %v bits.", alg.keySizeBits, kekSizeBits)) - } - - var iv,tag string - - if iv,ok = header["iv"].(string);!ok { - return nil,errors.New("AesGcmKW.Unwrap(): expected 'iv' param in JWT header, but was not found.") - } - - if tag,ok = header["tag"].(string);!ok { - return nil,errors.New("AesGcmKW.Unwrap(): expected 'tag' param in JWT header, but was not found.") - } - - var ivBytes,tagBytes []byte - - if ivBytes,err = base64url.Decode(iv);err!=nil { - return nil,err - } - - if tagBytes,err = base64url.Decode(tag);err!=nil { - return nil,err - } - - var block cipher.Block - - if block, err = aes.NewCipher(kek);err!=nil { - return nil,err - } - - var aesgcm cipher.AEAD - - if aesgcm,err = cipher.NewGCM(block);err!=nil { - return nil,err - } - - cipherAndTag:=append(encryptedCek,tagBytes...) - - if cek,err = aesgcm.Open(nil, ivBytes,cipherAndTag , nil);err!=nil { - fmt.Printf("err = %v\n",err) - return nil,err - } - - return cek,nil - } - - return nil,errors.New("AesGcmKW.Unwrap(): expected key to be '[]byte' array") -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/aeskw.go b/vendor/github.com/dvsekhvalnov/jose2go/aeskw.go deleted file mode 100644 index c5b3e4f..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/aeskw.go +++ /dev/null @@ -1,64 +0,0 @@ -package jose - -import ( - "errors" - "fmt" - "github.com/dvsekhvalnov/jose2go/aes" - "github.com/dvsekhvalnov/jose2go/arrays" -) - -func init() { - RegisterJwa(&AesKW{ keySizeBits: 128}) - RegisterJwa(&AesKW{ keySizeBits: 192}) - RegisterJwa(&AesKW{ keySizeBits: 256}) -} - -// AES Key Wrap key management algorithm implementation -type AesKW struct { - keySizeBits int -} - -func (alg *AesKW) Name() string { - switch alg.keySizeBits { - case 128: return A128KW - case 192: return A192KW - default: return A256KW - } -} - -func (alg *AesKW) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) { - if kek,ok:=key.([]byte); ok { - - kekSizeBits := len(kek) << 3 - - if kekSizeBits != alg.keySizeBits { - return nil,nil, errors.New(fmt.Sprintf("AesKW.WrapNewKey(): expected key of size %v bits, but was given %v bits.",alg.keySizeBits, kekSizeBits)) - } - - if cek,err = arrays.Random(cekSizeBits>>3);err==nil { - encryptedCek,err=aes.KeyWrap(cek,kek) - return - } - - return nil,nil,err - - } - - return nil,nil,errors.New("AesKW.WrapNewKey(): expected key to be '[]byte' array") -} - -func (alg *AesKW) Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) { - - if kek,ok:=key.([]byte); ok { - - kekSizeBits := len(kek) << 3 - - if kekSizeBits != alg.keySizeBits { - return nil,errors.New(fmt.Sprintf("AesKW.Unwrap(): expected key of size %v bits, but was given %v bits.", alg.keySizeBits, kekSizeBits)) - } - - return aes.KeyUnwrap(encryptedCek, kek) - } - - return nil,errors.New("AesKW.Unwrap(): expected key to be '[]byte' array") -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/arrays/arrays.go b/vendor/github.com/dvsekhvalnov/jose2go/arrays/arrays.go deleted file mode 100644 index 17ff0bd..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/arrays/arrays.go +++ /dev/null @@ -1,116 +0,0 @@ -// Package arrays provides various byte array utilities -package arrays - -import ( - "bytes" - "crypto/rand" - "encoding/binary" - "fmt" - "github.com/dvsekhvalnov/jose2go/base64url" -) - -// Xor is doing byte by byte exclusive or of 2 byte arrays -func Xor(left, right []byte) []byte { - result := make([]byte, len(left)) - - for i := 0; i < len(left); i++ { - result[i] = left[i] ^ right[i] - } - - return result -} - -// Slice is splitting input byte array into slice of subarrays. Each of count length. -func Slice(arr []byte, count int) [][]byte { - - sliceCount := len(arr) / count - result := make([][]byte, sliceCount) - - for i := 0; i < sliceCount; i++ { - start := i * count - end := i*count + count - - result[i] = arr[start:end] - } - - return result -} - -// Random generates byte array with random data of byteCount length -func Random(byteCount int) ([]byte, error) { - data := make([]byte, byteCount) - - if _, err := rand.Read(data); err != nil { - return nil, err - } - - return data, nil -} - -// Concat combine several arrays into single one, resulting slice = A1 | A2 | A3 | ... | An -func Concat(arrays ...[]byte) []byte { - var result []byte = arrays[0] - - for _, arr := range arrays[1:] { - result = append(result, arr...) - } - - return result -} - -// Unwrap same thing as Contact, just different interface, combines several array into single one -func Unwrap(arrays [][]byte) []byte { - var result []byte = arrays[0] - - for _, arr := range arrays[1:] { - result = append(result, arr...) - } - - return result -} - -// UInt64ToBytes unwrap uint64 value to byte array of length 8 using big endian -func UInt64ToBytes(value uint64) []byte { - result := make([]byte, 8) - binary.BigEndian.PutUint64(result, value) - - return result -} - -// UInt32ToBytes unwrap uint32 value to byte array of length 4 using big endian -func UInt32ToBytes(value uint32) []byte { - result := make([]byte, 4) - binary.BigEndian.PutUint32(result, value) - - return result -} - -// Dump produces printable debug representation of byte array as string -func Dump(arr []byte) string { - var buf bytes.Buffer - - buf.WriteString("(") - buf.WriteString(fmt.Sprintf("%v", len(arr))) - buf.WriteString(" bytes)[") - - for idx, b := range arr { - buf.WriteString(fmt.Sprintf("%v", b)) - if idx != len(arr)-1 { - buf.WriteString(", ") - } - } - - buf.WriteString("], Hex: [") - - for idx, b := range arr { - buf.WriteString(fmt.Sprintf("%X", b)) - if idx != len(arr)-1 { - buf.WriteString(" ") - } - } - - buf.WriteString("], Base64Url:") - buf.WriteString(base64url.Encode(arr)) - - return buf.String() -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/base64url/base64url.go b/vendor/github.com/dvsekhvalnov/jose2go/base64url/base64url.go deleted file mode 100644 index 7229a85..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/base64url/base64url.go +++ /dev/null @@ -1,31 +0,0 @@ -// package base64url provides base64url encoding/decoding support -package base64url - -import ( - "strings" - "encoding/base64" -) - -// Decode decodes base64url string to byte array -func Decode(data string) ([]byte,error) { - data = strings.Replace(data, "-", "+", -1) // 62nd char of encoding - data = strings.Replace(data, "_", "/", -1) // 63rd char of encoding - - switch(len(data) % 4) { // Pad with trailing '='s - case 0: // no padding - case 2: data+="==" // 2 pad chars - case 3: data+="=" // 1 pad char - } - - return base64.StdEncoding.DecodeString(data) -} - -// Encode encodes given byte array to base64url string -func Encode(data []byte) string { - result := base64.StdEncoding.EncodeToString(data) - result = strings.Replace(result, "+", "-", -1) // 62nd char of encoding - result = strings.Replace(result, "/", "_", -1) // 63rd char of encoding - result = strings.Replace(result, "=", "", -1) // Remove any trailing '='s - - return result -} \ No newline at end of file diff --git a/vendor/github.com/dvsekhvalnov/jose2go/compact/compact.go b/vendor/github.com/dvsekhvalnov/jose2go/compact/compact.go deleted file mode 100644 index 1e9dd2f..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/compact/compact.go +++ /dev/null @@ -1,33 +0,0 @@ -// package compact provides function to work with json compact serialization format -package compact - -import ( - "github.com/dvsekhvalnov/jose2go/base64url" - "strings" -) - -// Parse splitting & decoding compact serialized json web token, returns slice of byte arrays, each representing part of token -func Parse(token string) (result [][]byte, e error) { - parts := strings.Split(token, ".") - - result = make([][]byte, len(parts)) - - for i, part := range parts { - if result[i], e = base64url.Decode(part); e != nil { - return nil, e - } - } - - return result, nil -} - -// Serialize converts given parts into compact serialization format -func Serialize(parts ...[]byte) string { - result := make([]string, len(parts)) - - for i, part := range parts { - result[i] = base64url.Encode(part) - } - - return strings.Join(result, ".") -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/deflate.go b/vendor/github.com/dvsekhvalnov/jose2go/deflate.go deleted file mode 100644 index c788f5b..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/deflate.go +++ /dev/null @@ -1,39 +0,0 @@ -package jose - -import ( - "bytes" - "compress/flate" - "io/ioutil" -) - -func init() { - RegisterJwc(new(Deflate)) -} - -// Deflate compression algorithm implementation -type Deflate struct {} - -func (alg *Deflate) Name() string { - return DEF -} - -func (alg *Deflate) Compress(plainText []byte) []byte { - var buf bytes.Buffer - deflate,_ := flate.NewWriter(&buf, 8) //level=DEFLATED - - deflate.Write(plainText) - deflate.Close() - - return buf.Bytes() -} - -func (alg *Deflate) Decompress(compressedText []byte) []byte { - - enflated,_ := ioutil.ReadAll( - flate.NewReader( - bytes.NewReader(compressedText))) - - return enflated -} - - diff --git a/vendor/github.com/dvsekhvalnov/jose2go/direct.go b/vendor/github.com/dvsekhvalnov/jose2go/direct.go deleted file mode 100644 index 51f0a2f..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/direct.go +++ /dev/null @@ -1,39 +0,0 @@ -package jose - -import ( - "errors" -) - -func init() { - RegisterJwa(new(Direct)) -} - -// Direct (pre-shared) key management algorithm implementation -type Direct struct{ -} - -func (alg *Direct) Name() string { - return DIR -} - -func (alg *Direct) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) { - - if cek,ok:=key.([]byte); ok { - return cek,[]byte{},nil - } - - return nil,nil,errors.New("Direct.WrapNewKey(): expected key to be '[]byte' array") -} - -func (alg *Direct) Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) { - - if(len(encryptedCek)!=0) { - return nil, errors.New("Direct.Unwrap(): expected empty encrypted CEK") - } - - if cek,ok:=key.([]byte); ok { - return cek,nil - } - - return nil,errors.New("Direct.Unwrap(): expected key to be '[]byte' array") -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/ecdh.go b/vendor/github.com/dvsekhvalnov/jose2go/ecdh.go deleted file mode 100644 index c3512fb..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/ecdh.go +++ /dev/null @@ -1,157 +0,0 @@ -package jose - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/sha256" - "errors" - "fmt" - "github.com/dvsekhvalnov/jose2go/arrays" - "github.com/dvsekhvalnov/jose2go/base64url" - "github.com/dvsekhvalnov/jose2go/kdf" - "github.com/dvsekhvalnov/jose2go/keys/ecc" - "github.com/dvsekhvalnov/jose2go/padding" - "math/big" -) - -func init() { - RegisterJwa(&Ecdh{directAgreement: true}) -} - -// Elliptic curve Diffie–Hellman key management (key agreement) algorithm implementation -type Ecdh struct { - directAgreement bool -} - -func (alg *Ecdh) Name() string { - return ECDH_ES -} - -func (alg *Ecdh) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) { - - if pubKey, ok := key.(*ecdsa.PublicKey); ok { - - if _, ok := header[alg.idHeader()].(string); !ok { - return nil, nil, errors.New(fmt.Sprintf("Ecdh.WrapNewKey(): expected '%v' param in JWT header, but was not found.", alg.idHeader())) - } - - var d []byte - var x, y *big.Int - - if d, x, y, err = elliptic.GenerateKey(pubKey.Curve, rand.Reader); err != nil { - return nil, nil, err - } - - ephemeral := ecc.NewPrivate(x.Bytes(), y.Bytes(), d) - - xBytes := padding.Align(x.Bytes(), pubKey.Curve.Params().BitSize) - yBytes := padding.Align(y.Bytes(), pubKey.Curve.Params().BitSize) - - epk := map[string]string{ - "kty": "EC", - "x": base64url.Encode(xBytes), - "y": base64url.Encode(yBytes), - "crv": name(pubKey.Curve), - } - - header["epk"] = epk - - return alg.deriveKey(pubKey, ephemeral, cekSizeBits, header), nil, nil - } - - return nil, nil, errors.New("Ecdh.WrapNewKey(): expected key to be '*ecdsa.PublicKey'") -} - -func (alg *Ecdh) Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) { - - if privKey, ok := key.(*ecdsa.PrivateKey); ok { - - var epk map[string]interface{} - - if epk, ok = header["epk"].(map[string]interface{}); !ok { - return nil, errors.New("Ecdh.Unwrap(): expected 'epk' param in JWT header, but was not found.") - } - - if _, ok := header[alg.idHeader()].(string); !ok { - return nil, errors.New(fmt.Sprintf("Ecdh.Unwrap(): expected '%v' param in JWT header, but was not found.", alg.idHeader())) - } - - var x, y, crv string - var xBytes, yBytes []byte - - if x, ok = epk["x"].(string); !ok { - return nil, errors.New("Ecdh.Unwrap(): expects 'epk' key to contain 'x','y' and 'crv' fields, but 'x' was not found.") - } - - if y, ok = epk["y"].(string); !ok { - return nil, errors.New("Ecdh.Unwrap(): expects 'epk' key to contain 'x','y' and 'crv' fields, but 'y' was not found.") - } - - if crv, ok = epk["crv"].(string); !ok { - return nil, errors.New("Ecdh.Unwrap(): expects 'epk' key to contain 'x','y' and 'crv' fields, but 'crv' was not found.") - } - - if crv != "P-256" && crv != "P-384" && crv != "P-521" { - return nil, errors.New(fmt.Sprintf("Ecdh.Unwrap(): unknown or unsupported curve %v", crv)) - } - - if xBytes, err = base64url.Decode(x); err != nil { - return nil, err - } - if yBytes, err = base64url.Decode(y); err != nil { - return nil, err - } - - pubKey := ecc.NewPublic(xBytes, yBytes) - - if !privKey.Curve.IsOnCurve(pubKey.X, pubKey.Y) { - return nil, errors.New(fmt.Sprintf("Ephemeral public key received in header is invalid for reciever's private key.")) - } - - return alg.deriveKey(pubKey, privKey, cekSizeBits, header), nil - } - - return nil, errors.New("Ecdh.Unwrap(): expected key to be '*ecdsa.PrivateKey'") -} - -func (alg *Ecdh) deriveKey(pubKey *ecdsa.PublicKey, privKey *ecdsa.PrivateKey, keySizeBits int, header map[string]interface{}) []byte { - - var enc, apv, apu []byte - var err error - - enc = []byte(header[alg.idHeader()].(string)) - - if a, ok := header["apv"].(string); !ok { - if apv, err = base64url.Decode(a); err != nil { - apv = nil - } - } - - if a, ok := header["apu"].(string); !ok { - if apu, err = base64url.Decode(a); err != nil { - apu = nil - } - } - - z, _ := pubKey.Curve.ScalarMult(pubKey.X, pubKey.Y, privKey.D.Bytes()) - zBytes := padding.Align(z.Bytes(), privKey.Curve.Params().BitSize) - - return kdf.DeriveConcatKDF(keySizeBits, zBytes, prependDatalen(enc), prependDatalen(apu), prependDatalen(apv), arrays.UInt32ToBytes(uint32(keySizeBits)), nil, sha256.New()) -} - -func (alg *Ecdh) idHeader() string { - if alg.directAgreement { - return "enc" - } - - return "alg" -} - -func name(curve elliptic.Curve) string { - return fmt.Sprintf("P-%v", curve.Params().BitSize) -} - -func prependDatalen(bytes []byte) []byte { - return arrays.Concat(arrays.UInt32ToBytes(uint32(len(bytes))), bytes) -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/ecdh_aeskw.go b/vendor/github.com/dvsekhvalnov/jose2go/ecdh_aeskw.go deleted file mode 100644 index bff3480..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/ecdh_aeskw.go +++ /dev/null @@ -1,42 +0,0 @@ -package jose - -func init() { - RegisterJwa(&EcdhAesKW{ keySizeBits: 128, aesKW: &AesKW{ keySizeBits: 128}, ecdh: &Ecdh{directAgreement:false}}) - RegisterJwa(&EcdhAesKW{ keySizeBits: 192, aesKW: &AesKW{ keySizeBits: 192}, ecdh: &Ecdh{directAgreement:false}}) - RegisterJwa(&EcdhAesKW{ keySizeBits: 256, aesKW: &AesKW{ keySizeBits: 256}, ecdh: &Ecdh{directAgreement:false}}) -} - -// Elliptic curve Diffie–Hellman with AES Key Wrap key management algorithm implementation -type EcdhAesKW struct{ - keySizeBits int - aesKW JwaAlgorithm - ecdh JwaAlgorithm -} - -func (alg *EcdhAesKW) Name() string { - switch alg.keySizeBits { - case 128: return ECDH_ES_A128KW - case 192: return ECDH_ES_A192KW - default: return ECDH_ES_A256KW - } -} - -func (alg *EcdhAesKW) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) { - var kek []byte - - if kek,_,err=alg.ecdh.WrapNewKey(alg.keySizeBits, key, header);err!=nil { - return nil,nil,err - } - - return alg.aesKW.WrapNewKey(cekSizeBits,kek,header) -} - -func (alg *EcdhAesKW) Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) { - var kek []byte - - if kek,err=alg.ecdh.Unwrap(nil, key, alg.keySizeBits, header);err!=nil { - return nil,err - } - - return alg.aesKW.Unwrap(encryptedCek,kek,cekSizeBits,header) -} \ No newline at end of file diff --git a/vendor/github.com/dvsekhvalnov/jose2go/ecdsa_using_sha.go b/vendor/github.com/dvsekhvalnov/jose2go/ecdsa_using_sha.go deleted file mode 100644 index 23ac6ee..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/ecdsa_using_sha.go +++ /dev/null @@ -1,76 +0,0 @@ -package jose - -import ( - "crypto/rand" - "math/big" - "crypto/ecdsa" - "errors" - "github.com/dvsekhvalnov/jose2go/arrays" - "github.com/dvsekhvalnov/jose2go/padding" - "fmt" -) - -func init() { - RegisterJws(&EcdsaUsingSha{keySizeBits: 256, hashSizeBits: 256}) - RegisterJws(&EcdsaUsingSha{keySizeBits: 384, hashSizeBits: 384}) - RegisterJws(&EcdsaUsingSha{keySizeBits: 521, hashSizeBits: 512}) -} - -// ECDSA signing algorithm implementation -type EcdsaUsingSha struct{ - keySizeBits int - hashSizeBits int -} - -func (alg *EcdsaUsingSha) Name() string { - switch alg.keySizeBits { - case 256: return ES256 - case 384: return ES384 - default: return ES512 - } -} - -func (alg *EcdsaUsingSha) Verify(securedInput, signature []byte, key interface{}) error { - - if pubKey,ok:=key.(*ecdsa.PublicKey);ok { - - if sizeBits:=pubKey.Curve.Params().BitSize;sizeBits!=alg.keySizeBits { - return errors.New(fmt.Sprintf("EcdsaUsingSha.Verify(): expected key of size %v bits, but was given %v bits.",alg.keySizeBits,sizeBits)) - } - - r:=new(big.Int).SetBytes(signature[:len(signature)/2]) - s:=new(big.Int).SetBytes(signature[len(signature)/2:]) - - if ok:=ecdsa.Verify(pubKey, sha(alg.hashSizeBits, securedInput), r,s); ok { - return nil - } - - return errors.New("EcdsaUsingSha.Verify(): Signature is not valid.") - } - - return errors.New("EcdsaUsingSha.Verify(): expects key to be '*ecdsa.PublicKey'") -} - -func (alg *EcdsaUsingSha) Sign(securedInput []byte, key interface{}) (signature []byte, err error) { - - if privKey,ok := key.(*ecdsa.PrivateKey);ok { - - if sizeBits:=privKey.Curve.Params().BitSize;sizeBits!=alg.keySizeBits { - return nil,errors.New(fmt.Sprintf("EcdsaUsingSha.Sign(): expected key of size %v bits, but was given %v bits.",alg.keySizeBits,sizeBits)) - } - - var r,s *big.Int - - if r,s,err = ecdsa.Sign(rand.Reader, privKey, sha(alg.hashSizeBits, securedInput));err==nil { - - rBytes:=padding.Align(r.Bytes(), alg.keySizeBits) - sBytes:=padding.Align(s.Bytes(), alg.keySizeBits) - - return arrays.Concat(rBytes,sBytes),nil - } - - return nil, err - } - - return nil,errors.New("EcdsaUsingSha.Sign(): expects key to be '*ecdsa.PrivateKey'") -} \ No newline at end of file diff --git a/vendor/github.com/dvsekhvalnov/jose2go/hmac.go b/vendor/github.com/dvsekhvalnov/jose2go/hmac.go deleted file mode 100644 index d3726b7..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/hmac.go +++ /dev/null @@ -1,13 +0,0 @@ -package jose - -import ( - "crypto/hmac" - "hash" -) - -func calculateHmac(keySizeBits int, securedInput []byte, key []byte) []byte { - hasher := hmac.New(func() hash.Hash { return hashAlg(keySizeBits)}, key) - hasher.Write(securedInput) - - return hasher.Sum(nil) -} \ No newline at end of file diff --git a/vendor/github.com/dvsekhvalnov/jose2go/hmac_using_sha.go b/vendor/github.com/dvsekhvalnov/jose2go/hmac_using_sha.go deleted file mode 100644 index e0b664f..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/hmac_using_sha.go +++ /dev/null @@ -1,46 +0,0 @@ -package jose - -import ( - "crypto/hmac" - "errors" -) - -func init() { - RegisterJws(&HmacUsingSha{keySizeBits: 256}) - RegisterJws(&HmacUsingSha{keySizeBits: 384}) - RegisterJws(&HmacUsingSha{keySizeBits: 512}) -} - -// HMAC with SHA signing algorithm implementation -type HmacUsingSha struct{ - keySizeBits int -} - -func (alg *HmacUsingSha) Name() string { - switch alg.keySizeBits { - case 256: return HS256 - case 384: return HS384 - default: return HS512 - } -} - -func (alg *HmacUsingSha) Verify(securedInput, signature []byte, key interface{}) error { - - actualSig,_ := alg.Sign(securedInput, key) - - if !hmac.Equal(signature, actualSig) { - return errors.New("HmacUsingSha.Verify(): Signature is invalid") - } - - return nil -} - -func (alg *HmacUsingSha) Sign(securedInput []byte, key interface{}) (signature []byte, err error) { - //TODO: assert min key size - - if pubKey,ok:=key.([]byte); ok { - return calculateHmac(alg.keySizeBits, securedInput, pubKey),nil - } - - return nil,errors.New("HmacUsingSha.Sign(): expects key to be '[]byte' array") -} \ No newline at end of file diff --git a/vendor/github.com/dvsekhvalnov/jose2go/jose.go b/vendor/github.com/dvsekhvalnov/jose2go/jose.go deleted file mode 100644 index 1f1c19e..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/jose.go +++ /dev/null @@ -1,424 +0,0 @@ -//Package jose provides high level functions for producing (signing, encrypting and -// compressing) or consuming (decoding) Json Web Tokens using Java Object Signing and Encryption spec -package jose - -import ( - "encoding/json" - "errors" - "fmt" - - "github.com/dvsekhvalnov/jose2go/compact" -) - -const ( - NONE = "none" //plaintext (unprotected) without signature / encryption - - HS256 = "HS256" //HMAC using SHA-256 hash - HS384 = "HS384" //HMAC using SHA-384 hash - HS512 = "HS512" //HMAC using SHA-512 hash - RS256 = "RS256" //RSASSA-PKCS-v1_5 using SHA-256 hash - RS384 = "RS384" //RSASSA-PKCS-v1_5 using SHA-384 hash - RS512 = "RS512" //RSASSA-PKCS-v1_5 using SHA-512 hash - PS256 = "PS256" //RSASSA-PSS using SHA-256 hash - PS384 = "PS384" //RSASSA-PSS using SHA-384 hash - PS512 = "PS512" //RSASSA-PSS using SHA-512 hash - ES256 = "ES256" //ECDSA using P-256 curve and SHA-256 hash - ES384 = "ES384" //ECDSA using P-384 curve and SHA-384 hash - ES512 = "ES512" //ECDSA using P-521 curve and SHA-512 hash - - A128CBC_HS256 = "A128CBC-HS256" //AES in CBC mode with PKCS #5 (NIST.800-38A) padding with HMAC using 256 bit key - A192CBC_HS384 = "A192CBC-HS384" //AES in CBC mode with PKCS #5 (NIST.800-38A) padding with HMAC using 384 bit key - A256CBC_HS512 = "A256CBC-HS512" //AES in CBC mode with PKCS #5 (NIST.800-38A) padding with HMAC using 512 bit key - A128GCM = "A128GCM" //AES in GCM mode with 128 bit key - A192GCM = "A192GCM" //AES in GCM mode with 192 bit key - A256GCM = "A256GCM" //AES in GCM mode with 256 bit key - - DIR = "dir" //Direct use of pre-shared symmetric key - RSA1_5 = "RSA1_5" //RSAES with PKCS #1 v1.5 padding, RFC 3447 - RSA_OAEP = "RSA-OAEP" //RSAES using Optimal Assymetric Encryption Padding, RFC 3447 - RSA_OAEP_256 = "RSA-OAEP-256" //RSAES using Optimal Assymetric Encryption Padding with SHA-256, RFC 3447 - A128KW = "A128KW" //AES Key Wrap Algorithm using 128 bit keys, RFC 3394 - A192KW = "A192KW" //AES Key Wrap Algorithm using 192 bit keys, RFC 3394 - A256KW = "A256KW" //AES Key Wrap Algorithm using 256 bit keys, RFC 3394 - A128GCMKW = "A128GCMKW" //AES GCM Key Wrap Algorithm using 128 bit keys - A192GCMKW = "A192GCMKW" //AES GCM Key Wrap Algorithm using 192 bit keys - A256GCMKW = "A256GCMKW" //AES GCM Key Wrap Algorithm using 256 bit keys - PBES2_HS256_A128KW = "PBES2-HS256+A128KW" //Password Based Encryption using PBES2 schemes with HMAC-SHA and AES Key Wrap using 128 bit key - PBES2_HS384_A192KW = "PBES2-HS384+A192KW" //Password Based Encryption using PBES2 schemes with HMAC-SHA and AES Key Wrap using 192 bit key - PBES2_HS512_A256KW = "PBES2-HS512+A256KW" //Password Based Encryption using PBES2 schemes with HMAC-SHA and AES Key Wrap using 256 bit key - ECDH_ES = "ECDH-ES" //Elliptic Curve Diffie Hellman key agreement - ECDH_ES_A128KW = "ECDH-ES+A128KW" //Elliptic Curve Diffie Hellman key agreement with AES Key Wrap using 128 bit key - ECDH_ES_A192KW = "ECDH-ES+A192KW" //Elliptic Curve Diffie Hellman key agreement with AES Key Wrap using 192 bit key - ECDH_ES_A256KW = "ECDH-ES+A256KW" //Elliptic Curve Diffie Hellman key agreement with AES Key Wrap using 256 bit key - - DEF = "DEF" //DEFLATE compression, RFC 1951 -) - -var jwsHashers = map[string]JwsAlgorithm{} -var jweEncryptors = map[string]JweEncryption{} -var jwaAlgorithms = map[string]JwaAlgorithm{} -var jwcCompressors = map[string]JwcAlgorithm{} - -// RegisterJwe register new encryption algorithm -func RegisterJwe(alg JweEncryption) { - jweEncryptors[alg.Name()] = alg -} - -// RegisterJwa register new key management algorithm -func RegisterJwa(alg JwaAlgorithm) { - jwaAlgorithms[alg.Name()] = alg -} - -// RegisterJws register new signing algorithm -func RegisterJws(alg JwsAlgorithm) { - jwsHashers[alg.Name()] = alg -} - -// RegisterJwc register new compression algorithm -func RegisterJwc(alg JwcAlgorithm) { - jwcCompressors[alg.Name()] = alg -} - -// JweEncryption is a contract for implementing encryption algorithm -type JweEncryption interface { - Encrypt(aad, plainText, cek []byte) (iv, cipherText, authTag []byte, err error) - Decrypt(aad, cek, iv, cipherText, authTag []byte) (plainText []byte, err error) - KeySizeBits() int - Name() string -} - -// JwaAlgorithm is a contract for implementing key management algorithm -type JwaAlgorithm interface { - WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) - Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) - Name() string -} - -// JwsAlgorithm is a contract for implementing signing algorithm -type JwsAlgorithm interface { - Verify(securedInput, signature []byte, key interface{}) error - Sign(securedInput []byte, key interface{}) (signature []byte, err error) - Name() string -} - -// JwcAlgorithm is a contract for implementing compression algorithm -type JwcAlgorithm interface { - Compress(plainText []byte) []byte - Decompress(compressedText []byte) []byte - Name() string -} - -func Zip(alg string) func(cfg *JoseConfig) { - return func(cfg *JoseConfig) { - cfg.CompressionAlg = alg - } -} - -func Header(name string, value interface{}) func(cfg *JoseConfig) { - return func(cfg *JoseConfig) { - cfg.Headers[name] = value - } -} - -func Headers(headers map[string]interface{}) func(cfg *JoseConfig) { - return func(cfg *JoseConfig) { - for k, v := range headers { - cfg.Headers[k] = v - } - } -} - -type JoseConfig struct { - CompressionAlg string - Headers map[string]interface{} -} - -// Sign produces signed JWT token given arbitrary string payload, signature algorithm to use (see constants for list of supported algs), signing key and extra options (see option functions) -// Signing key is of different type for different signing alg, see specific -// signing alg implementation documentation. -// -// It returns 3 parts signed JWT token as string and not nil error if something went wrong. -func Sign(payload string, signingAlg string, key interface{}, options ...func(*JoseConfig)) (token string, err error) { - return SignBytes([]byte(payload), signingAlg, key, options...) -} - -// Sign produces signed JWT token given arbitrary binary payload, signature algorithm to use (see constants for list of supported algs), signing key and extra options (see option functions) -// Signing key is of different type for different signing alg, see specific -// signing alg implementation documentation. -// -// It returns 3 parts signed JWT token as string and not nil error if something went wrong. -func SignBytes(payload []byte, signingAlg string, key interface{}, options ...func(*JoseConfig)) (token string, err error) { - if signer, ok := jwsHashers[signingAlg]; ok { - - cfg := &JoseConfig{CompressionAlg: "", Headers: make(map[string]interface{})} - - //apply extra options - for _, option := range options { - option(cfg) - } - - //make sure defaults and requires are managed by us - cfg.Headers["alg"] = signingAlg - - paloadBytes := payload - var header []byte - var signature []byte - - if header, err = json.Marshal(cfg.Headers); err == nil { - securedInput := []byte(compact.Serialize(header, paloadBytes)) - - if signature, err = signer.Sign(securedInput, key); err == nil { - return compact.Serialize(header, paloadBytes, signature), nil - } - } - - return "", err - } - - return "", errors.New(fmt.Sprintf("jwt.Sign(): unknown algorithm: '%v'", signingAlg)) -} - -// Encrypt produces encrypted JWT token given arbitrary string payload, key management and encryption algorithms to use (see constants for list of supported algs) and management key. -// Management key is of different type for different key management alg, see specific -// key management alg implementation documentation. -// -// It returns 5 parts encrypted JWT token as string and not nil error if something went wrong. -func Encrypt(payload string, alg string, enc string, key interface{}, options ...func(*JoseConfig)) (token string, err error) { - return EncryptBytes([]byte(payload), alg, enc, key, options...) -} - -// Encrypt produces encrypted JWT token given arbitrary binary payload, key management and encryption algorithms to use (see constants for list of supported algs) and management key. -// Management key is of different type for different key management alg, see specific -// key management alg implementation documentation. -// -// It returns 5 parts encrypted JWT token as string and not nil error if something went wrong. -func EncryptBytes(payload []byte, alg string, enc string, key interface{}, options ...func(*JoseConfig)) (token string, err error) { - - cfg := &JoseConfig{CompressionAlg: "", Headers: make(map[string]interface{})} - - //apply extra options - for _, option := range options { - option(cfg) - } - - //make sure required headers are managed by us - cfg.Headers["alg"] = alg - cfg.Headers["enc"] = enc - - byteContent := payload - - if cfg.CompressionAlg != "" { - if zipAlg, ok := jwcCompressors[cfg.CompressionAlg]; ok { - byteContent = zipAlg.Compress([]byte(payload)) - cfg.Headers["zip"] = cfg.CompressionAlg - } else { - return "", errors.New(fmt.Sprintf("jwt.Compress(): Unknown compression method '%v'", cfg.CompressionAlg)) - } - - } else { - delete(cfg.Headers, "zip") //we not allow to manage 'zip' header manually for encryption - } - - return encrypt(byteContent, cfg.Headers, key) -} - -// This method is DEPRICATED and subject to be removed in next version. -// Use Encrypt(..) with Zip option instead. -// -// Compress produces encrypted & comressed JWT token given arbitrary payload, key management , encryption and compression algorithms to use (see constants for list of supported algs) and management key. -// Management key is of different type for different key management alg, see specific -// key management alg implementation documentation. -// -// It returns 5 parts encrypted & compressed JWT token as string and not nil error if something went wrong. -func Compress(payload string, alg string, enc string, zip string, key interface{}) (token string, err error) { - - if zipAlg, ok := jwcCompressors[zip]; ok { - compressed := zipAlg.Compress([]byte(payload)) - - jwtHeader := map[string]interface{}{ - "enc": enc, - "alg": alg, - "zip": zip, - } - - return encrypt(compressed, jwtHeader, key) - } - - return "", errors.New(fmt.Sprintf("jwt.Compress(): Unknown compression method '%v'", zip)) -} - -// Decode verifies, decrypts and decompresses given JWT token using management key. -// Management key is of different type for different key management or signing algorithms, see specific alg implementation documentation. -// -// Returns decoded payload as a string, headers and not nil error if something went wrong. -func Decode(token string, key interface{}) (string, map[string]interface{}, error) { - - payload, headers, err := DecodeBytes(token, key) - - if err != nil { - return "", nil, err - } - - return string(payload), headers, nil -} - -// Decode verifies, decrypts and decompresses given JWT token using management key. -// Management key is of different type for different key management or signing algorithms, see specific alg implementation documentation. -// -// Returns decoded payload as a raw bytes, headers and not nil error if something went wrong. -func DecodeBytes(token string, key interface{}) ([]byte, map[string]interface{}, error) { - parts, err := compact.Parse(token) - - if err != nil { - return nil, nil, err - } - - if len(parts) == 3 { - return verify(parts, key) - } - - if len(parts) == 5 { - return decrypt(parts, key) - } - - return nil, nil, errors.New(fmt.Sprintf("jwt.DecodeBytes() expects token of 3 or 5 parts, but was given: %v parts", len(parts))) -} - -func encrypt(payload []byte, jwtHeader map[string]interface{}, key interface{}) (token string, err error) { - var ok bool - var keyMgmtAlg JwaAlgorithm - var encAlg JweEncryption - - alg := jwtHeader["alg"].(string) - enc := jwtHeader["enc"].(string) - - if keyMgmtAlg, ok = jwaAlgorithms[alg]; !ok { - return "", errors.New(fmt.Sprintf("jwt.encrypt(): Unknown key management algorithm '%v'", alg)) - } - - if encAlg, ok = jweEncryptors[enc]; !ok { - return "", errors.New(fmt.Sprintf("jwt.encrypt(): Unknown encryption algorithm '%v'", enc)) - } - - var cek, encryptedCek, header, iv, cipherText, authTag []byte - - if cek, encryptedCek, err = keyMgmtAlg.WrapNewKey(encAlg.KeySizeBits(), key, jwtHeader); err != nil { - return "", err - } - - if header, err = json.Marshal(jwtHeader); err != nil { - return "", err - } - - if iv, cipherText, authTag, err = encAlg.Encrypt([]byte(compact.Serialize(header)), payload, cek); err != nil { - return "", err - } - - return compact.Serialize(header, encryptedCek, iv, cipherText, authTag), nil -} - -func verify(parts [][]byte, key interface{}) (plainText []byte, headers map[string]interface{}, err error) { - - header, payload, signature := parts[0], parts[1], parts[2] - - secured := []byte(compact.Serialize(header, payload)) - - var jwtHeader map[string]interface{} - - if err = json.Unmarshal(header, &jwtHeader); err != nil { - return nil, nil, err - } - - if alg, ok := jwtHeader["alg"].(string); ok { - if verifier, ok := jwsHashers[alg]; ok { - if key, err = retrieveActualKey(jwtHeader, string(payload), key); err != nil { - return nil, nil, err - } - - if err = verifier.Verify(secured, signature, key); err == nil { - return payload, jwtHeader, nil - } - - return nil, nil, err - } - - return nil, nil, errors.New(fmt.Sprintf("jwt.Decode(): Unknown algorithm: '%v'", alg)) - } - - return nil, nil, errors.New(fmt.Sprint("jwt.Decode(): required 'alg' header is missing or of invalid type")) -} - -func decrypt(parts [][]byte, key interface{}) (plainText []byte, headers map[string]interface{}, err error) { - - header, encryptedCek, iv, cipherText, authTag := parts[0], parts[1], parts[2], parts[3], parts[4] - - var jwtHeader map[string]interface{} - - if e := json.Unmarshal(header, &jwtHeader); e != nil { - return nil, nil, e - } - - var keyMgmtAlg JwaAlgorithm - var encAlg JweEncryption - var zipAlg JwcAlgorithm - var cek, plainBytes []byte - var ok bool - var alg, enc string - - if alg, ok = jwtHeader["alg"].(string); !ok { - return nil, nil, errors.New(fmt.Sprint("jwt.Decode(): required 'alg' header is missing or of invalid type")) - } - - if enc, ok = jwtHeader["enc"].(string); !ok { - return nil, nil, errors.New(fmt.Sprint("jwt.Decode(): required 'enc' header is missing or of invalid type")) - } - - aad := []byte(compact.Serialize(header)) - - if keyMgmtAlg, ok = jwaAlgorithms[alg]; ok { - if encAlg, ok = jweEncryptors[enc]; ok { - - if key, err = retrieveActualKey(jwtHeader, string(cipherText), key); err != nil { - return nil, nil, err - } - - if cek, err = keyMgmtAlg.Unwrap(encryptedCek, key, encAlg.KeySizeBits(), jwtHeader); err == nil { - if plainBytes, err = encAlg.Decrypt(aad, cek, iv, cipherText, authTag); err == nil { - - if zip, compressed := jwtHeader["zip"].(string); compressed { - - if zipAlg, ok = jwcCompressors[zip]; !ok { - return nil, nil, errors.New(fmt.Sprintf("jwt.decrypt(): Unknown compression algorithm '%v'", zip)) - } - - plainBytes = zipAlg.Decompress(plainBytes) - } - - return plainBytes, jwtHeader, nil - } - - return nil, nil, err - } - - return nil, nil, err - } - - return nil, nil, errors.New(fmt.Sprintf("jwt.decrypt(): Unknown encryption algorithm '%v'", enc)) - } - - return nil, nil, errors.New(fmt.Sprintf("jwt.decrypt(): Unknown key management algorithm '%v'", alg)) -} - -func retrieveActualKey(headers map[string]interface{}, payload string, key interface{}) (interface{}, error) { - if keyCallback, ok := key.(func(headers map[string]interface{}, payload string) interface{}); ok { - result := keyCallback(headers, payload) - - if err, ok := result.(error); ok { - return nil, err - } - - return result, nil - } - - return key, nil -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/kdf/nist_sp800_56a.go b/vendor/github.com/dvsekhvalnov/jose2go/kdf/nist_sp800_56a.go deleted file mode 100644 index dd76790..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/kdf/nist_sp800_56a.go +++ /dev/null @@ -1,43 +0,0 @@ -package kdf - -import ( - "hash" - "math" - "github.com/dvsekhvalnov/jose2go/arrays" -) - -const ( - MaxInt = int(^uint(0)>>1); -) - -// DeriveConcatKDF implements NIST SP 800-56A Concatenation Key Derivation Function. Derives -// key material of keydatalen bits size given Z (sharedSecret), OtherInfo (AlgorithmID | -// PartyUInfo | PartyVInfo | SuppPubInfo | SuppPrivInfo) and hash function -func DeriveConcatKDF(keydatalen int, sharedSecret, algId, partyUInfo, partyVInfo, suppPubInfo, suppPrivInfo []byte, h hash.Hash) []byte { - - otherInfo := arrays.Concat(algId, partyUInfo, partyVInfo, suppPubInfo, suppPrivInfo) - - keyLenBytes := keydatalen >> 3 - - reps := int(math.Ceil(float64(keyLenBytes) / float64(h.Size()))) - - if reps > MaxInt { - panic("kdf.DeriveConcatKDF: too much iterations (more than 2^32-1).") - } - - dk:=make([]byte, 0, keyLenBytes) - - for counter := 1;counter <= reps;counter++ { - h.Reset() - - counterBytes:=arrays.UInt32ToBytes(uint32(counter)) - - h.Write(counterBytes) - h.Write(sharedSecret) - h.Write(otherInfo) - - dk = h.Sum(dk) - } - - return dk[:keyLenBytes] -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/kdf/pbkdf2.go b/vendor/github.com/dvsekhvalnov/jose2go/kdf/pbkdf2.go deleted file mode 100644 index aec58e7..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/kdf/pbkdf2.go +++ /dev/null @@ -1,63 +0,0 @@ -// package kdf contains implementations of various key derivation functions -package kdf - -import ( - "crypto/hmac" - "fmt" - "hash" - "math" - - "github.com/dvsekhvalnov/jose2go/arrays" -) - -// DerivePBKDF2 implements Password Based Key Derivation Function 2, RFC 2898. Derives key of keyBitLength size, given password, salt, iteration count and hash function -func DerivePBKDF2(password, salt []byte, iterationCount, keyBitLength int, h func() hash.Hash) []byte { - - prf := hmac.New(h, password) - hLen := prf.Size() - dkLen := keyBitLength >> 3 //size of derived key in bytes - - l := int(math.Ceil(float64(dkLen) / float64(hLen))) // l = CEIL (dkLen / hLen) - r := dkLen - (l-1)*hLen - - // 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and stop. - if dkLen > MaxInt { - panic(fmt.Sprintf("kdf.DerivePBKDF2: expects derived key size to be not more that (2^32-1) bits, but was requested %v bits.", keyBitLength)) - } - - dk := make([]byte, 0, dkLen) - - for i := 0; i < l; i++ { - - t := f(salt, iterationCount, i+1, prf) // T_l = F (P, S, c, l) - - if i == (l - 1) { - t = t[:r] - } // truncate last block to r bits - - dk = append(dk, t...) // DK = T_1 || T_2 || ... || T_l<0..r-1> - } - - return dk -} - -func f(salt []byte, iterationCount, blockIndex int, prf hash.Hash) []byte { - - prf.Reset() - prf.Write(salt) - prf.Write(arrays.UInt32ToBytes(uint32(blockIndex))) - - u := prf.Sum(nil) // U_1 = PRF (P, S || INT (i)) - - result := u - - for i := 2; i <= iterationCount; i++ { - prf.Reset() - prf.Write(u) - - u = prf.Sum(nil) // U_c = PRF (P, U_{c-1}) . - result = arrays.Xor(result, u) // U_1 \xor U_2 \xor ... \xor U_c - } - - return result -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ec_cert.pem b/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ec_cert.pem deleted file mode 100644 index 384cb46..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ec_cert.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICJjCCAc6gAwIBAgIJAOCtH/xv+cfpMAkGByqGSM49BAEwRTELMAkGA1UEBhMC -QVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdp -dHMgUHR5IEx0ZDAeFw0xNDA4MTIxMTU5MTVaFw0xODA1MDgxMTU5MTVaMEUxCzAJ -BgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5l -dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASqGi1p -Eudyh+Nw//zeAGIYSQG/H/q/x6Xz2TIg3GN4hbD5BS1f4/vEitpui+TpmtJyggzo -x5D55N9kjq0X/hyyo4GnMIGkMB0GA1UdDgQWBBQvGSEecx9JdDECRIorVpeWy7oA -ujB1BgNVHSMEbjBsgBQvGSEecx9JdDECRIorVpeWy7oAuqFJpEcwRTELMAkGA1UE -BhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdp -ZGdpdHMgUHR5IEx0ZIIJAOCtH/xv+cfpMAwGA1UdEwQFMAMBAf8wCQYHKoZIzj0E -AQNHADBEAiAUQheZrGjbsy6PfpWGZEhTFzqvBVXtbqtz+6aTkOCrCQIgLfvw9C+0 -SDn/abV4NtgYOM0OLkoNRTCIzzguHxhhaJ4= ------END CERTIFICATE----- diff --git a/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ec_private.key b/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ec_private.key deleted file mode 100644 index 399b84b..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ec_private.key +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN EC PRIVATE KEY----- -MHcCAQEEIA/32XgQpS/tKRhw8jSdr8ivBmMyD/vbG5KT3s3XPArcoAoGCCqGSM49 -AwEHoUQDQgAEqhotaRLncofjcP/83gBiGEkBvx/6v8el89kyINxjeIWw+QUtX+P7 -xIrabovk6ZrScoIM6MeQ+eTfZI6tF/4csg== ------END EC PRIVATE KEY----- diff --git a/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ec_private.pem b/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ec_private.pem deleted file mode 100644 index 5247be2..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ec_private.pem +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgD/fZeBClL+0pGHDy -NJ2vyK8GYzIP+9sbkpPezdc8CtyhRANCAASqGi1pEudyh+Nw//zeAGIYSQG/H/q/ -x6Xz2TIg3GN4hbD5BS1f4/vEitpui+TpmtJyggzox5D55N9kjq0X/hyy ------END PRIVATE KEY----- diff --git a/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ec_public.key b/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ec_public.key deleted file mode 100644 index bc2345d..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ec_public.key +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqhotaRLncofjcP/83gBiGEkBvx/6 -v8el89kyINxjeIWw+QUtX+P7xIrabovk6ZrScoIM6MeQ+eTfZI6tF/4csg== ------END PUBLIC KEY----- diff --git a/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ecc.go b/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ecc.go deleted file mode 100644 index b1debe4..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/keys/ecc/ecc.go +++ /dev/null @@ -1,88 +0,0 @@ -//package ecc provides helpers for creating elliptic curve leys -package ecc - -import ( - "math/big" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/x509" - "encoding/pem" - "errors" -) - -// ReadPublic loads ecdsa.PublicKey from given PKCS1 X509 or PKIX blobs -func ReadPublic(raw []byte) (key *ecdsa.PublicKey,err error) { - var encoded *pem.Block - - if encoded, _ = pem.Decode(raw); encoded == nil { - return nil, errors.New("Ecc.ReadPublic(): Key must be PEM encoded PKCS1 X509 certificate or PKIX EC public key") - } - - var parsedKey interface{} - var cert *x509.Certificate - - if parsedKey, err = x509.ParsePKIXPublicKey(encoded.Bytes); err != nil { - if cert,err = x509.ParseCertificate(encoded.Bytes);err!=nil { - return nil, err - } - - parsedKey=cert.PublicKey - } - - var ok bool - - if key, ok = parsedKey.(*ecdsa.PublicKey); !ok { - return nil, errors.New("Ecc.ReadPublic(): Key is not a valid *ecdsa.PublicKey") - } - - return key, nil -} - -// ReadPrivate loads ecdsa.PrivateKey from given PKCS1 or PKCS8 blobs -func ReadPrivate(raw []byte) (key *ecdsa.PrivateKey,err error) { - var encoded *pem.Block - - if encoded, _ = pem.Decode(raw); encoded == nil { - return nil, errors.New("Ecc.ReadPrivate(): Key must be PEM encoded PKCS1 or PKCS8 EC private key") - } - - var parsedKey interface{} - - if parsedKey,err=x509.ParseECPrivateKey(encoded.Bytes);err!=nil { - if parsedKey, err = x509.ParsePKCS8PrivateKey(encoded.Bytes);err!=nil { - return nil,err - } - } - - var ok bool - - if key,ok=parsedKey.(*ecdsa.PrivateKey);!ok { - return nil, errors.New("Ecc.ReadPrivate(): Key is not valid *ecdsa.PrivateKey") - } - - return key,nil -} - -// NewPublic constructs ecdsa.PublicKey from given (X,Y) -func NewPublic(x,y []byte) (*ecdsa.PublicKey) { - return &ecdsa.PublicKey{ Curve: curve(len(x)), - X:new(big.Int).SetBytes(x), - Y:new(big.Int).SetBytes(y) } -} - -// NewPrivate constructs ecdsa.PrivateKey from given (X,Y) and D -func NewPrivate(x,y,d []byte) (*ecdsa.PrivateKey) { - return &ecdsa.PrivateKey {D:new(big.Int).SetBytes(d), - PublicKey: ecdsa.PublicKey{ Curve:curve(len(x)), - X:new(big.Int).SetBytes(x), - Y:new(big.Int).SetBytes(y)}} -} - -func curve(size int) (elliptic.Curve) { - switch size { - case 32: return elliptic.P256() - case 48: return elliptic.P384() - case 65,66: return elliptic.P521() //adjust for P-521 curve, which can be 65 or 66 bytes - default: return nil //unsupported curve - } -} \ No newline at end of file diff --git a/vendor/github.com/dvsekhvalnov/jose2go/padding/align.go b/vendor/github.com/dvsekhvalnov/jose2go/padding/align.go deleted file mode 100644 index 0ef601f..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/padding/align.go +++ /dev/null @@ -1,23 +0,0 @@ -// package padding provides various padding algorithms -package padding - -import ( - "bytes" -) - -// Align left pads given byte array with zeros till it have at least bitSize length. -func Align(data []byte, bitSize int) []byte { - - actual:=len(data) - required:=bitSize >> 3 - - if (bitSize % 8) > 0 { - required++ //extra byte if needed - } - - if (actual >= required) { - return data - } - - return append(bytes.Repeat([]byte{0}, required-actual), data...) -} \ No newline at end of file diff --git a/vendor/github.com/dvsekhvalnov/jose2go/padding/pkcs7.go b/vendor/github.com/dvsekhvalnov/jose2go/padding/pkcs7.go deleted file mode 100644 index 2f64e7e..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/padding/pkcs7.go +++ /dev/null @@ -1,38 +0,0 @@ -package padding - -import ( - "bytes" -) - -// AddPkcs7 pads given byte array using pkcs7 padding schema till it has blockSize length in bytes -func AddPkcs7(data []byte, blockSize int) []byte { - - var paddingCount int - - if paddingCount = blockSize - (len(data) % blockSize);paddingCount == 0 { - paddingCount=blockSize - } - - return append(data, bytes.Repeat([]byte{byte(paddingCount)}, paddingCount)...) -} - -// RemovePkcs7 removes pkcs7 padding from previously padded byte array -func RemovePkcs7(padded []byte, blockSize int) []byte { - - dataLen:=len(padded) - paddingCount:=int(padded[dataLen-1]) - - if(paddingCount > blockSize || paddingCount <= 0) { - return padded //data is not padded (or not padded correctly), return as is - } - - padding := padded[dataLen-paddingCount : dataLen-1] - - for _, b := range padding { - if int(b) != paddingCount { - return padded //data is not padded (or not padded correcly), return as is - } - } - - return padded[:len(padded)-paddingCount] //return data - padding -} \ No newline at end of file diff --git a/vendor/github.com/dvsekhvalnov/jose2go/pbse2_hmac_aeskw.go b/vendor/github.com/dvsekhvalnov/jose2go/pbse2_hmac_aeskw.go deleted file mode 100644 index baeaf9c..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/pbse2_hmac_aeskw.go +++ /dev/null @@ -1,103 +0,0 @@ -package jose - -import ( - "crypto/sha256" - "crypto/sha512" - "errors" - "hash" - - "github.com/dvsekhvalnov/jose2go/arrays" - "github.com/dvsekhvalnov/jose2go/base64url" - "github.com/dvsekhvalnov/jose2go/kdf" -) - -func init() { - RegisterJwa(&Pbse2HmacAesKW{keySizeBits: 128, aesKW: &AesKW{keySizeBits: 128}}) - RegisterJwa(&Pbse2HmacAesKW{keySizeBits: 192, aesKW: &AesKW{keySizeBits: 192}}) - RegisterJwa(&Pbse2HmacAesKW{keySizeBits: 256, aesKW: &AesKW{keySizeBits: 256}}) -} - -// PBSE2 with HMAC key management algorithm implementation -type Pbse2HmacAesKW struct { - keySizeBits int - aesKW JwaAlgorithm -} - -func (alg *Pbse2HmacAesKW) Name() string { - switch alg.keySizeBits { - case 128: - return PBES2_HS256_A128KW - case 192: - return PBES2_HS384_A192KW - default: - return PBES2_HS512_A256KW - } -} - -func (alg *Pbse2HmacAesKW) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) { - if passphrase, ok := key.(string); ok { - - algId := []byte(header["alg"].(string)) - - iterationCount := 8192 - var saltInput []byte - - if saltInput, err = arrays.Random(12); err != nil { - return nil, nil, err - } - - header["p2c"] = iterationCount - header["p2s"] = base64url.Encode(saltInput) - - salt := arrays.Concat(algId, []byte{0}, saltInput) - - kek := kdf.DerivePBKDF2([]byte(passphrase), salt, iterationCount, alg.keySizeBits, alg.prf) - return alg.aesKW.WrapNewKey(cekSizeBits, kek, header) - } - - return nil, nil, errors.New("Pbse2HmacAesKW.WrapNewKey(): expected key to be 'string' array") -} - -func (alg *Pbse2HmacAesKW) Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) { - - if passphrase, ok := key.(string); ok { - - var p2s string - var p2c float64 - - if p2c, ok = header["p2c"].(float64); !ok { - return nil, errors.New("Pbse2HmacAesKW.Unwrap(): expected 'p2c' param in JWT header, but was not found.") - } - - if p2s, ok = header["p2s"].(string); !ok { - return nil, errors.New("Pbse2HmacAesKW.Unwrap(): expected 'p2s' param in JWT header, but was not found.") - } - - var saltInput []byte - - algId := []byte(header["alg"].(string)) - - if saltInput, err = base64url.Decode(p2s); err != nil { - return nil, err - } - - salt := arrays.Concat(algId, []byte{0}, saltInput) - - kek := kdf.DerivePBKDF2([]byte(passphrase), salt, int(p2c), alg.keySizeBits, alg.prf) - - return alg.aesKW.Unwrap(encryptedCek, kek, cekSizeBits, header) - } - - return nil, errors.New("Pbse2HmacAesKW.Unwrap(): expected key to be 'string' array") -} - -func (alg *Pbse2HmacAesKW) prf() hash.Hash { - switch alg.keySizeBits { - case 128: - return sha256.New() - case 192: - return sha512.New384() - default: - return sha512.New() - } -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/plaintext.go b/vendor/github.com/dvsekhvalnov/jose2go/plaintext.go deleted file mode 100644 index 761ce5a..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/plaintext.go +++ /dev/null @@ -1,38 +0,0 @@ -package jose - -import ( - "errors" -) - -// Plaintext (no signing) signing algorithm implementation -type Plaintext struct{} - -func init() { - RegisterJws(new(Plaintext)) -} - -func (alg *Plaintext) Name() string { - return NONE -} - -func (alg *Plaintext) Verify(securedInput []byte, signature []byte, key interface{}) error { - - if key != nil { - return errors.New("Plaintext.Verify() expects key to be nil") - } - - if len(signature) != 0 { - return errors.New("Plaintext.Verify() expects signature to be empty.") - } - - return nil -} - -func (alg *Plaintext) Sign(securedInput []byte, key interface{}) (signature []byte, err error) { - - if key != nil { - return nil, errors.New("Plaintext.Verify() expects key to be nil") - } - - return []byte{}, nil -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/rsa_oaep.go b/vendor/github.com/dvsekhvalnov/jose2go/rsa_oaep.go deleted file mode 100644 index b0d1b52..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/rsa_oaep.go +++ /dev/null @@ -1,57 +0,0 @@ -package jose - -import ( - "errors" - "crypto/rsa" - "crypto/rand" - "hash" - "crypto/sha1" - "crypto/sha256" - "github.com/dvsekhvalnov/jose2go/arrays" -) - -// RS-AES using OAEP key management algorithm implementation -func init() { - RegisterJwa(&RsaOaep {shaSizeBits:1}) - RegisterJwa(&RsaOaep {shaSizeBits:256}) -} - -type RsaOaep struct{ - shaSizeBits int - // func shaF() hash.Hash -} - -func (alg *RsaOaep) Name() string { - switch alg.shaSizeBits { - case 1: return RSA_OAEP - default: return RSA_OAEP_256 - } -} - -func (alg *RsaOaep) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) { - if pubKey,ok:=key.(*rsa.PublicKey);ok { - if cek,err = arrays.Random(cekSizeBits>>3);err==nil { - encryptedCek,err=rsa.EncryptOAEP(alg.sha(),rand.Reader,pubKey,cek,nil) - return - } - - return nil,nil,err - } - - return nil,nil,errors.New("RsaOaep.WrapNewKey(): expected key to be '*rsa.PublicKey'") -} - -func (alg *RsaOaep) Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) { - if privKey,ok:=key.(*rsa.PrivateKey);ok { - return rsa.DecryptOAEP(alg.sha(), rand.Reader, privKey, encryptedCek, nil) - } - - return nil,errors.New("RsaOaep.Unwrap(): expected key to be '*rsa.PrivateKey'") -} - -func (alg *RsaOaep) sha() hash.Hash { - switch alg.shaSizeBits { - case 1: return sha1.New() - default: return sha256.New() - } -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/rsa_pkcs1v15.go b/vendor/github.com/dvsekhvalnov/jose2go/rsa_pkcs1v15.go deleted file mode 100644 index 10dac06..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/rsa_pkcs1v15.go +++ /dev/null @@ -1,41 +0,0 @@ -package jose - -import ( - "errors" - "crypto/rsa" - "crypto/rand" - "github.com/dvsekhvalnov/jose2go/arrays" -) - -func init() { - RegisterJwa(new(RsaPkcs1v15)) -} - -// RS-AES using PKCS #1 v1.5 padding key management algorithm implementation -type RsaPkcs1v15 struct{ -} - -func (alg *RsaPkcs1v15) Name() string { - return RSA1_5 -} - -func (alg *RsaPkcs1v15) WrapNewKey(cekSizeBits int, key interface{}, header map[string]interface{}) (cek []byte, encryptedCek []byte, err error) { - if pubKey,ok:=key.(*rsa.PublicKey);ok { - if cek,err = arrays.Random(cekSizeBits>>3);err==nil { - encryptedCek,err=rsa.EncryptPKCS1v15(rand.Reader,pubKey,cek) - return - } - - return nil,nil,err - } - - return nil,nil,errors.New("RsaPkcs1v15.WrapNewKey(): expected key to be '*rsa.PublicKey'") -} - -func (alg *RsaPkcs1v15) Unwrap(encryptedCek []byte, key interface{}, cekSizeBits int, header map[string]interface{}) (cek []byte, err error) { - if privKey,ok:=key.(*rsa.PrivateKey);ok { - return rsa.DecryptPKCS1v15(rand.Reader,privKey,encryptedCek) - } - - return nil,errors.New("RsaPkcs1v15.Unwrap(): expected key to be '*rsa.PrivateKey'") -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/rsa_using_sha.go b/vendor/github.com/dvsekhvalnov/jose2go/rsa_using_sha.go deleted file mode 100644 index 647a45a..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/rsa_using_sha.go +++ /dev/null @@ -1,50 +0,0 @@ -package jose - -import ( - "crypto/rand" - "crypto/rsa" - "errors" -) - -func init() { - RegisterJws(&RsaUsingSha{keySizeBits: 256}) - RegisterJws(&RsaUsingSha{keySizeBits: 384}) - RegisterJws(&RsaUsingSha{keySizeBits: 512}) -} - -// RSA using SHA signature algorithm implementation -type RsaUsingSha struct{ - keySizeBits int -} - -func (alg *RsaUsingSha) Name() string { - switch alg.keySizeBits { - case 256: return RS256 - case 384: return RS384 - default: return RS512 - } -} - -func (alg *RsaUsingSha) Verify(securedInput, signature []byte, key interface{}) error { - - if pubKey,ok:=key.(*rsa.PublicKey);ok { - return rsa.VerifyPKCS1v15(pubKey, hashFunc(alg.keySizeBits), sha(alg.keySizeBits, securedInput), signature) - } - - return errors.New("RsaUsingSha.Verify(): expects key to be '*rsa.PublicKey'") -} - -func (alg *RsaUsingSha) Sign(securedInput []byte, key interface{}) (signature []byte, err error) { - - if privKey,ok:=key.(*rsa.PrivateKey);ok { - return rsa.SignPKCS1v15(rand.Reader, privKey, hashFunc(alg.keySizeBits), sha(alg.keySizeBits, securedInput)) - } - - return nil,errors.New("RsaUsingSha.Sign(): expects key to be '*rsa.PrivateKey'") -} - -func sha(keySizeBits int, input []byte) (hash []byte) { - hasher := hashAlg(keySizeBits) - hasher.Write(input) - return hasher.Sum(nil) -} \ No newline at end of file diff --git a/vendor/github.com/dvsekhvalnov/jose2go/rsapss_using_sha.go b/vendor/github.com/dvsekhvalnov/jose2go/rsapss_using_sha.go deleted file mode 100644 index fc111db..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/rsapss_using_sha.go +++ /dev/null @@ -1,43 +0,0 @@ -package jose - -import ( - "crypto/rand" - "crypto/rsa" - "errors" -) - -func init() { - RegisterJws(&RsaPssUsingSha{keySizeBits: 256, saltSizeBytes: 32}) - RegisterJws(&RsaPssUsingSha{keySizeBits: 384, saltSizeBytes: 48}) - RegisterJws(&RsaPssUsingSha{keySizeBits: 512, saltSizeBytes: 64}) -} - -// RSA with PSS using SHA signing algorithm implementation -type RsaPssUsingSha struct{ - keySizeBits int - saltSizeBytes int -} - -func (alg *RsaPssUsingSha) Name() string { - switch alg.keySizeBits { - case 256: return PS256 - case 384: return PS384 - default: return PS512 - } -} - -func (alg *RsaPssUsingSha) Verify(securedInput, signature []byte, key interface{}) error { - if pubKey,ok:=key.(*rsa.PublicKey);ok { - return rsa.VerifyPSS(pubKey, hashFunc(alg.keySizeBits), sha(alg.keySizeBits, securedInput), signature, &rsa.PSSOptions{SaltLength:alg.saltSizeBytes}) - } - - return errors.New("RsaPssUsingSha.Verify(): expects key to be '*rsa.PublicKey'") -} - -func (alg *RsaPssUsingSha) Sign(securedInput []byte, key interface{}) (signature []byte, err error) { - if privKey,ok:=key.(*rsa.PrivateKey);ok { - return rsa.SignPSS(rand.Reader, privKey, hashFunc(alg.keySizeBits), sha(alg.keySizeBits, securedInput), &rsa.PSSOptions{SaltLength:alg.saltSizeBytes}) - } - - return nil,errors.New("RsaPssUsingSha.Sign(): expects key to be '*rsa.PrivateKey'") -} diff --git a/vendor/github.com/dvsekhvalnov/jose2go/sha.go b/vendor/github.com/dvsekhvalnov/jose2go/sha.go deleted file mode 100644 index 13b7b17..0000000 --- a/vendor/github.com/dvsekhvalnov/jose2go/sha.go +++ /dev/null @@ -1,24 +0,0 @@ -package jose - -import ( - "hash" - "crypto" - "crypto/sha256" - "crypto/sha512" -) - -func hashFunc(keySizeBits int) crypto.Hash { - switch keySizeBits { - case 256: return crypto.SHA256 - case 384: return crypto.SHA384 - default: return crypto.SHA512 - } -} - -func hashAlg(keySizeBits int) hash.Hash { - switch keySizeBits { - case 256: return sha256.New() - case 384: return sha512.New384() - default: return sha512.New() - } -} \ No newline at end of file diff --git a/vendor/github.com/godbus/dbus/.travis.yml b/vendor/github.com/godbus/dbus/.travis.yml deleted file mode 100644 index 752dc0a..0000000 --- a/vendor/github.com/godbus/dbus/.travis.yml +++ /dev/null @@ -1,46 +0,0 @@ -dist: xenial -language: go -go_import_path: github.com/godbus/dbus -sudo: true - -go: - - 1.7.3 - - 1.8.7 - - 1.9.5 - - 1.10.1 - - tip - -env: - global: - matrix: - - TARGET=amd64 - - TARGET=arm64 - - TARGET=arm - - TARGET=386 - - TARGET=ppc64le - -matrix: - fast_finish: true - allow_failures: - - go: tip - exclude: - - go: tip - env: TARGET=arm - - go: tip - env: TARGET=arm64 - - go: tip - env: TARGET=386 - - go: tip - env: TARGET=ppc64le - -addons: - apt: - packages: - - dbus - - dbus-x11 - -before_install: - -script: - - go test -v -race ./... # Run all the tests with the race detector enabled - - go vet ./... # go vet is the official Go static analyzer diff --git a/vendor/github.com/godbus/dbus/CONTRIBUTING.md b/vendor/github.com/godbus/dbus/CONTRIBUTING.md deleted file mode 100644 index c88f9b2..0000000 --- a/vendor/github.com/godbus/dbus/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# How to Contribute - -## Getting Started - -- Fork the repository on GitHub -- Read the [README](README.markdown) for build and test instructions -- Play with the project, submit bugs, submit patches! - -## Contribution Flow - -This is a rough outline of what a contributor's workflow looks like: - -- Create a topic branch from where you want to base your work (usually master). -- Make commits of logical units. -- Make sure your commit messages are in the proper format (see below). -- Push your changes to a topic branch in your fork of the repository. -- Make sure the tests pass, and add any new tests as appropriate. -- Submit a pull request to the original repository. - -Thanks for your contributions! - -### Format of the Commit Message - -We follow a rough convention for commit messages that is designed to answer two -questions: what changed and why. The subject line should feature the what and -the body of the commit should describe the why. - -``` -scripts: add the test-cluster command - -this uses tmux to setup a test cluster that you can easily kill and -start for debugging. - -Fixes #38 -``` - -The format can be described more formally as follows: - -``` -: - - - -