refactor: Decompose and pull up identity parsing to cmds

This commit is contained in:
Felix Pojtinger
2021-12-04 15:20:04 +01:00
parent 692cc4da39
commit 16d1a63c61
6 changed files with 132 additions and 134 deletions

View File

@@ -133,8 +133,7 @@ var archiveCmd = &cobra.Command{
viper.GetBool(overwriteFlag),
viper.GetString(compressionFlag),
viper.GetString(encryptionFlag),
[]byte{},
func(hdr *tar.Header, encryptionFormat string, privkey []byte, i int) error {
func(hdr *tar.Header, encryptionFormat string, i int) error {
if len(hdrs) <= i {
return errMissingTarHeader
}

View File

@@ -38,6 +38,8 @@ const (
var (
errEmbeddedHeaderMissing = errors.New("embedded header is missing")
errIdentityUnparsable = errors.New("recipient could not be parsed")
)
var recoveryFetchCmd = &cobra.Command{
@@ -64,6 +66,11 @@ var recoveryFetchCmd = &cobra.Command{
return err
}
identity, err := parseIdentity(viper.GetString(encryptionFlag), privkey, viper.GetString(passwordFlag))
if err != nil {
return err
}
return restoreFromRecordAndBlock(
viper.GetString(tapeFlag),
viper.GetInt(recordSizeFlag),
@@ -74,8 +81,7 @@ var recoveryFetchCmd = &cobra.Command{
true,
viper.GetString(compressionFlag),
viper.GetString(encryptionFlag),
privkey,
viper.GetString(passwordFlag),
identity,
)
},
}
@@ -90,8 +96,7 @@ func restoreFromRecordAndBlock(
showHeader bool,
compressionFormat string,
encryptionFormat string,
privkey []byte,
password string,
identity interface{},
) error {
f, isRegular, err := openTapeReadOnly(tape)
if err != nil {
@@ -127,7 +132,7 @@ func restoreFromRecordAndBlock(
return err
}
if err := decryptHeader(hdr, encryptionFormat, privkey, password); err != nil {
if err := decryptHeader(hdr, encryptionFormat, identity); err != nil {
return err
}
@@ -168,7 +173,7 @@ func restoreFromRecordAndBlock(
return nil
}
decryptor, err := decrypt(tr, encryptionFormat, privkey, password)
decryptor, err := decrypt(tr, encryptionFormat, identity)
if err != nil {
return err
}
@@ -245,8 +250,7 @@ func decompress(
func decryptHeader(
hdr *tar.Header,
encryptionFormat string,
privkey []byte,
password string,
identity interface{},
) error {
if encryptionFormat == encryptionFormatNoneKey {
return nil
@@ -261,7 +265,7 @@ func decryptHeader(
return errEmbeddedHeaderMissing
}
embeddedHeader, err := decryptString(encryptedEmbeddedHeader, encryptionFormat, privkey, password)
embeddedHeader, err := decryptString(encryptedEmbeddedHeader, encryptionFormat, identity)
if err != nil {
return err
}
@@ -276,103 +280,11 @@ func decryptHeader(
return nil
}
func decryptString(
src string,
func parseIdentity(
encryptionFormat string,
privkey []byte,
password string,
) (string, error) {
switch encryptionFormat {
case encryptionFormatAgeKey:
if password != "" {
passwordIdentity, err := age.NewScryptIdentity(password)
if err != nil {
return "", err
}
r, err := age.Decrypt(bytes.NewBuffer(privkey), passwordIdentity)
if err != nil {
return "", err
}
out := &bytes.Buffer{}
if _, err := io.Copy(out, r); err != nil {
return "", err
}
privkey = out.Bytes()
}
identity, err := age.ParseX25519Identity(string(privkey))
if err != nil {
return "", err
}
decoded, err := base64.StdEncoding.DecodeString(src)
if err != nil {
return "", err
}
r, err := age.Decrypt(bytes.NewBufferString(string(decoded)), identity)
if err != nil {
return "", err
}
out := &bytes.Buffer{}
if _, err := io.Copy(out, r); err != nil {
return "", err
}
return out.String(), nil
case encryptionFormatPGPKey:
identities, err := openpgp.ReadKeyRing(bytes.NewBuffer(privkey))
if err != nil {
return "", err
}
if password != "" {
for _, identity := range identities {
if err := identity.PrivateKey.Decrypt([]byte(password)); err != nil {
return "", err
}
for _, subkey := range identity.Subkeys {
if err := subkey.PrivateKey.Decrypt([]byte(password)); err != nil {
return "", err
}
}
}
}
decoded, err := base64.StdEncoding.DecodeString(src)
if err != nil {
return "", err
}
r, err := openpgp.ReadMessage(bytes.NewBufferString(string(decoded)), identities, nil, nil)
if err != nil {
return "", err
}
out := &bytes.Buffer{}
if _, err := io.Copy(out, r.UnverifiedBody); err != nil {
return "", err
}
return out.String(), nil
case encryptionFormatNoneKey:
return src, nil
default:
return "", errUnsupportedEncryptionFormat
}
}
func decrypt(
src io.Reader,
encryptionFormat string,
privkey []byte,
password string,
) (io.ReadCloser, error) {
) (interface{}, error) {
switch encryptionFormat {
case encryptionFormatAgeKey:
if password != "" {
@@ -394,17 +306,7 @@ func decrypt(
privkey = out.Bytes()
}
identity, err := age.ParseX25519Identity(string(privkey))
if err != nil {
return nil, err
}
r, err := age.Decrypt(src, identity)
if err != nil {
return nil, err
}
return io.NopCloser(r), nil
return age.ParseX25519Identity(string(privkey))
case encryptionFormatPGPKey:
identities, err := openpgp.ReadKeyRing(bytes.NewBuffer(privkey))
if err != nil {
@@ -425,7 +327,96 @@ func decrypt(
}
}
r, err := openpgp.ReadMessage(src, identities, nil, nil)
return identities, nil
case encryptionFormatNoneKey:
return privkey, nil
default:
return nil, errUnsupportedEncryptionFormat
}
}
func decryptString(
src string,
encryptionFormat string,
identity interface{},
) (string, error) {
switch encryptionFormat {
case encryptionFormatAgeKey:
identity, ok := identity.(*age.X25519Identity)
if !ok {
return "", errIdentityUnparsable
}
decoded, err := base64.StdEncoding.DecodeString(src)
if err != nil {
return "", err
}
r, err := age.Decrypt(bytes.NewBufferString(string(decoded)), identity)
if err != nil {
return "", err
}
out := &bytes.Buffer{}
if _, err := io.Copy(out, r); err != nil {
return "", err
}
return out.String(), nil
case encryptionFormatPGPKey:
identity, ok := identity.(openpgp.EntityList)
if !ok {
return "", errIdentityUnparsable
}
decoded, err := base64.StdEncoding.DecodeString(src)
if err != nil {
return "", err
}
r, err := openpgp.ReadMessage(bytes.NewBufferString(string(decoded)), identity, nil, nil)
if err != nil {
return "", err
}
out := &bytes.Buffer{}
if _, err := io.Copy(out, r.UnverifiedBody); err != nil {
return "", err
}
return out.String(), nil
case encryptionFormatNoneKey:
return src, nil
default:
return "", errUnsupportedEncryptionFormat
}
}
func decrypt(
src io.Reader,
encryptionFormat string,
identity interface{},
) (io.ReadCloser, error) {
switch encryptionFormat {
case encryptionFormatAgeKey:
identity, ok := identity.(*age.X25519Identity)
if !ok {
return nil, errIdentityUnparsable
}
r, err := age.Decrypt(src, identity)
if err != nil {
return nil, err
}
return io.NopCloser(r), nil
case encryptionFormatPGPKey:
identity, ok := identity.(openpgp.EntityList)
if !ok {
return nil, errIdentityUnparsable
}
r, err := openpgp.ReadMessage(src, identity, nil, nil)
if err != nil {
return nil, err
}

View File

@@ -47,6 +47,11 @@ var recoveryIndexCmd = &cobra.Command{
return err
}
identity, err := parseIdentity(viper.GetString(encryptionFlag), privkey, viper.GetString(passwordFlag))
if err != nil {
return err
}
return index(
viper.GetString(tapeFlag),
viper.GetString(metadataFlag),
@@ -56,9 +61,8 @@ var recoveryIndexCmd = &cobra.Command{
viper.GetBool(overwriteFlag),
viper.GetString(compressionFlag),
viper.GetString(encryptionFlag),
privkey,
func(hdr *tar.Header, encryptionFormat string, privkey []byte, i int) error {
return decryptHeader(hdr, encryptionFormat, privkey, viper.GetString(passwordFlag))
func(hdr *tar.Header, encryptionFormat string, i int) error {
return decryptHeader(hdr, encryptionFormat, identity)
},
0,
)
@@ -74,11 +78,9 @@ func index(
overwrite bool,
compressionFormat string,
encryptionFormat string,
privkey []byte,
decryptHeader func(
hdr *tar.Header,
encryptionFormat string,
privkey []byte,
i int,
) error,
offset int,
@@ -171,7 +173,7 @@ func index(
}
if i >= offset {
if err := decryptHeader(hdr, encryptionFormat, privkey, i-offset); err != nil {
if err := decryptHeader(hdr, encryptionFormat, i-offset); err != nil {
return err
}
@@ -253,7 +255,7 @@ func index(
}
if i >= offset {
if err := decryptHeader(hdr, encryptionFormat, privkey, i-offset); err != nil {
if err := decryptHeader(hdr, encryptionFormat, i-offset); err != nil {
return err
}

View File

@@ -39,14 +39,18 @@ var recoveryQueryCmd = &cobra.Command{
return err
}
identity, err := parseIdentity(viper.GetString(encryptionFlag), privkey, viper.GetString(passwordFlag))
if err != nil {
return err
}
return query(
viper.GetString(tapeFlag),
viper.GetInt(recordFlag),
viper.GetInt(blockFlag),
viper.GetInt(recordSizeFlag),
viper.GetString(encryptionFlag),
privkey,
viper.GetString(passwordFlag),
identity,
)
},
}
@@ -57,8 +61,7 @@ func query(
block int,
recordSize int,
encryptionFormat string,
privkey []byte,
password string,
identity interface{},
) error {
f, isRegular, err := openTapeReadOnly(tape)
if err != nil {
@@ -126,7 +129,7 @@ func query(
break
}
if err := decryptHeader(hdr, encryptionFormat, privkey, password); err != nil {
if err := decryptHeader(hdr, encryptionFormat, identity); err != nil {
return err
}
@@ -209,7 +212,7 @@ func query(
}
}
if err := decryptHeader(hdr, encryptionFormat, privkey, password); err != nil {
if err := decryptHeader(hdr, encryptionFormat, identity); err != nil {
return err
}

View File

@@ -51,6 +51,11 @@ var restoreCmd = &cobra.Command{
return err
}
identity, err := parseIdentity(viper.GetString(encryptionFlag), privkey, viper.GetString(passwordFlag))
if err != nil {
return err
}
headersToRestore := []*models.Header{}
src := strings.TrimSuffix(viper.GetString(srcFlag), "/")
dbhdr, err := metadataPersister.GetHeader(context.Background(), src)
@@ -117,8 +122,7 @@ var restoreCmd = &cobra.Command{
false,
viper.GetString(compressionFlag),
viper.GetString(encryptionFlag),
privkey,
viper.GetString(passwordFlag),
identity,
); err != nil {
return err
}

View File

@@ -88,8 +88,7 @@ var updateCmd = &cobra.Command{
false,
viper.GetString(compressionFlag),
viper.GetString(encryptionFlag),
[]byte{},
func(hdr *tar.Header, encryptionFormat string, privkey []byte, i int) error {
func(hdr *tar.Header, encryptionFormat string, i int) error {
if len(hdrs) <= i {
return errMissingTarHeader
}