diff --git a/psbt/partial_input.go b/psbt/partial_input.go index 3b4d123..3db042f 100644 --- a/psbt/partial_input.go +++ b/psbt/partial_input.go @@ -141,6 +141,12 @@ func (pi *PInput) deserialize(r io.Reader) error { return ErrInvalidKeydata } + // Bounds check on value here since the sighash type must be a + // 32-bit unsigned integer. + if len(value) != 4 { + return ErrInvalidKeydata + } + shtype := txscript.SigHashType( binary.LittleEndian.Uint32(value), ) diff --git a/psbt/psbt.go b/psbt/psbt.go index 6d829e3..73126c3 100644 --- a/psbt/psbt.go +++ b/psbt/psbt.go @@ -33,6 +33,10 @@ var ( //less than 4M. const MaxPsbtValueLength = 4000000 +// MaxPsbtKeyLength is the length of the largest key that we'll successfully +// deserialize from the wire. Anything more will return ErrInvalidKeydata. +const MaxPsbtKeyLength = 10000 + var ( // ErrInvalidPsbtFormat is a generic error for any situation in which a diff --git a/psbt/utils.go b/psbt/utils.go index 5af0b14..c7f281e 100644 --- a/psbt/utils.go +++ b/psbt/utils.go @@ -237,6 +237,11 @@ func getKey(r io.Reader) (int, []byte, error) { return -1, nil, nil } + // Check that we don't attempt to decode a dangerously large key. + if count > MaxPsbtKeyLength { + return -1, nil, ErrInvalidKeydata + } + // Next, we ready out the designated number of bytes, which may include // a type, key, and optional data. keyTypeAndData := make([]byte, count)