/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include"pk11pub.h" #include"ssl.h" #include"sslimpl.h" #include"sslproto.h" #include"tls13hkdf.h" #include"tls13psk.h" #include"tls13subcerts.h"
/* Check if we can properly return the length of data written and that * we're not asked to return more information than we know how to provide.
*/ if (!info || len < sizeof inf.length || len > sizeof inf) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
}
ss = ssl_FindSocket(fd); if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelInfo",
SSL_GETPID(), fd)); return SECFailure;
}
ssl_GetSpecReadLock(ss); /* XXX The cipher suite should be in the specs and this * function should get it from cwSpec rather than from the "hs". * See bug 275744 comment 69 and bug 766137.
*/
inf.cipherSuite = ss->ssl3.hs.cipher_suite;
ssl_ReleaseSpecReadLock(ss);
inf.compressionMethod = ssl_compression_null;
inf.compressionMethodName = "NULL";
/* Fill in the cipher details from the cipher suite. */
rv = SSL_GetCipherSuiteInfo(inf.cipherSuite,
&cinfo, sizeof(cinfo)); if (rv != SECSuccess) { return SECFailure; /* Error code already set. */
}
inf.symCipher = cinfo.symCipher;
inf.macAlgorithm = cinfo.macAlgorithm; /* Get these fromm |ss->sec| because that is accurate
* even with TLS 1.3 disaggregated cipher suites. */
inf.keaType = ss->sec.keaType;
inf.originalKeaGroup = ss->sec.originalKeaGroup
? ss->sec.originalKeaGroup->name
: ssl_grp_none;
inf.keaGroup = ss->sec.keaGroup
? ss->sec.keaGroup->name
: ssl_grp_none;
inf.keaKeyBits = ss->sec.keaKeyBits;
inf.authType = ss->sec.authType;
inf.authKeyBits = ss->sec.authKeyBits;
inf.signatureScheme = ss->sec.signatureScheme; /* If this is a resumed session, signatureScheme isn't set in ss->sec.
* Use the signature scheme from the previous handshake. */ if (inf.signatureScheme == ssl_sig_none && sid->sigScheme) {
inf.signatureScheme = sid->sigScheme;
}
inf.resumed = ss->statelessResume || ss->ssl3.hs.isResuming; if (inf.resumed) {
inf.pskType = ssl_psk_resume;
} elseif (inf.authType == ssl_auth_psk) {
inf.pskType = ssl_psk_external;
} else {
inf.pskType = ssl_psk_none;
}
inf.peerDelegCred = tls13_IsVerifyingWithDelegatedCredential(ss);
inf.echAccepted = ss->ssl3.hs.echAccepted;
/* Check if we can properly return the length of data written and that * we're not asked to return more information than we know how to provide.
*/ if (!info || len < sizeof inf.length || len > sizeof inf) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
}
ss = ssl_FindSocket(fd); if (!ss) {
SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetPreliminaryChannelInfo",
SSL_GETPID(), fd)); return SECFailure;
}
/* All fields MUST be zero initialized! */
memset(&inf, 0, sizeof(inf));
inf.length = PR_MIN(sizeof(inf), len);
inf.valuesSet = ss->ssl3.hs.preliminaryInfo;
inf.protocolVersion = ss->version;
inf.cipherSuite = ss->ssl3.hs.cipher_suite;
inf.canSendEarlyData = !ss->sec.isServer &&
(ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted); /* We shouldn't be able to send early data if the handshake is done. */
PORT_Assert(!ss->firstHsDone || !inf.canSendEarlyData);
if (ss->sec.ci.sid) {
PRUint32 ticketMaxEarlyData =
ss->sec.ci.sid->u.ssl3.locked.sessionTicket.max_early_data_size;
if (ss->ssl3.hs.zeroRttState == ssl_0rtt_sent ||
ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) { if (ss->statelessResume) {
inf.maxEarlyDataSize = ticketMaxEarlyData;
} elseif (ss->psk) { /* We may have cleared the handshake list, so check the socket.
* This is permissable since we only support one EPSK at a time. */
inf.maxEarlyDataSize = ss->psk->maxEarlyData;
}
}
}
inf.zeroRttCipherSuite = ss->ssl3.hs.zeroRttSuite;
inf.peerDelegCred = tls13_IsVerifyingWithDelegatedCredential(ss);
inf.authKeyBits = ss->sec.authKeyBits;
inf.signatureScheme = ss->sec.signatureScheme;
inf.echAccepted = ss->ssl3.hs.echAccepted; /* Only expose this if the application should use it for verification. */
inf.echPublicName = (inf.echAccepted == PR_FALSE) ? ss->ssl3.hs.echPublicName : NULL;
/* Check if we can properly return the length of data written and that * we're not asked to return more information than we know how to provide.
*/ if (!info || len < sizeof suiteInfo[0].length ||
len > sizeof suiteInfo[0]) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
}
len = PR_MIN(len, sizeof suiteInfo[0]); for (i = 0; i < NUM_SUITEINFOS; i++) { if (suiteInfo[i].cipherSuite == cipherSuite) {
memcpy(info, &suiteInfo[i], len);
info->length = len; return SECSuccess;
}
}
if (!secret) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
}
SSLHashType hashAlg; /* Early export requires a PSK. As in 0-RTT, default
* to the first PSK if no suite is negotiated yet. */ if (secret == ss->ssl3.hs.earlyExporterSecret && !ss->ssl3.hs.suite_def) { if (PR_CLIST_IS_EMPTY(&ss->ssl3.hs.psks)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure;
}
hashAlg = ((sslPsk *)PR_LIST_HEAD(&ss->ssl3.hs.psks))->hash;
} else {
hashAlg = tls13_GetHash(ss);
}
/* Pre-hash the context. */
rv = tls13_ComputeHash(ss, &contextHash, context, contextLen, hashAlg); if (rv != SECSuccess) { return rv;
}
/* construct PRF arguments */
valLen = SSL3_RANDOM_LENGTH * 2; if (hasContext) {
valLen += 2 /* PRUint16 length */ + contextLen;
}
val = PORT_Alloc(valLen); if (!val) { return SECFailure;
}
i = 0;
PORT_Memcpy(val + i, ss->ssl3.hs.client_random, SSL3_RANDOM_LENGTH);
i += SSL3_RANDOM_LENGTH;
PORT_Memcpy(val + i, ss->ssl3.hs.server_random, SSL3_RANDOM_LENGTH);
i += SSL3_RANDOM_LENGTH; if (hasContext) {
val[i++] = contextLen >> 8;
val[i++] = contextLen;
PORT_Memcpy(val + i, context, contextLen);
i += contextLen;
}
PORT_Assert(i == valLen);
/* Allow TLS keying material to be exported sooner, when the master * secret is available and we have sent ChangeCipherSpec.
*/
ssl_GetSpecReadLock(ss); if (!ss->ssl3.cwSpec->masterSecret) {
PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
rv = SECFailure;
} else {
rv = ssl3_TLSPRFWithMasterSecret(ss, ss->ssl3.cwSpec, label, labelLen,
val, valLen, out, outLen);
}
ssl_ReleaseSpecReadLock(ss);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.