Bug 480514: Prune the supported_signature_algorithms field of our
TLS 1.2 CertificateRequest message to reflect the limitation that
we only support TLS 1.2 CertificateVerify messages that use the
handshake hash (which is always SHA256). r=agl.
--- a/lib/ssl/ssl3con.c
+++ b/lib/ssl/ssl3con.c
@@ -193,29 +193,28 @@ compressionEnabled(sslSocket *ss, SSLCom
static const /*SSL3ClientCertificateType */ PRUint8 certificate_types [] = {
ct_RSA_sign,
#ifdef NSS_ENABLE_ECC
ct_ECDSA_sign,
#endif /* NSS_ENABLE_ECC */
ct_DSS_sign,
};
-/* This block is our supported_signature_algorithms value, in wire format.
- * See https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
+/* This block is the contents of the supported_signature_algorithms field of
+ * our TLS 1.2 CertificateRequest message, in wire format. See
+ * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
+ *
+ * This block contains only sha256 entries because we only support TLS 1.2
+ * CertificateVerify messages that use the handshake hash. */
static const PRUint8 supported_signature_algorithms[] = {
tls_hash_sha256, tls_sig_rsa,
- tls_hash_sha384, tls_sig_rsa,
- tls_hash_sha1, tls_sig_rsa,
#ifdef NSS_ENABLE_ECC
tls_hash_sha256, tls_sig_ecdsa,
- tls_hash_sha384, tls_sig_ecdsa,
- tls_hash_sha1, tls_sig_ecdsa,
#endif
tls_hash_sha256, tls_sig_dsa,
- tls_hash_sha1, tls_sig_dsa,
};
#define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
/* This global item is used only in servers. It is is initialized by
** SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest().
*/
@@ -3955,33 +3954,16 @@ ssl3_AppendSignatureAndHashAlgorithm(
return SECFailure;
}
serialized[1] = sigAndHash->sigAlg;
return ssl3_AppendHandshake(ss, serialized, sizeof(serialized));
}
-/* Appends our supported_signature_algorithms value to the current handshake
- * message. */
-SECStatus
-ssl3_AppendSupportedSignatureAlgorithms(sslSocket *ss)
-{
- return ssl3_AppendHandshakeVariable(ss, supported_signature_algorithms,
- sizeof(supported_signature_algorithms),
- 2);
-}
-
-/* Returns the size in bytes of our supported_signature_algorithms value. */
-unsigned int
-ssl3_SizeOfSupportedSignatureAlgorithms(void)
-{
- return sizeof(supported_signature_algorithms);
-}
-
/**************************************************************************
* Consume Handshake functions.
*
* All data used in these functions is protected by two locks,
* the RecvBufLock and the SSL3HandshakeLock
**************************************************************************/
/* Read up the next "bytes" number of bytes from the (decrypted) input
@@ -8353,23 +8335,25 @@ loser:
static SECStatus
ssl3_SendCertificateRequest(sslSocket *ss)
{
PRBool isTLS12;
SECItem * name;
CERTDistNames *ca_list;
const PRUint8 *certTypes;
+ const PRUint8 *sigAlgs;
SECItem * names = NULL;
SECStatus rv;
int length;
int i;
int calen = 0;
int nnames = 0;
int certTypesLength;
+ int sigAlgsLength;
SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake",
SSL_GETPID(), ss->fd));
PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
@@ -8386,32 +8370,34 @@ ssl3_SendCertificateRequest(sslSocket *s
}
for (i = 0, name = names; i < nnames; i++, name++) {
calen += 2 + name->len;
}
certTypes = certificate_types;
certTypesLength = sizeof certificate_types;
+ sigAlgs = supported_signature_algorithms;
+ sigAlgsLength = sizeof supported_signature_algorithms;
length = 1 + certTypesLength + 2 + calen;
if (isTLS12) {
- length += 2 + ssl3_SizeOfSupportedSignatureAlgorithms();
+ length += 2 + sigAlgsLength;
}
rv = ssl3_AppendHandshakeHeader(ss, certificate_request, length);
if (rv != SECSuccess) {
return rv; /* err set by AppendHandshake. */
}
rv = ssl3_AppendHandshakeVariable(ss, certTypes, certTypesLength, 1);
if (rv != SECSuccess) {
return rv; /* err set by AppendHandshake. */
}
if (isTLS12) {
- rv = ssl3_AppendSupportedSignatureAlgorithms(ss);
+ rv = ssl3_AppendHandshakeVariable(ss, sigAlgs, sigAlgsLength, 2);
if (rv != SECSuccess) {
return rv; /* err set by AppendHandshake. */
}
}
rv = ssl3_AppendHandshakeNumber(ss, calen, 2);
if (rv != SECSuccess) {
return rv; /* err set by AppendHandshake. */
}
--- a/lib/ssl/ssl3ext.c
+++ b/lib/ssl/ssl3ext.c
@@ -2076,37 +2076,53 @@ ssl3_ServerHandleSigAlgsXtn(sslSocket *
return SECSuccess;
}
/* ssl3_ClientSendSigAlgsXtn sends the signature_algorithm extension for TLS
* 1.2 ClientHellos. */
static PRInt32
ssl3_ClientSendSigAlgsXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes)
{
+ static const unsigned char signatureAlgorithms[] = {
+ /* This block is the contents of our signature_algorithms extension, in
+ * wire format. See
+ * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
+ tls_hash_sha256, tls_sig_rsa,
+ tls_hash_sha384, tls_sig_rsa,
+ tls_hash_sha1, tls_sig_rsa,
+#ifdef NSS_ENABLE_ECC
+ tls_hash_sha256, tls_sig_ecdsa,
+ tls_hash_sha384, tls_sig_ecdsa,
+ tls_hash_sha1, tls_sig_ecdsa,
+#endif
+ tls_hash_sha256, tls_sig_dsa,
+ tls_hash_sha1, tls_sig_dsa,
+ };
PRInt32 extension_length;
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_2) {
return 0;
}
extension_length =
2 /* extension type */ +
2 /* extension length */ +
2 /* supported_signature_algorithms length */ +
- ssl3_SizeOfSupportedSignatureAlgorithms();
+ sizeof(signatureAlgorithms);
if (append && maxBytes >= extension_length) {
SECStatus rv;
rv = ssl3_AppendHandshakeNumber(ss, ssl_signature_algorithms_xtn, 2);
if (rv != SECSuccess)
goto loser;
rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2);
if (rv != SECSuccess)
goto loser;
- rv = ssl3_AppendSupportedSignatureAlgorithms(ss);
+ rv = ssl3_AppendHandshakeVariable(ss, signatureAlgorithms,
+ sizeof(signatureAlgorithms), 2);
if (rv != SECSuccess)
goto loser;
ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
ssl_signature_algorithms_xtn;
} else if (maxBytes < extension_length) {
PORT_Assert(0);
return 0;
}
--- a/lib/ssl/sslimpl.h
+++ b/lib/ssl/sslimpl.h
@@ -1609,18 +1609,16 @@ extern SECStatus ssl3_AppendHandshake(ss
extern SECStatus ssl3_AppendHandshakeHeader(sslSocket *ss,
SSL3HandshakeType t, PRUint32 length);
extern SECStatus ssl3_AppendHandshakeNumber(sslSocket *ss, PRInt32 num,
PRInt32 lenSize);
extern SECStatus ssl3_AppendHandshakeVariable( sslSocket *ss,
const SSL3Opaque *src, PRInt32 bytes, PRInt32 lenSize);
extern SECStatus ssl3_AppendSignatureAndHashAlgorithm(sslSocket *ss,
const SSL3SignatureAndHashAlgorithm* sigAndHash);
-extern SECStatus ssl3_AppendSupportedSignatureAlgorithms(sslSocket *ss);
-extern unsigned int ssl3_SizeOfSupportedSignatureAlgorithms(void);
extern SECStatus ssl3_ConsumeHandshake(sslSocket *ss, void *v, PRInt32 bytes,
SSL3Opaque **b, PRUint32 *length);
extern PRInt32 ssl3_ConsumeHandshakeNumber(sslSocket *ss, PRInt32 bytes,
SSL3Opaque **b, PRUint32 *length);
extern SECStatus ssl3_ConsumeHandshakeVariable(sslSocket *ss, SECItem *i,
PRInt32 bytes, SSL3Opaque **b, PRUint32 *length);
extern SECOidTag ssl3_TLSHashAlgorithmToOID(int hashFunc);
extern SECStatus ssl3_CheckSignatureAndHashAlgorithmConsistency(