Skip to content

Commit

Permalink
crypto/x509: mitigate CVE-2020-0601 verification bypass on Windows
Browse files Browse the repository at this point in the history
An attacker can trick the Windows system verifier to use a poisoned set
of elliptic curve parameters for a trusted root, allowing it to generate
spoofed signatures. When this happens, the returned chain will present
the unmodified original root, so the actual signatures won't verify (as
they are invalid for the correct parameters). Simply double check them
as a safety measure and mitigation.

Windows users should still install the system security patch ASAP.

This is the same mitigation adopted by Chromium:

https://chromium-review.googlesource.com/c/chromium/src/+/1994434

Change-Id: I2c734f6fb2cb51d906c7fd77034318ffeeb3e146
Reviewed-on: https://go-review.googlesource.com/c/go/+/215905
Run-TryBot: Filippo Valsorda <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: Ryan Sleevi <[email protected]>
Reviewed-by: Katie Hockman <[email protected]>
  • Loading branch information
FiloSottile committed Jan 23, 2020
1 parent ace25f8 commit 953bc8f
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions src/crypto/x509/root_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,26 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate
if err != nil {
return nil, err
}
if len(chain) < 1 {
return nil, errors.New("x509: internal error: system verifier returned an empty chain")
}

chains = append(chains, chain)
// Mitigate CVE-2020-0601, where the Windows system verifier might be
// tricked into using custom curve parameters for a trusted root, by
// double-checking all ECDSA signatures. If the system was tricked into
// using spoofed parameters, the signature will be invalid for the correct
// ones we parsed. (We don't support custom curves ourselves.)
for i, parent := range chain[1:] {
if parent.PublicKeyAlgorithm != ECDSA {
continue
}
if err := parent.CheckSignature(chain[i].SignatureAlgorithm,
chain[i].RawTBSCertificate, chain[i].Signature); err != nil {
return nil, err
}
}

return chains, nil
return [][]*Certificate{chain}, nil
}

func loadSystemRoots() (*CertPool, error) {
Expand Down

0 comments on commit 953bc8f

Please sign in to comment.