Skip to content

Commit 953bc8f

Browse files
committed
crypto/x509: mitigate CVE-2020-0601 verification bypass on Windows
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]>
1 parent ace25f8 commit 953bc8f

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

src/crypto/x509/root_windows.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,10 +219,26 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate
219219
if err != nil {
220220
return nil, err
221221
}
222+
if len(chain) < 1 {
223+
return nil, errors.New("x509: internal error: system verifier returned an empty chain")
224+
}
222225

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

225-
return chains, nil
241+
return [][]*Certificate{chain}, nil
226242
}
227243

228244
func loadSystemRoots() (*CertPool, error) {

0 commit comments

Comments
 (0)