diff options
Diffstat (limited to 'net/third_party/nss/ssl/ssl3con.c')
-rw-r--r-- | net/third_party/nss/ssl/ssl3con.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c index b6f4313..5476fa5 100644 --- a/net/third_party/nss/ssl/ssl3con.c +++ b/net/third_party/nss/ssl/ssl3con.c @@ -5505,6 +5505,30 @@ loser: return SECFailure; } +/* ssl3_BigIntGreaterThan1 returns true iff |mpint|, taken as an unsigned, + * big-endian integer is > 1 */ +static PRBool +ssl3_BigIntGreaterThan1(const SECItem* mpint) { + unsigned char firstNonZeroByte = 0; + unsigned int i; + + for (i = 0; i < mpint->len; i++) { + if (mpint->data[i]) { + firstNonZeroByte = mpint->data[i]; + break; + } + } + + if (firstNonZeroByte == 0) + return PR_FALSE; + if (firstNonZeroByte > 1) + return PR_TRUE; + + // firstNonZeroByte == 1, therefore mpint > 1 iff the first non-zero byte + // is followed by another byte. + return (i < mpint->len - 1); +} + /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete * ssl3 ServerKeyExchange message. * Caller must hold Handshake and RecvBuf locks. @@ -5636,15 +5660,13 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length) if (rv != SECSuccess) { goto loser; /* malformed. */ } - if (dh_g.len == 0 || dh_g.len > dh_p.len + 1 || - (dh_g.len == 1 && dh_g.data[0] == 0)) + if (dh_g.len > dh_p.len || !ssl3_BigIntGreaterThan1(&dh_g)) goto alert_loser; rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length); if (rv != SECSuccess) { goto loser; /* malformed. */ } - if (dh_Ys.len == 0 || dh_Ys.len > dh_p.len + 1 || - (dh_Ys.len == 1 && dh_Ys.data[0] == 0)) + if (dh_Ys.len > dh_p.len || !ssl3_BigIntGreaterThan1(&dh_Ys)) goto alert_loser; rv = ssl3_ConsumeHandshakeVariable(ss, &signature, 2, &b, &length); if (rv != SECSuccess) { |