Version in base suite: 2.0.2-1 Base version: privatebin-cli_2.0.2-1 Target version: privatebin-cli_2.0.2-1+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/p/privatebin-cli/privatebin-cli_2.0.2-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/p/privatebin-cli/privatebin-cli_2.0.2-1+deb13u1.dsc changelog | 6 patches/0001-fix-privatebin-conf-man-page-section | 16 patches/0002-Backport-changes-to-adapt-GCM-for-newer-golang-versi.patch | 308 ++++++++++ patches/series | 1 4 files changed, 327 insertions(+), 4 deletions(-) diff -Nru privatebin-cli-2.0.2/debian/changelog privatebin-cli-2.0.2/debian/changelog --- privatebin-cli-2.0.2/debian/changelog 2024-11-16 11:17:22.000000000 +0000 +++ privatebin-cli-2.0.2/debian/changelog 2025-11-01 11:00:52.000000000 +0000 @@ -1,3 +1,9 @@ +privatebin-cli (2.0.2-1+deb13u1) trixie; urgency=medium + + * d/patches: Add patch to fix GCM issues with newer golang. (Closes: #1108675) + + -- Martin Dosch Sat, 01 Nov 2025 11:00:52 +0000 + privatebin-cli (2.0.2-1) unstable; urgency=medium * Initial release (Closes: #1087620) diff -Nru privatebin-cli-2.0.2/debian/patches/0001-fix-privatebin-conf-man-page-section privatebin-cli-2.0.2/debian/patches/0001-fix-privatebin-conf-man-page-section --- privatebin-cli-2.0.2/debian/patches/0001-fix-privatebin-conf-man-page-section 2024-11-16 11:17:22.000000000 +0000 +++ privatebin-cli-2.0.2/debian/patches/0001-fix-privatebin-conf-man-page-section 2025-11-01 11:00:45.000000000 +0000 @@ -1,13 +1,21 @@ -Description: Fix manpage section for privatebin.conf manpage -Author: Martin Dosch +From: Martin Dosch +Date: Sat, 27 Sep 2025 12:01:35 +0200 +Subject: Fix manpage section for privatebin.conf manpage + Origin: upstream, https://github.com/gearnode/privatebin/pull/15 Forwarded: URL, https://github.com/gearnode/privatebin/pull/15 Last-Update: 2024-11-16 + +Last-Update: 2024-11-16 --- -This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ + doc/privatebin.conf.5.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/doc/privatebin.conf.5.md b/doc/privatebin.conf.5.md +index 0ec5e12..6b066e9 100644 --- a/doc/privatebin.conf.5.md +++ b/doc/privatebin.conf.5.md -@@ -3,7 +3,7 @@ +@@ -3,7 +3,7 @@ title: PRIVATEBIN.CONF header: Privatebin Manual footer: 1.0.0 date: Jan 20, 2022 diff -Nru privatebin-cli-2.0.2/debian/patches/0002-Backport-changes-to-adapt-GCM-for-newer-golang-versi.patch privatebin-cli-2.0.2/debian/patches/0002-Backport-changes-to-adapt-GCM-for-newer-golang-versi.patch --- privatebin-cli-2.0.2/debian/patches/0002-Backport-changes-to-adapt-GCM-for-newer-golang-versi.patch 1970-01-01 00:00:00.000000000 +0000 +++ privatebin-cli-2.0.2/debian/patches/0002-Backport-changes-to-adapt-GCM-for-newer-golang-versi.patch 2025-11-01 11:00:45.000000000 +0000 @@ -0,0 +1,308 @@ +From: Martin Dosch +Date: Sat, 27 Sep 2025 12:33:54 +0200 +Subject: Backport changes to adapt GCM for newer golang versions. (Closes: + #1108675) + +--- + cmd/privatebin/cfg.go | 6 ++++ + cmd/privatebin/main.go | 19 ++++++++++-- + gcm.go | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ + privatebin.go | 13 +++++++-- + utils.go | 39 ++----------------------- + 5 files changed, 116 insertions(+), 40 deletions(-) + create mode 100644 gcm.go + +diff --git a/cmd/privatebin/cfg.go b/cmd/privatebin/cfg.go +index 2a65678..b9731ca 100644 +--- a/cmd/privatebin/cfg.go ++++ b/cmd/privatebin/cfg.go +@@ -35,6 +35,7 @@ type ( + OpenDiscussion *bool `json:"open-discussion"` + BurnAfterReading *bool `json:"burn-after-reading"` + GZip *bool `json:"gzip"` ++ SkipTLSVerify *bool `json:"skip-tls-verify"` + Formatter string `json:"formatter"` + ExtraHeaderFields map[string]string `json:"extra-header-fields"` + } +@@ -45,6 +46,7 @@ type ( + OpenDiscussion bool `json:"open-discussion"` + BurnAfterReading bool `json:"burn-after-reading"` + GZip bool `json:"gzip"` ++ SkipTLSVerify bool `json:"skip-tls-verify"` + Formatter string `json:"formatter"` + ExtraHeaderFields map[string]string `json:"extra-header-fields"` + } +@@ -106,6 +108,10 @@ func loadCfgFile(path string) (*Cfg, error) { + binCfg.GZip = &cfg.GZip + } + ++ if binCfg.SkipTLSVerify == nil { ++ binCfg.SkipTLSVerify = &cfg.SkipTLSVerify ++ } ++ + if binCfg.ExtraHeaderFields == nil { + binCfg.ExtraHeaderFields = cfg.ExtraHeaderFields + } +diff --git a/cmd/privatebin/main.go b/cmd/privatebin/main.go +index e986f1f..4d1df20 100644 +--- a/cmd/privatebin/main.go ++++ b/cmd/privatebin/main.go +@@ -16,6 +16,7 @@ package main + + import ( + "context" ++ "crypto/tls" + "encoding/base64" + "encoding/json" + "fmt" +@@ -58,8 +59,9 @@ var ( + filename string + attachment bool + +- insecure bool +- confirmBurn bool ++ insecure bool ++ confirmBurn bool ++ skipTLSVerify bool + + rootCmd = &cobra.Command{ + Use: "privatebin", +@@ -123,6 +125,17 @@ var ( + ) + } + ++ if (binCfg.SkipTLSVerify != nil && *binCfg.SkipTLSVerify) || skipTLSVerify { ++ tlsConfig := &tls.Config{ ++ InsecureSkipVerify: true, ++ } ++ ++ clientOptions = append( ++ clientOptions, ++ privatebin.WithTLSConfig(tlsConfig), ++ ) ++ } ++ + host, err := url.Parse(binCfg.Host) + if err != nil { + return fmt.Errorf("cannot parse %q bin %q host: %w", binCfg.Name, binCfg.Host, err) +@@ -302,10 +315,12 @@ func init() { + createCmd.Flags().StringVar(&password, "password", "", "the paste password") + createCmd.Flags().StringVar(&filename, "filename", "", "read filepath instead of stdin") + createCmd.Flags().BoolVar(&attachment, "attachment", false, "create the paste as an attachment") ++ createCmd.Flags().BoolVar(&skipTLSVerify, "skip-tls-verify", false, "skip TLS certificate verification") + + showCmd.Flags().BoolVar(&insecure, "insecure", false, "allow reading paste from untrusted instance") + showCmd.Flags().BoolVar(&confirmBurn, "confirm-burn", false, "confirm paste opening, it will be deleted immediately afterwards") + showCmd.Flags().StringVar(&password, "password", "", "the paste password") ++ showCmd.Flags().BoolVar(&skipTLSVerify, "skip-tls-verify", false, "skip TLS certificate verification") + + rootCmd.AddCommand(showCmd, createCmd) + } +diff --git a/gcm.go b/gcm.go +new file mode 100644 +index 0000000..22fd87f +--- /dev/null ++++ b/gcm.go +@@ -0,0 +1,79 @@ ++// Copyright (c) 2020-2025 Bryan Frimin . ++// ++// Permission to use, copy, modify, and/or distribute this software for any ++// purpose with or without fee is hereby granted, provided that the above ++// copyright notice and this permission notice appear in all copies. ++// ++// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH ++// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ++// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, ++// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ++// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR ++// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ++// PERFORMANCE OF THIS SOFTWARE. ++ ++package privatebin ++ ++import ( ++ "crypto/cipher" ++ "fmt" ++) ++ ++const ( ++ gcmStandardNonceSize = 12 ++ gcmStandardTagSize = 16 ++) ++ ++// newGCMWithNonceOrTagSize creates a GCM cipher with custom nonce or tag sizes. ++// ++// Historical context: ++// - Before Go 1.19: There was a public function cipher.NewGCMWithNonceAndTagSize() ++// that allowed creation of GCM with both custom nonce AND tag sizes. ++// - Go 1.19: The public NewGCMWithNonceAndTagSize was removed as a breaking change. ++// However, the internal newGCMWithNonceAndTagSize function and gcmAble interface ++// were still accessible, allowing a workaround to achieve both custom parameters. ++// - Go 1.21+: The FIPS 140-3 refactoring moved everything into internal packages ++// (crypto/internal/fips140), making the gcmAble interface completely inaccessible. ++// No public or hackable interface remains to create GCM with both custom parameters. ++// ++// Related issue: https://github.com/golang/go/issues/42470 (still open) ++// ++// Current limitations due to Go 1.21+ changes: ++// - Standard parameters (12-byte nonce, 16-byte tag): Fully supported via cipher.NewGCM() ++// - Custom nonce size only: Supported via cipher.NewGCMWithNonceSize() ++// - Custom tag size only: Supported via cipher.NewGCMWithTagSize() ++// - Both custom nonce AND tag sizes: No longer possible - returns an error ++// ++// This implementation is now limited to maintain compatibility with newer Go versions. ++// Applications requiring both custom nonce and tag sizes must either use Go < 1.19 ++// or find alternative cryptographic libraries. ++// ++// Design decision: ++// I chose not to fork or implement a custom GCM mode because this project is not a ++// full-time commitment, making it impossible to invest the time needed to properly ++// maintain such critical cryptographic code. Using the latest Go version is prioritized ++// to keep this project secure and usable by everyone. Third-party cryptographic libraries ++// are not an option as none currently exist for this use case, and even if one did, ++// establishing proper trust for cryptographic code in a security-focused project like ++// this would be challenging. ++func newGCMWithNonceOrTagSize(block cipher.Block, nonceSize, tagSize int) (cipher.AEAD, error) { ++ if nonceSize == gcmStandardNonceSize && tagSize == gcmStandardTagSize { ++ return cipher.NewGCM(block) ++ } ++ ++ // For standard parameters, use the standard implementation ++ if nonceSize == gcmStandardNonceSize && tagSize == gcmStandardTagSize { ++ return cipher.NewGCM(block) ++ } ++ ++ if tagSize == gcmStandardTagSize { ++ return cipher.NewGCMWithNonceSize(block, nonceSize) ++ } ++ ++ if nonceSize == gcmStandardNonceSize { ++ return cipher.NewGCMWithTagSize(block, tagSize) ++ } ++ ++ // For non-standard parameters in Go 1.19+, we cannot proceed ++ return nil, fmt.Errorf("custom GCM parameters (nonce=%d, tag=%d) are not supported since Go 1.20+", nonceSize, tagSize) ++} +diff --git a/privatebin.go b/privatebin.go +index ef52ca9..b7c36ff 100644 +--- a/privatebin.go ++++ b/privatebin.go +@@ -21,6 +21,7 @@ import ( + "crypto/aes" + "crypto/cipher" + "crypto/sha256" ++ "crypto/tls" + "encoding/base64" + "encoding/json" + "fmt" +@@ -50,6 +51,7 @@ type ( + password string + customHTTPHeaderFields map[string]string + userAgent string ++ tlsConfig *tls.Config + } + + Option func(c *Client) +@@ -165,10 +167,15 @@ func WithUserAgent(userAgent string) Option { + } + } + ++func WithTLSConfig(tlsConfig *tls.Config) Option { ++ return func(c *Client) { ++ c.tlsConfig = tlsConfig ++ } ++} ++ + func NewClient(endpoint url.URL, options ...Option) *Client { + client := &Client{ + endpoint: endpoint, +- httpClient: defaultPooledClient(), + customHTTPHeaderFields: make(map[string]string), + } + +@@ -176,6 +183,8 @@ func NewClient(endpoint url.URL, options ...Option) *Client { + option(client) + } + ++ client.httpClient = defaultPooledClient(client.tlsConfig) ++ + return client + } + +@@ -489,7 +498,7 @@ func decrypt(masterKey []byte, ct string, adata []byte, spec Spec) ([]byte, erro + + switch spec.Mode { + case EncryptionModeGCM: +- gcm, err = newGCMWithNonceAndTagSize( ++ gcm, err = newGCMWithNonceOrTagSize( + cipherBlock, + len(spec.IV), + spec.TagSize/8, +diff --git a/utils.go b/utils.go +index 61cd717..1a0f67b 100644 +--- a/utils.go ++++ b/utils.go +@@ -15,10 +15,9 @@ + package privatebin + + import ( +- "crypto/cipher" + "crypto/rand" ++ "crypto/tls" + "encoding/base64" +- "errors" + "net" + "net/http" + "runtime" +@@ -53,7 +52,7 @@ func decode64(s string) ([]byte, error) { + return base64.RawStdEncoding.DecodeString(s) + } + +-func defaultPooledClient() *http.Client { ++func defaultPooledClient(tlsConfig *tls.Config) *http.Client { + dial := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, +@@ -69,41 +68,9 @@ func defaultPooledClient() *http.Client { + ExpectContinueTimeout: 1 * time.Second, + ForceAttemptHTTP2: true, + MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1, ++ TLSClientConfig: tlsConfig, + } + + return &http.Client{Transport: transport} + } + +-// Golang standard library does not expose GCM with custom nonce and +-// tag size, even if it supported. Following code is a backport from +-// the Golang crypto module to allowing it. +-// +-// References: +-// - https://go-review.googlesource.com/c/go/+/116435 +-// - https://github.com/golang/go/issues?q=NewGCMWithNonceAndTagSize +-// - https://github.com/golang/go/issues/42470 +- +-const ( +- gcmBlockSize = 16 +- gcmMinimumTagSize = 12 // NIST SP 800-38D recommends tags with 12 or more bytes. +-) +- +-type gcmAble interface { +- NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) +-} +- +-func newGCMWithNonceAndTagSize(cipher cipher.Block, nonceSize, tagSize int) (cipher.AEAD, error) { +- if tagSize < gcmMinimumTagSize || tagSize > gcmBlockSize { +- return nil, errors.New("cipher: incorrect tag size given to GCM") +- } +- +- if nonceSize <= 0 { +- return nil, errors.New("cipher: the nonce can't have zero length, or the security of the key will be immediately compromised") +- } +- +- if cipher, ok := cipher.(gcmAble); ok { +- return cipher.NewGCM(nonceSize, tagSize) +- } +- +- panic("non GCM crypto is not supported") +-} diff -Nru privatebin-cli-2.0.2/debian/patches/series privatebin-cli-2.0.2/debian/patches/series --- privatebin-cli-2.0.2/debian/patches/series 2024-11-16 11:17:22.000000000 +0000 +++ privatebin-cli-2.0.2/debian/patches/series 2025-11-01 11:00:45.000000000 +0000 @@ -1 +1,2 @@ 0001-fix-privatebin-conf-man-page-section +0002-Backport-changes-to-adapt-GCM-for-newer-golang-versi.patch