Bug 1166031 - Update NSS to NSS_3_19_1_BETA1. r=mt

This commit is contained in:
Ryan VanderMeulen 2015-05-20 21:06:06 -04:00
parent 05ad7f7385
commit b1647b5e41
20 changed files with 165 additions and 136 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please # changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more. # don't change CLOBBER for WebIDL changes any more.
Bug 1163201 needs clobber. Bug 1166031 - NSS update hit needs-clobber bustage.

View File

@ -1 +1 @@
NSS_3_19_RTM NSS_3_19_1_BETA1

View File

@ -180,7 +180,7 @@ AddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, char *name, char *trusts,
static SECStatus static SECStatus
CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType, CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
SECOidTag hashAlgTag, CERTName *subject, char *phone, int ascii, SECOidTag hashAlgTag, CERTName *subject, const char *phone, int ascii,
const char *emailAddrs, const char *dnsNames, const char *emailAddrs, const char *dnsNames,
certutilExtnList extnList, const char *extGeneric, certutilExtnList extnList, const char *extGeneric,
/*out*/ SECItem *result) /*out*/ SECItem *result)
@ -270,7 +270,7 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
} }
if (!phone) if (!phone)
phone = strdup("(not specified)"); phone = "(not specified)";
email = CERT_GetCertEmailAddress(subject); email = CERT_GetCertEmailAddress(subject);
if (!email) if (!email)
@ -323,6 +323,7 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
} }
PR_smprintf_free(header); PR_smprintf_free(header);
} }
PORT_Free(obuf);
} else { } else {
(void) SECITEM_CopyItem(NULL, result, &signedReq); (void) SECITEM_CopyItem(NULL, result, &signedReq);
} }

View File

@ -10,3 +10,4 @@
*/ */
#error "Do not include this header file." #error "Do not include this header file."

View File

@ -30,8 +30,5 @@ INCLUDES += -I.
# To create a loadable module on Darwin, we must use -bundle. # To create a loadable module on Darwin, we must use -bundle.
# #
ifeq ($(OS_TARGET),Darwin) ifeq ($(OS_TARGET),Darwin)
ifndef USE_64
DSO_LDOPTS = -bundle DSO_LDOPTS = -bundle
endif endif
endif

View File

@ -27,8 +27,5 @@ endif
# To create a loadable module on Darwin, we must use -bundle. # To create a loadable module on Darwin, we must use -bundle.
# #
ifeq ($(OS_TARGET),Darwin) ifeq ($(OS_TARGET),Darwin)
ifndef USE_64
DSO_LDOPTS = -bundle DSO_LDOPTS = -bundle
endif endif
endif

View File

@ -37,6 +37,11 @@ extern SECStatus SECKEY_CopySubjectPublicKeyInfo(PLArenaPool *arena,
extern SECStatus extern SECStatus
SECKEY_UpdateCertPQG(CERTCertificate * subjectCert); SECKEY_UpdateCertPQG(CERTCertificate * subjectCert);
/*
** Return the number of bits in the provided big integer. This assumes that the
** SECItem contains a big-endian number and counts from the first non-zero bit.
*/
extern unsigned SECKEY_BigIntegerBitLength(const SECItem *number);
/* /*
** Return the strength of the public key in bytes ** Return the strength of the public key in bytes

View File

@ -178,8 +178,8 @@ SECKEY_CreateDHPrivateKey(SECKEYDHParams *param, SECKEYPublicKey **pubk, void *c
PK11SlotInfo *slot; PK11SlotInfo *slot;
if (!param || !param->base.data || !param->prime.data || if (!param || !param->base.data || !param->prime.data ||
param->prime.len < 512/8 || param->base.len == 0 || SECKEY_BigIntegerBitLength(&param->prime) < DH_MIN_P_BITS ||
param->base.len > param->prime.len + 1 || param->base.len == 0 || param->base.len > param->prime.len + 1 ||
(param->base.len == 1 && param->base.data[0] == 0)) { (param->base.len == 1 && param->base.data[0] == 0)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL; return NULL;
@ -941,61 +941,76 @@ SECKEY_ECParamsToBasePointOrderLen(const SECItem *encodedParams)
} }
} }
/* The number of bits in the number from the first non-zero bit onward. */
unsigned
SECKEY_BigIntegerBitLength(const SECItem *number)
{
const unsigned char *p;
unsigned octets;
unsigned bits;
if (!number || !number->data) {
PORT_SetError(SEC_ERROR_INVALID_KEY);
return 0;
}
p = number->data;
octets = number->len;
while (octets > 0 && !*p) {
++p;
--octets;
}
if (octets == 0) {
return 0;
}
/* bits = 7..1 because we know at least one bit is set already */
/* Note: This could do a binary search, but this is faster for keys if we
* assume that good keys will have the MSB set. */
for (bits = 7; bits > 0; --bits) {
if (*p & (1 << bits)) {
break;
}
}
return octets * 8 + bits - 7;
}
/* returns key strength in bytes (not bits) */ /* returns key strength in bytes (not bits) */
unsigned unsigned
SECKEY_PublicKeyStrength(const SECKEYPublicKey *pubk) SECKEY_PublicKeyStrength(const SECKEYPublicKey *pubk)
{ {
unsigned char b0; return (SECKEY_PublicKeyStrengthInBits(pubk) + 7) / 8;
unsigned size;
/* interpret modulus length as key strength */
if (!pubk)
goto loser;
switch (pubk->keyType) {
case rsaKey:
if (!pubk->u.rsa.modulus.data) break;
b0 = pubk->u.rsa.modulus.data[0];
return b0 ? pubk->u.rsa.modulus.len : pubk->u.rsa.modulus.len - 1;
case dsaKey:
if (!pubk->u.dsa.publicValue.data) break;
b0 = pubk->u.dsa.publicValue.data[0];
return b0 ? pubk->u.dsa.publicValue.len :
pubk->u.dsa.publicValue.len - 1;
case dhKey:
if (!pubk->u.dh.publicValue.data) break;
b0 = pubk->u.dh.publicValue.data[0];
return b0 ? pubk->u.dh.publicValue.len :
pubk->u.dh.publicValue.len - 1;
case ecKey:
/* Get the key size in bits and adjust */
size = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
return (size + 7)/8;
default:
break;
}
loser:
PORT_SetError(SEC_ERROR_INVALID_KEY);
return 0;
} }
/* returns key strength in bits */ /* returns key strength in bits */
unsigned unsigned
SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk) SECKEY_PublicKeyStrengthInBits(const SECKEYPublicKey *pubk)
{ {
unsigned size; unsigned bitSize = 0;
if (!pubk) {
PORT_SetError(SEC_ERROR_INVALID_KEY);
return 0;
}
/* interpret modulus length as key strength */
switch (pubk->keyType) { switch (pubk->keyType) {
case rsaKey: case rsaKey:
bitSize = SECKEY_BigIntegerBitLength(&pubk->u.rsa.modulus);
break;
case dsaKey: case dsaKey:
bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dsa.publicValue);
break;
case dhKey: case dhKey:
return SECKEY_PublicKeyStrength(pubk) * 8; /* 1 byte = 8 bits */ bitSize = SECKEY_BigIntegerBitLength(&pubk->u.dh.publicValue);
break;
case ecKey: case ecKey:
size = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams); bitSize = SECKEY_ECParamsToKeySize(&pubk->u.ec.DEREncodedParams);
return size; break;
default: default:
break; PORT_SetError(SEC_ERROR_INVALID_KEY);
break;
} }
PORT_SetError(SEC_ERROR_INVALID_KEY); return bitSize;
return 0;
} }
/* returns signature length in bytes (not bits) */ /* returns signature length in bytes (not bits) */

View File

@ -138,10 +138,13 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
* These values come from the initial key size limits from the PKCS #11 * These values come from the initial key size limits from the PKCS #11
* module. They may be arbitrarily adjusted to any value freebl supports. * module. They may be arbitrarily adjusted to any value freebl supports.
*/ */
#define RSA_MIN_MODULUS_BITS 128 #define RSA_MIN_MODULUS_BITS 512
#define RSA_MAX_MODULUS_BITS 16384 #define RSA_MAX_MODULUS_BITS 16384
#define RSA_MAX_EXPONENT_BITS 64 #define RSA_MAX_EXPONENT_BITS 64
#define DH_MIN_P_BITS 128 /* 1023 to avoid cases where p = 2q+1 for a 512-bit q turns out to be
* only 1023 bits and similar. We don't have good data on whether this
* happens because NSS used to count bit lengths incorrectly. */
#define DH_MIN_P_BITS 1023
#define DH_MAX_P_BITS 16384 #define DH_MAX_P_BITS 16384
/* /*
@ -181,7 +184,7 @@ typedef int __BLAPI_DEPRECATED __attribute__((deprecated));
#define DSA1_Q_BITS 160 #define DSA1_Q_BITS 160
#define DSA_MAX_P_BITS 3072 #define DSA_MAX_P_BITS 3072
#define DSA_MIN_P_BITS 512 #define DSA_MIN_P_BITS 1023
#define DSA_MAX_Q_BITS 256 #define DSA_MAX_Q_BITS 256
#define DSA_MIN_Q_BITS 160 #define DSA_MIN_Q_BITS 160

View File

@ -144,6 +144,20 @@ ec_GFp_pt_add_jac_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
MP_CHECKOK(group->meth->field_sub(&A, px, &C, group->meth)); MP_CHECKOK(group->meth->field_sub(&A, px, &C, group->meth));
MP_CHECKOK(group->meth->field_sub(&B, py, &D, group->meth)); MP_CHECKOK(group->meth->field_sub(&B, py, &D, group->meth));
if (mp_cmp_z(&C) == 0) {
/* P == Q or P == -Q */
if (mp_cmp_z(&D) == 0) {
/* P == Q */
/* It is cheaper to double (qx, qy, 1) than (px, py, pz). */
MP_DIGIT(&D, 0) = 1; /* Set D to 1. */
MP_CHECKOK(ec_GFp_pt_dbl_jac(qx, qy, &D, rx, ry, rz, group));
} else {
/* P == -Q */
MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
}
goto CLEANUP;
}
/* C2 = C^2, C3 = C^3 */ /* C2 = C^2, C3 = C^3 */
MP_CHECKOK(group->meth->field_sqr(&C, &C2, group->meth)); MP_CHECKOK(group->meth->field_sqr(&C, &C2, group->meth));
MP_CHECKOK(group->meth->field_mul(&C, &C2, &C3, group->meth)); MP_CHECKOK(group->meth->field_mul(&C, &C2, &C3, group->meth));
@ -205,7 +219,8 @@ ec_GFp_pt_dbl_jac(const mp_int *px, const mp_int *py, const mp_int *pz,
MP_CHECKOK(mp_init(&M)); MP_CHECKOK(mp_init(&M));
MP_CHECKOK(mp_init(&S)); MP_CHECKOK(mp_init(&S));
if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES) { /* P == inf or P == -P */
if (ec_GFp_pt_is_inf_jac(px, py, pz) == MP_YES || mp_cmp_z(py) == 0) {
MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz)); MP_CHECKOK(ec_GFp_pt_set_inf_jac(rx, ry, rz));
goto CLEANUP; goto CLEANUP;
} }

View File

@ -16,7 +16,7 @@
* output that is still field-encoded. * output that is still field-encoded.
* *
*/ */
mp_err static mp_err
ec_GFp_pt_dbl_jm(const mp_int *px, const mp_int *py, const mp_int *pz, ec_GFp_pt_dbl_jm(const mp_int *px, const mp_int *py, const mp_int *pz,
const mp_int *paz4, mp_int *rx, mp_int *ry, mp_int *rz, const mp_int *paz4, mp_int *rx, mp_int *ry, mp_int *rz,
mp_int *raz4, mp_int scratch[], const ECGroup *group) mp_int *raz4, mp_int scratch[], const ECGroup *group)
@ -86,7 +86,7 @@ ec_GFp_pt_dbl_jm(const mp_int *px, const mp_int *py, const mp_int *pz,
* Uses mixed Modified_Jacobian-affine coordinates. Assumes input is * Uses mixed Modified_Jacobian-affine coordinates. Assumes input is
* already field-encoded using field_enc, and returns output that is still * already field-encoded using field_enc, and returns output that is still
* field-encoded. */ * field-encoded. */
mp_err static mp_err
ec_GFp_pt_add_jm_aff(const mp_int *px, const mp_int *py, const mp_int *pz, ec_GFp_pt_add_jm_aff(const mp_int *px, const mp_int *py, const mp_int *pz,
const mp_int *paz4, const mp_int *qx, const mp_int *paz4, const mp_int *qx,
const mp_int *qy, mp_int *rx, mp_int *ry, mp_int *rz, const mp_int *qy, mp_int *rx, mp_int *ry, mp_int *rz,

View File

@ -1076,3 +1076,9 @@ CERT_GetImposedNameConstraints;
;+ local: ;+ local:
;+ *; ;+ *;
;+}; ;+};
;+NSS_3.19.1 { # NSS 3.19.1 release
;+ global:
SECKEY_BigIntegerBitLength;
;+ local:
;+ *;
;+};

View File

@ -33,12 +33,12 @@
* The format of the version string should be * The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]" * "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/ */
#define NSS_VERSION "3.19" _NSS_ECC_STRING _NSS_CUSTOMIZED #define NSS_VERSION "3.19.1" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta"
#define NSS_VMAJOR 3 #define NSS_VMAJOR 3
#define NSS_VMINOR 19 #define NSS_VMINOR 19
#define NSS_VPATCH 0 #define NSS_VPATCH 1
#define NSS_VBUILD 0 #define NSS_VBUILD 0
#define NSS_BETA PR_FALSE #define NSS_BETA PR_TRUE
#ifndef RC_INVOKED #ifndef RC_INVOKED

View File

@ -1247,7 +1247,7 @@ loser:
PORT_ZFree(newKey.data,newKey.len); PORT_ZFree(newKey.data,newKey.len);
} }
if (result) { if (result) {
SECITEM_FreeItem(result, PR_FALSE); SECITEM_FreeItem(result, PR_TRUE);
} }
if (rv != SECSuccess) { if (rv != SECSuccess) {
(*keydb->db->sdb_Abort)(keydb->db); (*keydb->db->sdb_Abort)(keydb->db);

View File

@ -25,11 +25,11 @@
* The format of the version string should be * The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]" * "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/ */
#define SOFTOKEN_VERSION "3.19" SOFTOKEN_ECC_STRING #define SOFTOKEN_VERSION "3.19.1" SOFTOKEN_ECC_STRING " Beta"
#define SOFTOKEN_VMAJOR 3 #define SOFTOKEN_VMAJOR 3
#define SOFTOKEN_VMINOR 19 #define SOFTOKEN_VMINOR 19
#define SOFTOKEN_VPATCH 0 #define SOFTOKEN_VPATCH 1
#define SOFTOKEN_VBUILD 0 #define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_FALSE #define SOFTOKEN_BETA PR_TRUE
#endif /* _SOFTKVER_H_ */ #endif /* _SOFTKVER_H_ */

View File

@ -422,3 +422,6 @@ ER3(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL, (SSL_ERROR_BASE + 130),
ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 131), ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 131),
"The server rejected the handshake because the client downgraded to a lower " "The server rejected the handshake because the client downgraded to a lower "
"TLS version than the server supports.") "TLS version than the server supports.")
ER3(SSL_ERROR_WEAK_SERVER_CERT_KEY, (SSL_ERROR_BASE + 132),
"The server certificate included a public key that was too weak.")

View File

@ -5401,9 +5401,7 @@ ssl3_HandleHelloRequest(sslSocket *ss)
return SECFailure; return SECFailure;
} }
if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) { if (ss->opt.enableRenegotiation == SSL_RENEGOTIATE_NEVER) {
ssl_GetXmitBufLock(ss); (void)SSL3_SendAlert(ss, alert_warning, no_renegotiation);
rv = SSL3_SendAlert(ss, alert_warning, no_renegotiation);
ssl_ReleaseXmitBufLock(ss);
PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED); PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
return SECFailure; return SECFailure;
} }
@ -6601,29 +6599,6 @@ loser:
return SECFailure; return SECFailure;
} }
/* ssl3_BigIntGreaterThanOne returns true iff |mpint|, taken as an unsigned,
* big-endian integer is > 1 */
static PRBool
ssl3_BigIntGreaterThanOne(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 /* Called from ssl3_HandleHandshakeMessage() when it has deciphered a complete
* ssl3 ServerKeyExchange message. * ssl3 ServerKeyExchange message.
@ -6668,6 +6643,12 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (rv != SECSuccess) { if (rv != SECSuccess) {
goto loser; /* malformed. */ goto loser; /* malformed. */
} }
/* This exchange method is only used by export cipher suites.
* Those are broken and so this code will eventually be removed. */
if (SECKEY_BigIntegerBitLength(&modulus) < 512) {
desc = isTLS ? insufficient_security : illegal_parameter;
goto alert_loser;
}
rv = ssl3_ConsumeHandshakeVariable(ss, &exponent, 2, &b, &length); rv = ssl3_ConsumeHandshakeVariable(ss, &exponent, 2, &b, &length);
if (rv != SECSuccess) { if (rv != SECSuccess) {
goto loser; /* malformed. */ goto loser; /* malformed. */
@ -6753,12 +6734,16 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
SECItem dh_p = {siBuffer, NULL, 0}; SECItem dh_p = {siBuffer, NULL, 0};
SECItem dh_g = {siBuffer, NULL, 0}; SECItem dh_g = {siBuffer, NULL, 0};
SECItem dh_Ys = {siBuffer, NULL, 0}; SECItem dh_Ys = {siBuffer, NULL, 0};
unsigned dh_p_bits;
unsigned dh_g_bits;
unsigned dh_Ys_bits;
rv = ssl3_ConsumeHandshakeVariable(ss, &dh_p, 2, &b, &length); rv = ssl3_ConsumeHandshakeVariable(ss, &dh_p, 2, &b, &length);
if (rv != SECSuccess) { if (rv != SECSuccess) {
goto loser; /* malformed. */ goto loser; /* malformed. */
} }
if (dh_p.len < 512/8) { dh_p_bits = SECKEY_BigIntegerBitLength(&dh_p);
if (dh_p_bits < DH_MIN_P_BITS) {
errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY; errCode = SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY;
goto alert_loser; goto alert_loser;
} }
@ -6766,13 +6751,16 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (rv != SECSuccess) { if (rv != SECSuccess) {
goto loser; /* malformed. */ goto loser; /* malformed. */
} }
if (dh_g.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_g)) /* Abort if dh_g is 0, 1, or obviously too big. */
dh_g_bits = SECKEY_BigIntegerBitLength(&dh_g);
if (dh_g_bits > dh_p_bits || dh_g_bits <= 1)
goto alert_loser; goto alert_loser;
rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length); rv = ssl3_ConsumeHandshakeVariable(ss, &dh_Ys, 2, &b, &length);
if (rv != SECSuccess) { if (rv != SECSuccess) {
goto loser; /* malformed. */ goto loser; /* malformed. */
} }
if (dh_Ys.len > dh_p.len || !ssl3_BigIntGreaterThanOne(&dh_Ys)) dh_Ys_bits = SECKEY_BigIntegerBitLength(&dh_Ys);
if (dh_Ys_bits > dh_p_bits || dh_Ys_bits <= 1)
goto alert_loser; goto alert_loser;
if (isTLS12) { if (isTLS12) {
rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length, rv = ssl3_ConsumeSignatureAndHashAlgorithm(ss, &b, &length,
@ -8881,6 +8869,10 @@ ssl3_SendServerKeyExchange(sslSocket *ss)
2 + sdPub->u.rsa.publicExponent.len + 2 + sdPub->u.rsa.publicExponent.len +
2 + signed_hash.len; 2 + signed_hash.len;
if (ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2) {
length += 2;
}
rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length); rv = ssl3_AppendHandshakeHeader(ss, server_key_exchange, length);
if (rv != SECSuccess) { if (rv != SECSuccess) {
goto loser; /* err set by AppendHandshake. */ goto loser; /* err set by AppendHandshake. */
@ -10055,33 +10047,25 @@ ssl3_AuthCertificate(sslSocket *ss)
if (pubKey) { if (pubKey) {
ss->sec.keaKeyBits = ss->sec.authKeyBits = ss->sec.keaKeyBits = ss->sec.authKeyBits =
SECKEY_PublicKeyStrengthInBits(pubKey); SECKEY_PublicKeyStrengthInBits(pubKey);
#ifndef NSS_DISABLE_ECC KeyType pubKeyType = SECKEY_GetPublicKeyType(pubKey);
if (ss->sec.keaType == kt_ecdh) { /* Too small: not good enough. Send a fatal alert. */
/* Get authKeyBits from signing key. /* TODO: Use 1023 for RSA because a higher RSA_MIN_MODULUS_BITS
* XXX The code below uses a quick approximation of * breaks export cipher suites, not 1024 to be conservative; when
* key size based on cert->signatureWrap.signature.data * export removed, increase RSA_MIN_MODULUS_BITS and use that. */
* (which contains the DER encoded signature). The field /* We aren't checking EC here on the understanding that we only
* cert->signatureWrap.signature.len contains the * support curves we like, a decision that might need revisiting. */
* length of the encoded signature in bits. if (((pubKeyType == rsaKey || pubKeyType == rsaPssKey ||
*/ pubKeyType == rsaOaepKey) && ss->sec.authKeyBits < 1023) ||
if (ss->ssl3.hs.kea_def->kea == kea_ecdh_ecdsa) { (pubKeyType == dsaKey && ss->sec.authKeyBits < DSA_MIN_P_BITS) ||
ss->sec.authKeyBits = (pubKeyType == dhKey && ss->sec.authKeyBits < DH_MIN_P_BITS)) {
cert->signatureWrap.signature.data[3]*8; PORT_SetError(SSL_ERROR_WEAK_SERVER_CERT_KEY);
if (cert->signatureWrap.signature.data[4] == 0x00) (void)SSL3_SendAlert(ss, alert_fatal,
ss->sec.authKeyBits -= 8; ss->version >= SSL_LIBRARY_VERSION_TLS_1_0
/* ? insufficient_security
* XXX: if cert is not signed by ecdsa we should : illegal_parameter);
* destroy pubKey and goto bad_cert SECKEY_DestroyPublicKey(pubKey);
*/ return SECFailure;
} else if (ss->ssl3.hs.kea_def->kea == kea_ecdh_rsa) { }
ss->sec.authKeyBits = cert->signatureWrap.signature.len;
/*
* XXX: if cert is not signed by rsa we should
* destroy pubKey and goto bad_cert
*/
}
}
#endif /* NSS_DISABLE_ECC */
SECKEY_DestroyPublicKey(pubKey); SECKEY_DestroyPublicKey(pubKey);
pubKey = NULL; pubKey = NULL;
} }

View File

@ -625,8 +625,8 @@ ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data)
rv = ssl3_ValidateNextProtoNego(data->data, data->len); rv = ssl3_ValidateNextProtoNego(data->data, data->len);
if (rv != SECSuccess) { if (rv != SECSuccess) {
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error); (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return rv; return rv;
} }
@ -653,8 +653,8 @@ ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data)
ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) { ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) {
/* The callback might say OK, but then it picks a default value - one /* The callback might say OK, but then it picks a default value - one
* that was not listed. That's OK for NPN, but not ALPN. */ * that was not listed. That's OK for NPN, but not ALPN. */
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL);
(void)SSL3_SendAlert(ss, alert_fatal, no_application_protocol); (void)SSL3_SendAlert(ss, alert_fatal, no_application_protocol);
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL);
return SECFailure; return SECFailure;
} }
@ -673,8 +673,8 @@ ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
* despite it being permitted by the spec. */ * despite it being permitted by the spec. */
if (ss->firstHsDone || data->len == 0) { if (ss->firstHsDone || data->len == 0) {
/* Clients MUST send a non-empty ALPN extension. */ /* Clients MUST send a non-empty ALPN extension. */
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure; return SECFailure;
} }
@ -701,8 +701,8 @@ ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
rv = ssl3_RegisterServerHelloExtensionSender( rv = ssl3_RegisterServerHelloExtensionSender(
ss, ex_type, ssl3_ServerSendAppProtoXtn); ss, ex_type, ssl3_ServerSendAppProtoXtn);
if (rv != SECSuccess) { if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
(void)SSL3_SendAlert(ss, alert_fatal, internal_error); (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return rv; return rv;
} }
} }
@ -722,8 +722,8 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
* we've negotiated NPN then we're required to send the NPN handshake * we've negotiated NPN then we're required to send the NPN handshake
* message. Thus, these two extensions cannot both be negotiated on the * message. Thus, these two extensions cannot both be negotiated on the
* same connection. */ * same connection. */
PORT_SetError(SSL_ERROR_BAD_SERVER);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
PORT_SetError(SSL_ERROR_BAD_SERVER);
return SECFailure; return SECFailure;
} }
@ -733,8 +733,8 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
* we sent the ClientHello and now. */ * we sent the ClientHello and now. */
if (!ss->nextProtoCallback) { if (!ss->nextProtoCallback) {
PORT_Assert(0); PORT_Assert(0);
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK);
(void)SSL3_SendAlert(ss, alert_fatal, internal_error); (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK);
return SECFailure; return SECFailure;
} }
@ -758,16 +758,16 @@ ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
* uint8 len; // where len >= 1 * uint8 len; // where len >= 1
* uint8 protocol_name[len]; */ * uint8 protocol_name[len]; */
if (data->len < 4 || data->len > 2 + 1 + 255) { if (data->len < 4 || data->len > 2 + 1 + 255) {
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error); (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure; return SECFailure;
} }
list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); list_len = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len);
/* The list has to be the entire extension. */ /* The list has to be the entire extension. */
if (list_len != data->len) { if (list_len != data->len) {
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error); (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure; return SECFailure;
} }
@ -775,8 +775,8 @@ ssl3_ClientHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
&data->data, &data->len); &data->data, &data->len);
/* The list must have exactly one value. */ /* The list must have exactly one value. */
if (rv != SECSuccess || data->len != 0) { if (rv != SECSuccess || data->len != 0) {
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error); (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
return SECFailure; return SECFailure;
} }
@ -2063,8 +2063,8 @@ ssl3_HandleRenegotiationInfoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data)
} }
if (len && NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data, if (len && NSS_SecureMemcmp(ss->ssl3.hs.finishedMsgs.data,
data->data + 1, len)) { data->data + 1, len)) {
PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
(void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure);
PORT_SetError(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE);
return SECFailure; return SECFailure;
} }
/* remember that we got this extension and it was correct. */ /* remember that we got this extension and it was correct. */
@ -2188,8 +2188,8 @@ ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
} }
if (!found) { if (!found) {
PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
return SECFailure; return SECFailure;
} }
@ -2202,8 +2202,8 @@ ssl3_ClientHandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
/* We didn't offer an MKI, so this must be 0 length */ /* We didn't offer an MKI, so this must be 0 length */
if (litem.len != 0) { if (litem.len != 0) {
PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
(void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter); (void)SSL3_SendAlert(ss, alert_fatal, illegal_parameter);
PORT_SetError(SSL_ERROR_RX_MALFORMED_SERVER_HELLO);
return SECFailure; return SECFailure;
} }
@ -2313,8 +2313,8 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
} }
/* Trailing data, empty value, or odd-length value is invalid. */ /* Trailing data, empty value, or odd-length value is invalid. */
if (data->len != 0 || algorithms.len == 0 || (algorithms.len & 1) != 0) { if (data->len != 0 || algorithms.len == 0 || (algorithms.len & 1) != 0) {
PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
(void)SSL3_SendAlert(ss, alert_fatal, decode_error); (void)SSL3_SendAlert(ss, alert_fatal, decode_error);
PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
return SECFailure; return SECFailure;
} }
@ -2328,8 +2328,8 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
ss->ssl3.hs.clientSigAndHash = ss->ssl3.hs.clientSigAndHash =
PORT_NewArray(SSL3SignatureAndHashAlgorithm, numAlgorithms); PORT_NewArray(SSL3SignatureAndHashAlgorithm, numAlgorithms);
if (!ss->ssl3.hs.clientSigAndHash) { if (!ss->ssl3.hs.clientSigAndHash) {
PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
(void)SSL3_SendAlert(ss, alert_fatal, internal_error); (void)SSL3_SendAlert(ss, alert_fatal, internal_error);
PORT_SetError(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO);
return SECFailure; return SECFailure;
} }
ss->ssl3.hs.numClientSigAndHash = 0; ss->ssl3.hs.numClientSigAndHash = 0;

View File

@ -198,6 +198,8 @@ SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL = (SSL_ERROR_BASE + 130),
SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 131), SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 131),
SSL_ERROR_WEAK_SERVER_CERT_KEY = (SSL_ERROR_BASE + 132),
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
} SSLErrorCodes; } SSLErrorCodes;
#endif /* NO_SECURITY_ERROR_ENUM */ #endif /* NO_SECURITY_ERROR_ENUM */

View File

@ -19,12 +19,12 @@
* The format of the version string should be * The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]" * "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
*/ */
#define NSSUTIL_VERSION "3.19" #define NSSUTIL_VERSION "3.19.1 Beta"
#define NSSUTIL_VMAJOR 3 #define NSSUTIL_VMAJOR 3
#define NSSUTIL_VMINOR 19 #define NSSUTIL_VMINOR 19
#define NSSUTIL_VPATCH 0 #define NSSUTIL_VPATCH 1
#define NSSUTIL_VBUILD 0 #define NSSUTIL_VBUILD 0
#define NSSUTIL_BETA PR_FALSE #define NSSUTIL_BETA PR_TRUE
SEC_BEGIN_PROTOS SEC_BEGIN_PROTOS