feat: Start implementation of signed headers

This commit is contained in:
Felicitas Pojtinger
2021-12-04 20:55:25 +01:00
parent 6643d21e9c
commit a21099cfb2
3 changed files with 131 additions and 3 deletions

View File

@@ -349,6 +349,10 @@ func archive(
hdrToAppend := *hdr
headers = append(headers, &hdrToAppend)
if err := signHeader(hdr, signatureFormat, identity); err != nil {
return err
}
if err := encryptHeader(hdr, encryptionFormat, recipient); err != nil {
return err
}
@@ -472,7 +476,38 @@ func encryptHeader(
return err
}
newHdr.PAXRecords[pax.STFSEmbeddedHeader], err = encryptString(string(wrappedHeader), encryptionFormat, recipient)
newHdr.PAXRecords[pax.STFSRecordEmbeddedHeader], err = encryptString(string(wrappedHeader), encryptionFormat, recipient)
if err != nil {
return err
}
*hdr = *newHdr
return nil
}
func signHeader(
hdr *tar.Header,
signatureFormat string,
identity interface{},
) error {
if signatureFormat == noneKey {
return nil
}
newHdr := &tar.Header{
Format: tar.FormatPAX,
Size: hdr.Size,
PAXRecords: map[string]string{},
}
wrappedHeader, err := json.Marshal(hdr)
if err != nil {
return err
}
newHdr.PAXRecords[pax.STFSRecordEmbeddedHeader] = string(wrappedHeader)
newHdr.PAXRecords[pax.STFSRecordSignature], err = signString(newHdr.PAXRecords[pax.STFSRecordEmbeddedHeader], signatureFormat, identity)
if err != nil {
return err
}
@@ -655,6 +690,26 @@ func encryptString(
}
}
func signString(
src string,
signatureFormat string,
identity interface{},
) (string, error) {
switch signatureFormat {
case signatureFormatMinisignKey:
identity, ok := identity.(minisign.PrivateKey)
if !ok {
return "", errIdentityUnparsable
}
return base64.StdEncoding.EncodeToString(minisign.Sign(identity, []byte(src))), nil
case noneKey:
return src, nil
default:
return "", errUnsupportedSignatureFormat
}
}
func compress(
dst io.Writer,
compressionFormat string,

View File

@@ -43,6 +43,8 @@ var (
errIdentityUnparsable = errors.New("recipient could not be parsed")
errInvalidSignature = errors.New("invalid signature")
errSignatureMissing = errors.New("missing signature")
)
var recoveryFetchCmd = &cobra.Command{
@@ -157,6 +159,10 @@ func restoreFromRecordAndBlock(
return err
}
if err := verifyHeader(hdr, signatureFormat, recipient); err != nil {
return err
}
if showHeader {
if err := formatting.PrintCSV(formatting.TARHeaderCSV); err != nil {
return err
@@ -297,7 +303,7 @@ func decryptHeader(
return errEmbeddedHeaderMissing
}
encryptedEmbeddedHeader, ok := hdr.PAXRecords[pax.STFSEmbeddedHeader]
encryptedEmbeddedHeader, ok := hdr.PAXRecords[pax.STFSRecordEmbeddedHeader]
if !ok {
return errEmbeddedHeaderMissing
}
@@ -317,6 +323,43 @@ func decryptHeader(
return nil
}
func verifyHeader(
hdr *tar.Header,
signatureFormat string,
recipient interface{},
) error {
if signatureFormat == noneKey {
return nil
}
if hdr.PAXRecords == nil {
return errEmbeddedHeaderMissing
}
embeddedHeader, ok := hdr.PAXRecords[pax.STFSRecordEmbeddedHeader]
if !ok {
return errEmbeddedHeaderMissing
}
signature, ok := hdr.PAXRecords[pax.STFSRecordSignature]
if !ok {
return errSignatureMissing
}
if err := verifyString(embeddedHeader, signatureFormat, recipient, signature); err != nil {
return err
}
var newHdr tar.Header
if err := json.Unmarshal([]byte(embeddedHeader), &newHdr); err != nil {
return err
}
*hdr = newHdr
return nil
}
func parseIdentity(
encryptionFormat string,
privkey []byte,
@@ -525,6 +568,36 @@ func verify(
}
}
func verifyString(
src string,
signatureFormat string,
recipient interface{},
signature string,
) error {
switch signatureFormat {
case signatureFormatMinisignKey:
recipient, ok := recipient.(minisign.PublicKey)
if !ok {
return errRecipientUnparsable
}
decodedSignature, err := base64.StdEncoding.DecodeString(signature)
if err != nil {
return err
}
if minisign.Verify(recipient, []byte(src), decodedSignature) {
return nil
}
return errInvalidSignature
case noneKey:
return nil
default:
return errUnsupportedSignatureFormat
}
}
func init() {
recoveryFetchCmd.PersistentFlags().IntP(recordSizeFlag, "z", 20, "Amount of 512-bit blocks per record")
recoveryFetchCmd.PersistentFlags().IntP(recordFlag, "k", 0, "Record to seek too")

View File

@@ -23,7 +23,7 @@ const (
STFSRecordSignature = STFSPrefix + "Signature"
STFSEmbeddedHeader = STFSPrefix + "EmbeddedHeader"
STFSRecordEmbeddedHeader = STFSPrefix + "EmbeddedHeader"
)
var (