[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1117202: trixie-pu: package privatebin-cli/2.0.2-1+deb13u1



Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: privatebin-cli@packages.debian.org
Control: affects -1 + src:privatebin-cli
User: release.debian.org@packages.debian.org
Usertags: pu

[ Reason ]
There is an annoying issue (#1108675) that renders the program partly 
unusable as it renders the "show" functionality to read pastes in a 
privatebin unusable. This was introduced by changes in golang >= 1.21.
The new upstream release 2.1.1 fixes this issue and was just uploaded to 
unstable by a sponsor.

[ Impact ]
Users can create pastes using this tool, but can't read pastes without 
opening them in the web browser. But the reason to install this CLI tool 
is to not have to use the web browser for interacting with privatebin 
instances.

[ Tests ]
The package was built and the normal autopkgtests have been run, 
additionally I manually tested it on a trixie installation by creating 
and showing several pastes on different privatebin instances.

[ Risks ]
As I have tested it manually I see little risks for this update. The 
worst thing that might happen is the tool is not working and people have 
to use the browser instead.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]
- The way the tool interacts with GCM cipher creation was changed to 
  comply with the interfaces Go 1.21+ offers.

[ Other info ]
Nothing I can think of.

Best regards,
Martin
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 12:17:22.000000000 +0100
+++ privatebin-cli-2.0.2/debian/changelog	2025-09-27 12:41:15.000000000 +0200
@@ -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 <martin@mdosch.de>  Sat, 27 Sep 2025 10:41:15 +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 12:17:22.000000000 +0100
+++ privatebin-cli-2.0.2/debian/patches/0001-fix-privatebin-conf-man-page-section	2025-09-27 12:37:30.000000000 +0200
@@ -1,13 +1,21 @@
-Description: Fix manpage section for privatebin.conf manpage
-Author: Martin Dosch <martin@mdosch.de>
+From: Martin Dosch <martin@mdosch.de>
+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 01:00:00.000000000 +0100
+++ privatebin-cli-2.0.2/debian/patches/0002-Backport-changes-to-adapt-GCM-for-newer-golang-versi.patch	2025-09-27 12:37:30.000000000 +0200
@@ -0,0 +1,308 @@
+From: Martin Dosch <martin@mdosch.de>
+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 <bryan@frimin.fr>.
++//
++// 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 12:17:22.000000000 +0100
+++ privatebin-cli-2.0.2/debian/patches/series	2025-09-27 12:37:30.000000000 +0200
@@ -1 +1,2 @@
 0001-fix-privatebin-conf-man-page-section
+0002-Backport-changes-to-adapt-GCM-for-newer-golang-versi.patch

Attachment: signature.asc
Description: PGP signature


Reply to: