Bug 1569221 - Change TLSServer.cpp to support the modern SSL_ConfigServerCert r=keeler

This patch does not change the existing servers to use the new mechanism, rather
attempting to be minimalist. I filed Bug 1569222 for that.

Differential Revision: https://phabricator.services.mozilla.com/D39518

--HG--
extra : moz-landing-system : lando
This commit is contained in:
J.C. Jones 2019-07-26 20:09:43 +00:00
parent 271cd169eb
commit aca1e19c11
6 changed files with 43 additions and 22 deletions

View File

@ -93,8 +93,8 @@ int32_t DoSNISocketConfigBySubjectCN(PRFileDesc* aFd,
static_cast<char*>(PORT_ZAlloc(aSrvNameArr[i].len + 1)));
if (name) {
PORT_Memcpy(name.get(), aSrvNameArr[i].data, aSrvNameArr[i].len);
if (ConfigSecureServerWithNamedCert(aFd, name.get(), nullptr, nullptr) ==
SECSuccess) {
if (ConfigSecureServerWithNamedCert(aFd, name.get(), nullptr, nullptr,
nullptr) == SECSuccess) {
return 0;
}
}
@ -123,8 +123,8 @@ int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr,
UniqueCERTCertificate cert;
SSLKEAType certKEA;
if (SECSuccess !=
ConfigSecureServerWithNamedCert(aFd, host->mCertName, &cert, &certKEA)) {
if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, host->mCertName, &cert,
&certKEA, nullptr)) {
return SSL_SNI_SEND_ALERT;
}

View File

@ -115,8 +115,8 @@ int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr,
UniqueCERTCertificate cert;
SSLKEAType certKEA;
if (SECSuccess !=
ConfigSecureServerWithNamedCert(aFd, certNickname, &cert, &certKEA)) {
if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, certNickname, &cert,
&certKEA, nullptr)) {
return SSL_SNI_SEND_ALERT;
}

View File

@ -44,8 +44,8 @@ int32_t DoSNISocketConfigBySubjectCN(PRFileDesc* aFd,
static_cast<char*>(PORT_ZAlloc(aSrvNameArr[i].len + 1)));
if (name) {
PORT_Memcpy(name.get(), aSrvNameArr[i].data, aSrvNameArr[i].len);
if (ConfigSecureServerWithNamedCert(aFd, name.get(), nullptr, nullptr) ==
SECSuccess) {
if (ConfigSecureServerWithNamedCert(aFd, name.get(), nullptr, nullptr,
nullptr) == SECSuccess) {
return 0;
}
}
@ -74,8 +74,8 @@ int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr,
UniqueCERTCertificate cert;
SSLKEAType certKEA;
if (SECSuccess !=
ConfigSecureServerWithNamedCert(aFd, host->mCertName, &cert, &certKEA)) {
if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, host->mCertName, &cert,
&certKEA, nullptr)) {
return SSL_SNI_SEND_ALERT;
}

View File

@ -388,7 +388,8 @@ int DoCallback() {
SECStatus ConfigSecureServerWithNamedCert(
PRFileDesc* fd, const char* certName,
/*optional*/ UniqueCERTCertificate* certOut,
/*optional*/ SSLKEAType* keaOut) {
/*optional*/ SSLKEAType* keaOut,
/*optional*/ SSLExtraServerCertData* extraData) {
UniqueCERTCertificate cert(PK11_FindCertFromNickname(certName, nullptr));
if (!cert) {
PrintPRError("PK11_FindCertFromNickname failed");
@ -448,22 +449,36 @@ SECStatus ConfigSecureServerWithNamedCert(
return SECFailure;
}
SSLKEAType certKEA = NSS_FindCertKEAType(cert.get());
if (extraData) {
SSLExtraServerCertData dataCopy = {ssl_auth_null, nullptr, nullptr,
nullptr, nullptr, nullptr};
memcpy(&dataCopy, extraData, sizeof(dataCopy));
dataCopy.certChain = certList.get();
if (SSL_ConfigSecureServerWithCertChain(fd, cert.get(), certList.get(),
key.get(), certKEA) != SECSuccess) {
PrintPRError("SSL_ConfigSecureServer failed");
return SECFailure;
if (SSL_ConfigServerCert(fd, cert.get(), key.get(), &dataCopy,
sizeof(dataCopy)) != SECSuccess) {
PrintPRError("SSL_ConfigServerCert failed");
return SECFailure;
}
} else {
// This is the deprecated setup mechanism, to be cleaned up in Bug 1569222
SSLKEAType certKEA = NSS_FindCertKEAType(cert.get());
if (SSL_ConfigSecureServerWithCertChain(fd, cert.get(), certList.get(),
key.get(), certKEA) != SECSuccess) {
PrintPRError("SSL_ConfigSecureServer failed");
return SECFailure;
}
if (keaOut) {
*keaOut = certKEA;
}
}
if (certOut) {
*certOut = std::move(cert);
}
if (keaOut) {
*keaOut = certKEA;
}
SSL_OptionSet(fd, SSL_NO_CACHE, false);
SSL_OptionSet(fd, SSL_ENABLE_SESSION_TICKETS, true);
@ -585,7 +600,8 @@ int StartServer(int argc, char* argv[], SSLSNISocketConfig sniSocketConfig,
// we're actually going to end up using. In the SNI callback, we pick
// the right certificate for the connection.
if (ConfigSecureServerWithNamedCert(modelSocket.get(), DEFAULT_CERT_NICKNAME,
nullptr, nullptr) != SECSuccess) {
nullptr, nullptr,
nullptr) != SECSuccess) {
return 1;
}

View File

@ -39,12 +39,16 @@ void PrintPRError(const char* aPrefix);
// The default certificate is trusted for localhost and *.example.com
extern const char DEFAULT_CERT_NICKNAME[];
// ConfigSecureServerWithNamedCert sets up the hostname name provided. If the
// extraData parameter is presented, extraData->certChain will be automatically
// filled in using database information.
// Pass DEFAULT_CERT_NICKNAME as certName unless you need a specific
// certificate.
SECStatus ConfigSecureServerWithNamedCert(
PRFileDesc* fd, const char* certName,
/*optional*/ UniqueCERTCertificate* cert,
/*optional*/ SSLKEAType* kea);
/*optional*/ SSLKEAType* kea,
/*optional*/ SSLExtraServerCertData* extraData);
SECStatus InitializeNSS(const char* nssCertDBDir);

View File

@ -646,6 +646,7 @@ SSL_CipherPrefSetDefault
SSL_ClearSessionCache
SSL_ConfigSecureServer
SSL_ConfigSecureServerWithCertChain
SSL_ConfigServerCert
SSL_ConfigServerSessionIDCache
SSL_ExportKeyingMaterial
SSL_ForceHandshake