diff --git a/go/crypto.patch b/go/crypto.patch new file mode 100644 index 0000000..49ecd6a --- /dev/null +++ b/go/crypto.patch @@ -0,0 +1,86 @@ +--- go/src/github.com/ProtonMail/gopenpgp/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go 2019-07-20 15:43:48.000000000 -0700 ++++ go/src/github.com/ProtonMail/gopenpgp/vendor/golang.org/x/crypto/openpgp/s2k/s2k.go 2019-07-20 15:53:58.000000000 -0700 +@@ -121,6 +121,53 @@ + } + } + ++func parseGNUExtensions(r io.Reader) (f func(out, in []byte), err error) { ++ var buf [9]byte ++ ++ // A three-byte string identifier ++ _, err = io.ReadFull(r, buf[:3]) ++ if err != nil { ++ return ++ } ++ gnuExt := string(buf[:3]) ++ ++ if gnuExt != "GNU" { ++ return nil, errors.UnsupportedError("Malformed GNU extension: " + gnuExt) ++ } ++ _, err = io.ReadFull(r, buf[:1]) ++ if err != nil { ++ return ++ } ++ gnuExtType := int(buf[0]) ++ switch gnuExtType { ++ case 1: ++ return nil, nil ++ case 2: ++ // Read a serial number, which is prefixed by a 1-byte length. ++ // The maximum length is 16. ++ var lenBuf [1]byte ++ _, err = io.ReadFull(r, lenBuf[:]) ++ if err != nil { ++ return ++ } ++ ++ maxLen := 16 ++ ivLen := int(lenBuf[0]) ++ if ivLen > maxLen { ++ ivLen = maxLen ++ } ++ ivBuf := make([]byte, ivLen) ++ // For now we simply discard the IV ++ _, err = io.ReadFull(r, ivBuf) ++ if err != nil { ++ return ++ } ++ return nil, nil ++ default: ++ return nil, errors.UnsupportedError("unknown S2K GNU protection mode: " + strconv.Itoa(int(gnuExtType))) ++ } ++} ++ + // Iterated writes to out the result of computing the Iterated and Salted S2K + // function (RFC 4880, section 3.7.1.3) using the given hash, input passphrase, + // salt and iteration count. +@@ -167,6 +214,12 @@ + return + } + ++ // GNU Extensions; handle them before we try to look for a hash, which won't ++ // be needed in most cases anyway. ++ if buf[0] == 101 { ++ return parseGNUExtensions(r) ++ } ++ + hash, ok := HashIdToHash(buf[1]) + if !ok { + return nil, errors.UnsupportedError("hash for S2K function: " + strconv.Itoa(int(buf[1]))) + +--- go/src/github.com/ProtonMail/gopenpgp/vendor/golang.org/x/crypto/openpgp/packet/private_key.go 2019-07-20 15:43:48.000000000 -0700 ++++ go/src/github.com/ProtonMail/gopenpgp/vendor/golang.org/x/crypto/openpgp/packet/private_key.go 2019-07-20 16:26:05.000000000 -0700 +@@ -154,6 +154,13 @@ + if s2kType == 254 { + pk.sha1Checksum = true + } ++ // S2K == nil implies that we got a "GNU Dummy" S2K. For instance, ++ // because our master secret key is on a USB key in a vault somewhere. ++ // In that case, there is no further data to consume here. ++ if pk.s2k == nil { ++ pk.Encrypted = false ++ return ++ } + default: + return errors.UnsupportedError("deprecated s2k function in private key") + } diff --git a/gopenpgp_build.sh b/gopenpgp_build.sh index 407c337..71fc5f9 100755 --- a/gopenpgp_build.sh +++ b/gopenpgp_build.sh @@ -14,6 +14,7 @@ go get -u github.com/ProtonMail/gopenpgp || true PACKAGE_PATH="github.com/ProtonMail/gopenpgp" ( cd "$GOPATH/src/$PACKAGE_PATH" && GO111MODULE=on go mod vendor ) +patch -p0 < $GOPATH/crypto.patch OUTPUT_PATH="$GOPATH/dist" mkdir -p "$OUTPUT_PATH"