From 7c3835a4f3ffc7565601d3fda0f99e2bc4dbef51 Mon Sep 17 00:00:00 2001 From: Felix Pojtinger Date: Sat, 4 Dec 2021 20:34:34 +0100 Subject: [PATCH] feat: Add signature support to `update` cmd --- cmd/stbak/cmd/recovery_fetch.go | 4 ++++ cmd/stbak/cmd/update.go | 34 ++++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/cmd/stbak/cmd/recovery_fetch.go b/cmd/stbak/cmd/recovery_fetch.go index a049a2f..b1d23b7 100644 --- a/cmd/stbak/cmd/recovery_fetch.go +++ b/cmd/stbak/cmd/recovery_fetch.go @@ -352,6 +352,10 @@ func parseIdentity( if password != "" { for _, identity := range identities { + if identity.PrivateKey == nil { + return nil, errIdentityUnparsable + } + if err := identity.PrivateKey.Decrypt([]byte(password)); err != nil { return nil, err } diff --git a/cmd/stbak/cmd/update.go b/cmd/stbak/cmd/update.go index a89109f..9a5cdf1 100644 --- a/cmd/stbak/cmd/update.go +++ b/cmd/stbak/cmd/update.go @@ -34,7 +34,11 @@ var updateCmd = &cobra.Command{ return err } - return checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)) + if err := checkKeyAccessible(viper.GetString(encryptionFlag), viper.GetString(recipientFlag)); err != nil { + return err + } + + return checkKeyAccessible(viper.GetString(signatureFlag), viper.GetString(identityFlag)) }, RunE: func(cmd *cobra.Command, args []string) error { if err := viper.BindPFlags(cmd.PersistentFlags()); err != nil { @@ -65,6 +69,16 @@ var updateCmd = &cobra.Command{ return err } + privkey, err := readKey(viper.GetString(signatureFlag), viper.GetString(identityFlag)) + if err != nil { + return err + } + + identity, err := parseSignerIdentity(viper.GetString(signatureFlag), privkey, viper.GetString(passwordFlag)) + if err != nil { + return err + } + hdrs, err := update( viper.GetString(driveFlag), viper.GetInt(recordSizeFlag), @@ -74,6 +88,8 @@ var updateCmd = &cobra.Command{ viper.GetString(compressionLevelFlag), viper.GetString(encryptionFlag), recipient, + viper.GetString(signatureFlag), + identity, ) if err != nil { return err @@ -111,6 +127,8 @@ func update( compressionLevel string, encryptionFormat string, recipient interface{}, + signatureFormat string, + identity interface{}, ) ([]*tar.Header, error) { dirty := false tw, isRegular, cleanup, err := openTapeWriter(tape) @@ -177,13 +195,18 @@ func update( return err } + signer, sign, err := sign(file, signatureFormat, identity) + if err != nil { + return err + } + if isRegular { - if _, err := io.Copy(compressor, file); err != nil { + if _, err := io.Copy(compressor, signer); err != nil { return err } } else { buf := make([]byte, controllers.BlockSize*recordSize) - if _, err := io.CopyBuffer(compressor, file, buf); err != nil { + if _, err := io.CopyBuffer(compressor, signer, buf); err != nil { return err } } @@ -208,6 +231,9 @@ func update( hdr.PAXRecords = map[string]string{} } hdr.PAXRecords[pax.STFSRecordUncompressedSize] = strconv.Itoa(int(hdr.Size)) + if signature := sign(); signature != "" { + hdr.PAXRecords[pax.STFSRecordSignature] = signature + } hdr.Size = int64(fileSizeCounter.BytesRead) hdr.Name, err = addSuffix(hdr.Name, compressionFormat, encryptionFormat) @@ -325,6 +351,8 @@ func init() { updateCmd.PersistentFlags().BoolP(overwriteFlag, "o", false, "Replace the content on the tape or tar file") updateCmd.PersistentFlags().StringP(compressionLevelFlag, "l", compressionLevelBalanced, fmt.Sprintf("Compression level to use (default %v, available are %v)", compressionLevelBalanced, knownCompressionLevels)) updateCmd.PersistentFlags().StringP(recipientFlag, "r", "", "Path to public key of recipient to encrypt for") + updateCmd.PersistentFlags().StringP(identityFlag, "i", "", "Path to private key to sign with") + updateCmd.PersistentFlags().StringP(passwordFlag, "p", "", "Password for the private key") viper.AutomaticEnv()