Bug 480514: Prune the supported_signature_algorithms field of our
authorWan-Teh Chang <wtc@google.com>
Fri, 07 Jun 2013 12:33:25 -0700
changeset 10804 f6a0a66c6037a59b8c277d3a3d3793f707c00b0f
parent 10803 ace8f8e05e2b856b00f00f9a24c575177aa68797
child 10805 0114a0ae7ebee658d21b9c5f8dabadc4515b6836
push id113
push userwtc@google.com
push dateFri, 07 Jun 2013 19:33:30 +0000
bugs480514
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.
lib/ssl/ssl3con.c
lib/ssl/ssl3ext.c
lib/ssl/sslimpl.h
--- 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(