Skip to content

x/crypto/openpgp: ReadMessage(): Panic on invalid input in math/big.nat.div() (division by zero) #11505

Closed
@marete

Description

@marete

The following program panics:

package main

import (
    "bytes"
    "encoding/hex"
    "io"
    "log"
    "os"

    "golang.org/x/crypto/openpgp"
)

// An empty Keyring
type emptyKR struct {
}

func (kr emptyKR) KeysById(id uint64) []openpgp.Key {
    return nil
}

func (kr emptyKR) DecryptionKeys() []openpgp.Key {
    return nil
}

func (kr emptyKR) KeysByIdUsage(uint64, byte) []openpgp.Key {
    return nil
}

var data = "9c3004303030300100000011303030000000000000010130303030303030303030303030303030303030303030303030303030303030303030303030303030303030"

func main() {
    buf, err := hex.DecodeString(data)
    if err != nil {
        log.Fatalln(err)
    }

    md, err := openpgp.ReadMessage(bytes.NewBuffer(buf), emptyKR{},
        func([]openpgp.Key, bool) ([]byte, error) {
            return []byte("insecure"), nil
        }, nil)

    if err != nil {
        log.Fatalln(err)
    }

    _, err = io.Copy(os.Stdout, md.UnverifiedBody)
    if err != nil {
        log.Fatalln(err)
    }

    if md.SignatureError != nil {
        log.Fatalln("integrity check failed")
    }
}

with the trace:

panic: division by zero

goroutine 1 [running]:
math/big.nat.div(0x0, 0x0, 0x0, 0xc20803c570, 0x0, 0x5, 0x0, 0x0, 0x0, 0xc20803c570, ...)
    /opt/go/src/math/big/nat.go:503 +0xcb
math/big.(*Int).QuoRem(0xc208020320, 0xc2080200e0, 0xc2080202e0, 0xc2080202e0, 0x1, 0x5)
    /opt/go/src/math/big/int.go:224 +0xb6
math/big.(*Int).Mod(0xc2080202e0, 0xc2080200e0, 0xc2080202e0, 0xc2080202e0)
    /opt/go/src/math/big/int.go:255 +0x15c
crypto/rsa.(*PrivateKey).Precompute(0xc208068000)
    /opt/go/src/crypto/rsa/rsa.go:376 +0x1ba
golang.org/x/crypto/openpgp/packet.(*PrivateKey).parseRSAPrivateKey(0xc208040000, 0xc208066000, 0x22, 0x600, 0x0, 0x0)
    /home/marebri/devel/go/src/golang.org/x/crypto/openpgp/packet/private_key.go:266 +0x520
golang.org/x/crypto/openpgp/packet.(*PrivateKey).parsePrivateKey(0xc208040000, 0xc208066000, 0x22, 0x600, 0x0, 0x0)
    /home/marebri/devel/go/src/golang.org/x/crypto/openpgp/packet/private_key.go:234 +0x6c
golang.org/x/crypto/openpgp/packet.(*PrivateKey).parse(0xc208040000, 0x7f5e808d1bc0, 0xc208020080, 0x0, 0x0)
    /home/marebri/devel/go/src/golang.org/x/crypto/openpgp/packet/private_key.go:103 +0x3f8
golang.org/x/crypto/openpgp/packet.Read(0x7f5e808d1b60, 0xc2080120e0, 0x7f5e808d1be8, 0xc208040000, 0x0, 0x0)
    /home/marebri/devel/go/src/golang.org/x/crypto/openpgp/packet/packet.go:375 +0x152
golang.org/x/crypto/openpgp/packet.(*Reader).Next(0xc20803c330, 0x0, 0x0, 0x0, 0x0)
    /home/marebri/devel/go/src/golang.org/x/crypto/openpgp/packet/reader.go:37 +0x10c
golang.org/x/crypto/openpgp.ReadMessage(0x7f5e808d1b60, 0xc2080120e0, 0x7f5e808d1b88, 0x68c0a8, 0x5f0860, 0x0, 0xc208062000, 0x0, 0x0)
    /home/marebri/devel/go/src/golang.org/x/crypto/openpgp/read.go:101 +0x206
main.main()
    /home/marebri/devel/lab/go/crypto/openpgp/issues/50eccec52/main.go:40 +0x285

goroutine 2 [runnable]:
runtime.forcegchelper()
    /opt/go/src/runtime/proc.go:90
runtime.goexit()
    /opt/go/src/runtime/asm_amd64.s:2232 +0x1

goroutine 3 [runnable]:
runtime.bgsweep()
    /opt/go/src/runtime/mgc0.go:82
runtime.goexit()
    /opt/go/src/runtime/asm_amd64.s:2232 +0x1

goroutine 4 [runnable]:
runtime.runfinq()
    /opt/go/src/runtime/malloc.go:712
runtime.goexit()
    /opt/go/src/runtime/asm_amd64.s:2232 +0x1

Found using gofuzz. You may assign this issue to me.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions