Home | History | Annotate | Download | only in patches
      1 Index: net/third_party/nss/ssl/ssl3con.c
      2 ===================================================================
      3 --- net/third_party/nss/ssl/ssl3con.c	(revision 220594)
      4 +++ net/third_party/nss/ssl/ssl3con.c	(working copy)
      5 @@ -3933,6 +3933,20 @@
      6  		ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
      7  		return SECFailure;
      8  	    }
      9 +
     10 +	    /* A backup SHA-1 hash for a potential client auth signature. */
     11 +	    if (!ss->sec.isServer) {
     12 +		ss->ssl3.hs.md5 = PK11_CreateDigestContext(SEC_OID_SHA1);
     13 +		if (ss->ssl3.hs.md5 == NULL) {
     14 +		    ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
     15 +		    return SECFailure;
     16 +		}
     17 +
     18 +		if (PK11_DigestBegin(ss->ssl3.hs.md5) != SECSuccess) {
     19 +		    ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
     20 +		    return SECFailure;
     21 +		}
     22 +	    }
     23  	} else {
     24  	    /* Both ss->ssl3.hs.md5 and ss->ssl3.hs.sha should be NULL or
     25  	     * created successfully. */
     26 @@ -4043,6 +4057,13 @@
     27  	    ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
     28  	    return rv;
     29  	}
     30 +	if (ss->ssl3.hs.md5) {
     31 +	    rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
     32 +	    if (rv != SECSuccess) {
     33 +		ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
     34 +		return rv;
     35 +	    }
     36 +	}
     37      } else {
     38  	rv = PK11_DigestOp(ss->ssl3.hs.md5, b, l);
     39  	if (rv != SECSuccess) {
     40 @@ -4791,6 +4812,30 @@
     41      return rv;
     42  }
     43  
     44 +static SECStatus
     45 +ssl3_ComputeBackupHandshakeHashes(sslSocket * ss,
     46 +				  SSL3Hashes * hashes) /* output goes here. */
     47 +{
     48 +    SECStatus rv = SECSuccess;
     49 +
     50 +    PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) );
     51 +    PORT_Assert( ss->ssl3.hs.hashType == handshake_hash_single );
     52 +
     53 +    rv = PK11_DigestFinal(ss->ssl3.hs.md5, hashes->u.raw, &hashes->len,
     54 +			  sizeof(hashes->u.raw));
     55 +    if (rv != SECSuccess) {
     56 +	ssl_MapLowLevelError(SSL_ERROR_SHA_DIGEST_FAILURE);
     57 +	rv = SECFailure;
     58 +	goto loser;
     59 +    }
     60 +    hashes->hashAlg = SEC_OID_SHA1;
     61 +
     62 +loser:
     63 +    PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
     64 +    ss->ssl3.hs.md5 = NULL;
     65 +    return rv;
     66 +}
     67 +
     68  /*
     69   * SSL 2 based implementations pass in the initial outbound buffer
     70   * so that the handshake hash can contain the included information.
     71 @@ -6044,7 +6089,17 @@
     72  		SSL_GETPID(), ss->fd));
     73  
     74      ssl_GetSpecReadLock(ss);
     75 -    rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
     76 +    /* In TLS 1.2, ssl3_ComputeHandshakeHashes always uses the handshake hash
     77 +     * function (SHA-256). If the server or the client does not support SHA-256
     78 +     * as a signature hash, we can either maintain a backup SHA-1 handshake
     79 +     * hash or buffer all handshake messages.
     80 +     */
     81 +    if (ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) {
     82 +	rv = ssl3_ComputeBackupHandshakeHashes(ss, &hashes);
     83 +	PORT_Assert(ss->ssl3.hs.md5 == NULL);
     84 +    } else {
     85 +	rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0);
     86 +    }
     87      ssl_ReleaseSpecReadLock(ss);
     88      if (rv != SECSuccess) {
     89  	goto done;	/* err code was set by ssl3_ComputeHandshakeHashes */
     90 @@ -6098,11 +6153,6 @@
     91  	if (rv != SECSuccess) {
     92  	    goto done;
     93  	}
     94 -	/* We always sign using the handshake hash function. It's possible that
     95 -	 * a server could support SHA-256 as the handshake hash but not as a
     96 -	 * signature hash. In that case we wouldn't be able to do client
     97 -	 * certificates with it. The alternative is to buffer all handshake
     98 -	 * messages. */
     99  	sigAndHash.hashAlg = hashes.hashAlg;
    100  
    101  	rv = ssl3_AppendSignatureAndHashAlgorithm(ss, &sigAndHash);
    102 @@ -6802,6 +6852,70 @@
    103  }
    104  
    105  
    106 +/*
    107 + * Returns true if the client authentication key is an RSA or DSA key that
    108 + * may be able to sign only SHA-1 hashes.
    109 + */
    110 +static PRBool
    111 +ssl3_ClientKeyPrefersSHA1(sslSocket *ss)
    112 +{
    113 +    SECKEYPublicKey *pubk;
    114 +    PRBool prefer_sha1 = PR_FALSE;
    115 +
    116 +#if defined(NSS_PLATFORM_CLIENT_AUTH) && defined(_WIN32)
    117 +    /* If the key is in CAPI, assume conservatively that the CAPI service
    118 +     * provider may be unable to sign SHA-256 hashes.
    119 +     */
    120 +    if (ss->ssl3.platformClientKey->dwKeySpec != CERT_NCRYPT_KEY_SPEC) {
    121 +	/* CAPI only supports RSA and DSA signatures, so we don't need to
    122 +	 * check the key type. */
    123 +	return PR_TRUE;
    124 +    }
    125 +#endif  /* NSS_PLATFORM_CLIENT_AUTH && _WIN32 */
    126 +
    127 +    /* If the key is a 1024-bit RSA or DSA key, assume conservatively that
    128 +     * it may be unable to sign SHA-256 hashes. This is the case for older
    129 +     * Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and
    130 +     * older, DSA key size is at most 1024 bits and the hash function must
    131 +     * be SHA-1.
    132 +     */
    133 +    pubk = CERT_ExtractPublicKey(ss->ssl3.clientCertificate);
    134 +    if (pubk == NULL) {
    135 +	return PR_FALSE;
    136 +    }
    137 +    if (pubk->keyType == rsaKey || pubk->keyType == dsaKey) {
    138 +	prefer_sha1 = SECKEY_PublicKeyStrength(pubk) <= 128;
    139 +    }
    140 +    SECKEY_DestroyPublicKey(pubk);
    141 +    return prefer_sha1;
    142 +}
    143 +
    144 +/* Destroys the backup handshake hash context if we don't need it. */
    145 +static void
    146 +ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss,
    147 +					   const SECItem *algorithms)
    148 +{
    149 +    PRBool need_backup_hash = PR_FALSE;
    150 +    unsigned int i;
    151 +
    152 +    PORT_Assert(ss->ssl3.hs.md5);
    153 +    if (ssl3_ClientKeyPrefersSHA1(ss)) {
    154 +	/* Use SHA-1 if the server supports it. */
    155 +	for (i = 0; i < algorithms->len; i += 2) {
    156 +	    if (algorithms->data[i] == tls_hash_sha1 &&
    157 +		(algorithms->data[i+1] == tls_sig_rsa ||
    158 +		 algorithms->data[i+1] == tls_sig_dsa)) {
    159 +		need_backup_hash = PR_TRUE;
    160 +		break;
    161 +	    }
    162 +	}
    163 +    }
    164 +    if (!need_backup_hash) {
    165 +	PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
    166 +	ss->ssl3.hs.md5 = NULL;
    167 +    }
    168 +}
    169 +
    170  typedef struct dnameNode {
    171      struct dnameNode *next;
    172      SECItem           name;
    173 @@ -6994,6 +7108,9 @@
    174  		}
    175  		goto send_no_certificate;
    176  	    }
    177 +	    if (isTLS12) {
    178 +		ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms);
    179 +	    }
    180  	    break;  /* not an error */
    181  	}
    182  #endif   /* NSS_PLATFORM_CLIENT_AUTH */
    183 @@ -7029,6 +7146,9 @@
    184  	    }
    185  	    goto send_no_certificate;
    186  	}
    187 +	if (isTLS12) {
    188 +	    ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms);
    189 +	}
    190  	break;	/* not an error */
    191  
    192      case SECFailure:
    193 @@ -7227,6 +7347,13 @@
    194  		     (ss->ssl3.platformClientKey ||
    195  		     ss->ssl3.clientPrivateKey != NULL);
    196  
    197 +    if (!sendClientCert &&
    198 +	ss->ssl3.hs.hashType == handshake_hash_single && ss->ssl3.hs.md5) {
    199 +	/* Don't need the backup handshake hash. */
    200 +	PK11_DestroyContext(ss->ssl3.hs.md5, PR_TRUE);
    201 +	ss->ssl3.hs.md5 = NULL;
    202 +    }
    203 +
    204      /* We must wait for the server's certificate to be authenticated before
    205       * sending the client certificate in order to disclosing the client
    206       * certificate to an attacker that does not have a valid cert for the
    207 Index: net/third_party/nss/ssl/sslimpl.h
    208 ===================================================================
    209 --- net/third_party/nss/ssl/sslimpl.h	(revision 220594)
    210 +++ net/third_party/nss/ssl/sslimpl.h	(working copy)
    211 @@ -838,6 +838,9 @@
    212       * SSL 3.0 - TLS 1.1 use both |md5| and |sha|. |md5| is used for MD5 and
    213       * |sha| for SHA-1.
    214       * TLS 1.2 and later use only |sha|, for SHA-256. */
    215 +    /* NOTE: On the client side, TLS 1.2 and later use |md5| as a backup
    216 +     * handshake hash for generating client auth signatures. Confusingly, the
    217 +     * backup hash function is SHA-1. */
    218      PK11Context *         md5;
    219      PK11Context *         sha;
    220  
    221