|
|
1b6f66 |
diff -up ./lib/ssl/ssl3con.c.client_auth_prf ./lib/ssl/ssl3con.c
|
|
|
1b6f66 |
--- ./lib/ssl/ssl3con.c.client_auth_prf 2016-02-14 09:14:32.821182333 -0800
|
|
|
1b6f66 |
+++ ./lib/ssl/ssl3con.c 2016-02-14 09:52:47.506071502 -0800
|
|
|
1b6f66 |
@@ -270,6 +270,27 @@ static const /*SSL3ClientCertificateType
|
|
|
1b6f66 |
ct_DSS_sign,
|
|
|
1b6f66 |
};
|
|
|
1b6f66 |
|
|
|
1b6f66 |
+/* This block is the contents of the supported_signature_algorithms field of
|
|
|
1b6f66 |
+ * our TLS 1.2 CertificateRequest message, in wire format. See
|
|
|
1b6f66 |
+ * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
|
|
|
1b6f66 |
+ *
|
|
|
1b6f66 |
+ * We only support TLS 1.2
|
|
|
1b6f66 |
+ * CertificateVerify messages that use the handshake PRF hash. */
|
|
|
1b6f66 |
+static const PRUint8 supported_signature_algorithms_sha256[] = {
|
|
|
1b6f66 |
+ tls_hash_sha256, tls_sig_rsa,
|
|
|
1b6f66 |
+#ifndef NSS_DISABLE_ECC
|
|
|
1b6f66 |
+ tls_hash_sha256, tls_sig_ecdsa,
|
|
|
1b6f66 |
+#endif
|
|
|
1b6f66 |
+ tls_hash_sha256, tls_sig_dsa,
|
|
|
1b6f66 |
+};
|
|
|
1b6f66 |
+static const PRUint8 supported_signature_algorithms_sha384[] = {
|
|
|
1b6f66 |
+ tls_hash_sha384, tls_sig_rsa,
|
|
|
1b6f66 |
+#ifndef NSS_DISABLE_ECC
|
|
|
1b6f66 |
+ tls_hash_sha384, tls_sig_ecdsa,
|
|
|
1b6f66 |
+#endif
|
|
|
1b6f66 |
+ tls_hash_sha384, tls_sig_dsa,
|
|
|
1b6f66 |
+};
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
#define EXPORT_RSA_KEY_LENGTH 64 /* bytes */
|
|
|
1b6f66 |
|
|
|
1b6f66 |
|
|
|
1b6f66 |
@@ -4904,6 +4925,7 @@ ssl3_ComputeHandshakeHashes(sslSocket *
|
|
|
1b6f66 |
unsigned int stateLen;
|
|
|
1b6f66 |
unsigned char stackBuf[1024];
|
|
|
1b6f66 |
unsigned char *stateBuf = NULL;
|
|
|
1b6f66 |
+ SECOidData *hashOid;
|
|
|
1b6f66 |
|
|
|
1b6f66 |
h = ss->ssl3.hs.sha;
|
|
|
1b6f66 |
stateBuf = PK11_SaveContextAlloc(h, stackBuf,
|
|
|
1b6f66 |
@@ -4919,9 +4941,25 @@ ssl3_ComputeHandshakeHashes(sslSocket *
|
|
|
1b6f66 |
rv = SECFailure;
|
|
|
1b6f66 |
goto tls12_loser;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
- /* If we ever support ciphersuites where the PRF hash isn't SHA-256
|
|
|
1b6f66 |
- * then this will need to be updated. */
|
|
|
1b6f66 |
- hashes->hashAlg = ssl_hash_sha256;
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
+ /* updated in support of ciphersuites where the PRF hash
|
|
|
1b6f66 |
+ * could be SHA-256 or SHA-384 */
|
|
|
1b6f66 |
+ hashOid = SECOID_FindOIDByMechanism(ssl3_GetPrfHashMechanism(ss));
|
|
|
1b6f66 |
+ if (hashOid == NULL) {
|
|
|
1b6f66 |
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
|
|
|
1b6f66 |
+ rv = SECFailure;
|
|
|
1b6f66 |
+ goto tls12_loser;
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
+ hashes->hashAlg = hashOid->offset;
|
|
|
1b6f66 |
+ PORT_Assert(hashes->hashAlg == ssl_hash_sha256 ||
|
|
|
1b6f66 |
+ hashes->hashAlg == ssl_hash_sha384);
|
|
|
1b6f66 |
+ if (hashes->hashAlg != ssl_hash_sha256 &&
|
|
|
1b6f66 |
+ hashes->hashAlg != ssl_hash_sha384) {
|
|
|
1b6f66 |
+ ssl_MapLowLevelError(SSL_ERROR_DIGEST_FAILURE);
|
|
|
1b6f66 |
+ rv = SECFailure;
|
|
|
1b6f66 |
+ goto tls12_loser;
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
rv = SECSuccess;
|
|
|
1b6f66 |
|
|
|
1b6f66 |
tls12_loser:
|
|
|
1b6f66 |
@@ -7242,7 +7280,7 @@ done:
|
|
|
1b6f66 |
/* Destroys the backup handshake hash context if we don't need it. Note that
|
|
|
1b6f66 |
* this function selects the hash algorithm for client authentication
|
|
|
1b6f66 |
* signatures; ssl3_SendCertificateVerify uses the presence of the backup hash
|
|
|
1b6f66 |
- * to determine whether to use SHA-1 or SHA-256. */
|
|
|
1b6f66 |
+ * to determine whether to use SHA-1, or the PRF hash of the cipher suite. */
|
|
|
1b6f66 |
static void
|
|
|
1b6f66 |
ssl3_DestroyBackupHandshakeHashIfNotNeeded(sslSocket *ss,
|
|
|
1b6f66 |
const SECItem *algorithms)
|
|
|
1b6f66 |
@@ -7251,9 +7289,12 @@ ssl3_DestroyBackupHandshakeHashIfNotNeed
|
|
|
1b6f66 |
SSLSignType sigAlg;
|
|
|
1b6f66 |
PRBool preferSha1;
|
|
|
1b6f66 |
PRBool supportsSha1 = PR_FALSE;
|
|
|
1b6f66 |
- PRBool supportsSha256 = PR_FALSE;
|
|
|
1b6f66 |
+ PRBool supportsHandshakeHash = PR_FALSE;
|
|
|
1b6f66 |
PRBool needBackupHash = PR_FALSE;
|
|
|
1b6f66 |
unsigned int i;
|
|
|
1b6f66 |
+ SECOidData *hashOid;
|
|
|
1b6f66 |
+ TLSHashAlgorithm suitePRFHash;
|
|
|
1b6f66 |
+ PRBool suitePRFIs256Or384 = PR_FALSE;
|
|
|
1b6f66 |
|
|
|
1b6f66 |
#ifndef NO_PKCS11_BYPASS
|
|
|
1b6f66 |
/* Backup handshake hash is not supported in PKCS #11 bypass mode. */
|
|
|
1b6f66 |
@@ -7270,20 +7311,35 @@ ssl3_DestroyBackupHandshakeHashIfNotNeed
|
|
|
1b6f66 |
goto done;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
|
|
|
1b6f66 |
+ hashOid = SECOID_FindOIDByMechanism(ssl3_GetPrfHashMechanism(ss));
|
|
|
1b6f66 |
+ if (hashOid == NULL) {
|
|
|
1b6f66 |
+ rv = SECFailure;
|
|
|
1b6f66 |
+ goto done;
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
+ if (hashOid->offset == SEC_OID_SHA256) {
|
|
|
1b6f66 |
+ suitePRFHash = tls_hash_sha256;
|
|
|
1b6f66 |
+ suitePRFIs256Or384 = PR_TRUE;
|
|
|
1b6f66 |
+ } else if (hashOid->offset == SEC_OID_SHA384) {
|
|
|
1b6f66 |
+ suitePRFHash = tls_hash_sha384;
|
|
|
1b6f66 |
+ suitePRFIs256Or384 = PR_TRUE;
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
/* Determine the server's hash support for that signature algorithm. */
|
|
|
1b6f66 |
for (i = 0; i < algorithms->len; i += 2) {
|
|
|
1b6f66 |
if (algorithms->data[i+1] == sigAlg) {
|
|
|
1b6f66 |
if (algorithms->data[i] == ssl_hash_sha1) {
|
|
|
1b6f66 |
supportsSha1 = PR_TRUE;
|
|
|
1b6f66 |
- } else if (algorithms->data[i] == ssl_hash_sha256) {
|
|
|
1b6f66 |
- supportsSha256 = PR_TRUE;
|
|
|
1b6f66 |
+ } else if (suitePRFIs256Or384 &&
|
|
|
1b6f66 |
+ algorithms->data[i] == suitePRFHash) {
|
|
|
1b6f66 |
+ supportsHandshakeHash = PR_TRUE;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
|
|
|
1b6f66 |
/* If either the server does not support SHA-256 or the client key prefers
|
|
|
1b6f66 |
* SHA-1, leave the backup hash. */
|
|
|
1b6f66 |
- if (supportsSha1 && (preferSha1 || !supportsSha256)) {
|
|
|
1b6f66 |
+ if (supportsSha1 && (preferSha1 || !supportsHandshakeHash)) {
|
|
|
1b6f66 |
needBackupHash = PR_TRUE;
|
|
|
1b6f66 |
}
|
|
|
1b6f66 |
|
|
|
1b6f66 |
@@ -9548,6 +9604,7 @@ ssl3_SendCertificateRequest(sslSocket *s
|
|
|
1b6f66 |
int certTypesLength;
|
|
|
1b6f66 |
PRUint8 sigAlgs[MAX_SIGNATURE_ALGORITHMS * 2];
|
|
|
1b6f66 |
unsigned int sigAlgsLength = 0;
|
|
|
1b6f66 |
+ SECOidData *hashOid;
|
|
|
1b6f66 |
|
|
|
1b6f66 |
SSL_TRC(3, ("%d: SSL3[%d]: send certificate_request handshake",
|
|
|
1b6f66 |
SSL_GETPID(), ss->fd));
|
|
|
1b6f66 |
@@ -9575,6 +9632,20 @@ ssl3_SendCertificateRequest(sslSocket *s
|
|
|
1b6f66 |
certTypes = certificate_types;
|
|
|
1b6f66 |
certTypesLength = sizeof certificate_types;
|
|
|
1b6f66 |
|
|
|
1b6f66 |
+ hashOid = SECOID_FindOIDByMechanism(ssl3_GetPrfHashMechanism(ss));
|
|
|
1b6f66 |
+ if (hashOid == NULL) {
|
|
|
1b6f66 |
+ return SECFailure; /* err set by AppendHandshake. */
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
+ if (hashOid->offset == SEC_OID_SHA256) {
|
|
|
1b6f66 |
+ sigAlgsLength = sizeof supported_signature_algorithms_sha256;
|
|
|
1b6f66 |
+ PORT_Memcpy(sigAlgs, supported_signature_algorithms_sha256, sigAlgsLength);
|
|
|
1b6f66 |
+ } else if (hashOid->offset == SEC_OID_SHA384) {
|
|
|
1b6f66 |
+ sigAlgsLength = sizeof supported_signature_algorithms_sha384;
|
|
|
1b6f66 |
+ PORT_Memcpy(sigAlgs, supported_signature_algorithms_sha384, sigAlgsLength);
|
|
|
1b6f66 |
+ } else {
|
|
|
1b6f66 |
+ return SECFailure; /* err set by AppendHandshake. */
|
|
|
1b6f66 |
+ }
|
|
|
1b6f66 |
+
|
|
|
1b6f66 |
length = 1 + certTypesLength + 2 + calen;
|
|
|
1b6f66 |
if (isTLS12) {
|
|
|
1b6f66 |
rv = ssl3_EncodeCertificateRequestSigAlgs(ss, sigAlgs, sizeof(sigAlgs),
|