Skip to content

Commit

Permalink
Bug 1540403 - draft-ietf-tls-subcerts-03, r=mt,jcj
Browse files Browse the repository at this point in the history
Differential Revision: https://phabricator.services.mozilla.com/D25654

--HG--
extra : rebase_source : ca10c636f713d432ff5909c6ef9f0f78167294b0
extra : amend_source : 0b979c5b5fd096f846ac3f23c053d799e4dc0294
  • Loading branch information
cjpatton committed Jun 25, 2019
1 parent a3a0d51 commit 88b7fd5
Show file tree
Hide file tree
Showing 32 changed files with 1,522 additions and 66 deletions.
22 changes: 22 additions & 0 deletions automation/abi-check/expected-report-libssl3.so.txt
@@ -0,0 +1,22 @@

2 functions with some indirect sub-type change:

[C]'function SECStatus SSL_ConfigServerCert(PRFileDesc*, CERTCertificate*, SECKEYPrivateKey*, const SSLExtraServerCertData*, unsigned int)' at sslcert.c:640:1 has some indirect sub-type changes:
parameter 4 of type 'const SSLExtraServerCertData*' has sub-type changes:
in pointed to type 'const SSLExtraServerCertData':
in unqualified underlying type 'typedef SSLExtraServerCertData' at sslt.h:291:1:
underlying type 'struct SSLExtraServerCertDataStr' at sslt.h:256:1 changed:
type size changed from 256 to 384 (in bits)
2 data member insertions:
'const SECItem* SSLExtraServerCertDataStr::delegCred', at offset 256 (in bits) at sslt.h:283:1
'const SECKEYPrivateKey* SSLExtraServerCertDataStr::delegCredPrivKey', at offset 320 (in bits) at sslt.h:290:1

[C]'function SECStatus SSL_GetChannelInfo(PRFileDesc*, SSLChannelInfo*, PRUintn)' at sslinfo.c:13:1 has some indirect sub-type changes:
parameter 2 of type 'SSLChannelInfo*' has sub-type changes:
in pointed to type 'typedef SSLChannelInfo' at sslt.h:357:1:
underlying type 'struct SSLChannelInfoStr' at sslt.h:272:1 changed:
type size hasn't changed
1 data member insertion:
'PRBool SSLChannelInfoStr::peerDelegCred', at offset 928 (in bits) at sslt.h:353:1


2 changes: 1 addition & 1 deletion cmd/selfserv/selfserv.c
Expand Up @@ -1926,7 +1926,7 @@ server_main(
for (i = 0; i < certNicknameIndex; i++) {
if (cert[i] != NULL) {
const SSLExtraServerCertData ocspData = {
ssl_auth_null, NULL, certStatus[i], NULL
ssl_auth_null, NULL, certStatus[i], NULL, NULL, NULL
};

secStatus = SSL_ConfigServerCert(model_sock, cert[i],
Expand Down
22 changes: 19 additions & 3 deletions cmd/tstclnt/tstclnt.c
Expand Up @@ -213,6 +213,9 @@ printSecurityInfo(PRFileDesc *fd)
" %u\n",
scts->len);
}
if (channel.peerDelegCred) {
fprintf(stderr, "Received a Delegated Credential\n");
}
}

static void
Expand Down Expand Up @@ -272,6 +275,7 @@ PrintParameterUsage()
fprintf(stderr, "%-20s Enable false start.\n", "-g");
fprintf(stderr, "%-20s Enable the cert_status extension (OCSP stapling).\n", "-T");
fprintf(stderr, "%-20s Enable the signed_certificate_timestamp extension.\n", "-U");
fprintf(stderr, "%-20s Enable the delegated credentials extension.\n", "-B");
fprintf(stderr, "%-20s Require fresh revocation info from side channel.\n"
"%-20s -F once means: require for server cert only\n"
"%-20s -F twice means: require for intermediates, too\n"
Expand Down Expand Up @@ -993,6 +997,7 @@ char *versionString = NULL;
PRBool handshakeComplete = PR_FALSE;
char *encryptedSNIKeys = NULL;
PRBool enablePostHandshakeAuth = PR_FALSE;
PRBool enableDelegatedCredentials = PR_FALSE;

static int
writeBytesToServer(PRFileDesc *s, const PRUint8 *buf, int nb)
Expand Down Expand Up @@ -1365,6 +1370,14 @@ run()
goto done;
}

/* enable negotiation of delegated credentials (draft-ietf-tls-subcerts) */
rv = SSL_OptionSet(s, SSL_ENABLE_DELEGATED_CREDENTIALS, enableDelegatedCredentials);
if (rv != SECSuccess) {
SECU_PrintError(progName, "error enabling delegated credentials");
error = 1;
goto done;
}

/* enable extended master secret mode */
if (enableExtendedMasterSecret) {
rv = SSL_OptionSet(s, SSL_ENABLE_EXTENDED_MASTER_SECRET, PR_TRUE);
Expand Down Expand Up @@ -1715,12 +1728,11 @@ main(int argc, char **argv)
}
}

/* Note: 'B' was used in the past but removed in 3.28
* 'z' was removed in 3.39
/* Note: 'z' was removed in 3.39
* Please leave some time before reusing these.
*/
optstate = PL_CreateOptState(argc, argv,
"46A:CDEFGHI:J:KL:M:N:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:");
"46A:BCDEFGHI:J:KL:M:N:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:");
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case '?':
Expand All @@ -1743,6 +1755,10 @@ main(int argc, char **argv)
requestFile = PORT_Strdup(optstate->value);
break;

case 'B':
enableDelegatedCredentials = PR_TRUE;
break;

case 'C':
++dumpServerChain;
break;
Expand Down
1 change: 1 addition & 0 deletions gtests/ssl_gtest/manifest.mn
Expand Up @@ -54,6 +54,7 @@ CPPSRCS = \
tls_hkdf_unittest.cc \
tls_filter.cc \
tls_protect.cc \
tls_subcerts_unittest.cc \
tls_esni_unittest.cc \
$(SSLKEYLOGFILE_FILES) \
$(NULL)
Expand Down
6 changes: 3 additions & 3 deletions gtests/ssl_gtest/ssl_auth_unittest.cc
Expand Up @@ -1322,11 +1322,11 @@ TEST_P(TlsConnectGeneric, AuthFailImmediate) {
}

static const SSLExtraServerCertData ServerCertDataRsaPkcs1Decrypt = {
ssl_auth_rsa_decrypt, nullptr, nullptr, nullptr};
ssl_auth_rsa_decrypt, nullptr, nullptr, nullptr, nullptr, nullptr};
static const SSLExtraServerCertData ServerCertDataRsaPkcs1Sign = {
ssl_auth_rsa_sign, nullptr, nullptr, nullptr};
ssl_auth_rsa_sign, nullptr, nullptr, nullptr, nullptr, nullptr};
static const SSLExtraServerCertData ServerCertDataRsaPss = {
ssl_auth_rsa_pss, nullptr, nullptr, nullptr};
ssl_auth_rsa_pss, nullptr, nullptr, nullptr, nullptr, nullptr};

// Test RSA cert with usage=[signature, encipherment].
TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPkcs1SignAndKEX) {
Expand Down
10 changes: 5 additions & 5 deletions gtests/ssl_gtest/ssl_cert_ext_unittest.cc
Expand Up @@ -64,8 +64,8 @@ static const uint8_t kSctValue[] = {0x01, 0x23, 0x45, 0x67, 0x89};
static const SECItem kSctItem = {siBuffer, const_cast<uint8_t*>(kSctValue),
sizeof(kSctValue)};
static const DataBuffer kSctBuffer(kSctValue, sizeof(kSctValue));
static const SSLExtraServerCertData kExtraSctData = {ssl_auth_null, nullptr,
nullptr, &kSctItem};
static const SSLExtraServerCertData kExtraSctData = {
ssl_auth_null, nullptr, nullptr, &kSctItem, nullptr, nullptr};

// Test timestamps extraction during a successful handshake.
TEST_P(TlsConnectGenericPre13, SignedCertificateTimestampsLegacy) {
Expand Down Expand Up @@ -147,8 +147,8 @@ static const SECItem kOcspItems[] = {
{siBuffer, const_cast<uint8_t*>(kOcspValue2), sizeof(kOcspValue2)}};
static const SECItemArray kOcspResponses = {const_cast<SECItem*>(kOcspItems),
PR_ARRAY_SIZE(kOcspItems)};
const static SSLExtraServerCertData kOcspExtraData = {ssl_auth_null, nullptr,
&kOcspResponses, nullptr};
const static SSLExtraServerCertData kOcspExtraData = {
ssl_auth_null, nullptr, &kOcspResponses, nullptr, nullptr, nullptr};

TEST_P(TlsConnectGeneric, NoOcsp) {
EnsureTlsSetup();
Expand Down Expand Up @@ -224,7 +224,7 @@ TEST_P(TlsConnectGeneric, OcspHugeSuccess) {
const SECItemArray hugeOcspResponses = {const_cast<SECItem*>(hugeOcspItems),
PR_ARRAY_SIZE(hugeOcspItems)};
const SSLExtraServerCertData hugeOcspExtraData = {
ssl_auth_null, nullptr, &hugeOcspResponses, nullptr};
ssl_auth_null, nullptr, &hugeOcspResponses, nullptr, nullptr, nullptr};

// The value should be available during the AuthCertificateCallback
client_->SetAuthCertificateCallback([&](TlsAgent* agent, bool checksig,
Expand Down
3 changes: 2 additions & 1 deletion gtests/ssl_gtest/ssl_gtest.gyp
Expand Up @@ -54,7 +54,8 @@
'tls_filter.cc',
'tls_hkdf_unittest.cc',
'tls_esni_unittest.cc',
'tls_protect.cc'
'tls_protect.cc',
'tls_subcerts_unittest.cc'
],
'dependencies': [
'<(DEPTH)/exports.gyp:nss_exports',
Expand Down
58 changes: 58 additions & 0 deletions gtests/ssl_gtest/tls_agent.cc
Expand Up @@ -47,6 +47,7 @@ const std::string TlsAgent::kServerEcdsa521 = "ecdsa521";
const std::string TlsAgent::kServerEcdhRsa = "ecdh_rsa";
const std::string TlsAgent::kServerEcdhEcdsa = "ecdh_ecdsa";
const std::string TlsAgent::kServerDsa = "dsa";
const std::string TlsAgent::kDelegatorEcdsa256 = "delegator_ecdsa256";

static const uint8_t kCannedTls13ServerHello[] = {
0x03, 0x03, 0x9c, 0xbc, 0x14, 0x9b, 0x0e, 0x2e, 0xfa, 0x0d, 0xf3,
Expand Down Expand Up @@ -137,6 +138,59 @@ void TlsAgent::SetState(State s) {
return true;
}

// Loads a key pair from the certificate identified by |id|.
/*static*/ bool TlsAgent::LoadKeyPairFromCert(const std::string& name,
ScopedSECKEYPublicKey* pub,
ScopedSECKEYPrivateKey* priv) {
ScopedCERTCertificate cert;
if (!TlsAgent::LoadCertificate(name, &cert, priv)) {
return false;
}

pub->reset(SECKEY_ExtractPublicKey(&cert->subjectPublicKeyInfo));
if (!pub->get()) {
return false;
}

return true;
}

void TlsAgent::DelegateCredential(const std::string& name,
const ScopedSECKEYPublicKey& dc_pub,
SSLSignatureScheme dc_cert_verify_alg,
PRUint32 dc_valid_for, PRTime now,
SECItem* dc) {
ScopedCERTCertificate cert;
ScopedSECKEYPrivateKey certPriv;
EXPECT_TRUE(TlsAgent::LoadCertificate(name, &cert, &certPriv));
EXPECT_EQ(SECSuccess,
SSL_DelegateCredential(cert.get(), certPriv.get(), dc_pub.get(),
dc_cert_verify_alg, dc_valid_for, now, dc));
}

void TlsAgent::EnableDelegatedCredentials() {
ASSERT_TRUE(EnsureTlsSetup());
SetOption(SSL_ENABLE_DELEGATED_CREDENTIALS, PR_TRUE);
}

void TlsAgent::AddDelegatedCredential(const std::string& dc_name,
SSLSignatureScheme dc_cert_verify_alg,
PRUint32 dc_valid_for, PRTime now) {
ASSERT_TRUE(EnsureTlsSetup());

ScopedSECKEYPublicKey pub;
ScopedSECKEYPrivateKey priv;
EXPECT_TRUE(TlsAgent::LoadKeyPairFromCert(dc_name, &pub, &priv));

StackSECItem dc;
TlsAgent::DelegateCredential(name_, pub, dc_cert_verify_alg, dc_valid_for,
now, &dc);

SSLExtraServerCertData extra_data = {ssl_auth_null, nullptr, nullptr,
nullptr, &dc, priv.get()};
EXPECT_TRUE(ConfigServerCert(name_, true, &extra_data));
}

bool TlsAgent::ConfigServerCert(const std::string& id, bool updateKeyBits,
const SSLExtraServerCertData* serverCertData) {
ScopedCERTCertificate cert;
Expand Down Expand Up @@ -318,6 +372,10 @@ void TlsAgent::CheckCipherSuite(uint16_t suite) {
EXPECT_EQ(csinfo_.cipherSuite, suite);
}

void TlsAgent::CheckPeerDelegCred(bool expected) {
EXPECT_EQ(expected, info_.peerDelegCred);
}

void TlsAgent::RequestClientAuth(bool requireAuth) {
ASSERT_EQ(SERVER, role_);

Expand Down
22 changes: 22 additions & 0 deletions gtests/ssl_gtest/tls_agent.h
Expand Up @@ -76,6 +76,7 @@ class TlsAgent : public PollTarget {
static const std::string kServerEcdhEcdsa;
static const std::string kServerEcdhRsa;
static const std::string kServerDsa;
static const std::string kDelegatorEcdsa256; // draft-ietf-tls-subcerts

TlsAgent(const std::string& name, Role role, SSLProtocolVariant variant);
virtual ~TlsAgent();
Expand Down Expand Up @@ -113,6 +114,26 @@ class TlsAgent : public PollTarget {
static bool LoadCertificate(const std::string& name,
ScopedCERTCertificate* cert,
ScopedSECKEYPrivateKey* priv);
static bool LoadKeyPairFromCert(const std::string& name,
ScopedSECKEYPublicKey* pub,
ScopedSECKEYPrivateKey* priv);

// Delegated credentials.
//
// Generate a delegated credential and sign it using the certificate
// associated with |name|.
static void DelegateCredential(const std::string& name,
const ScopedSECKEYPublicKey& dcPub,
SSLSignatureScheme dcCertVerifyAlg,
PRUint32 dcValidFor, PRTime now, SECItem* dc);
// Indicate support for the delegated credentials extension.
void EnableDelegatedCredentials();
// Generate and configure a delegated credential to use in the handshake with
// clients that support this extension..
void AddDelegatedCredential(const std::string& dc_name,
SSLSignatureScheme dcCertVerifyAlg,
PRUint32 dcValidFor, PRTime now);

bool ConfigServerCert(const std::string& name, bool updateKeyBits = false,
const SSLExtraServerCertData* serverCertData = nullptr);
bool ConfigServerCertWithChain(const std::string& name);
Expand Down Expand Up @@ -163,6 +184,7 @@ class TlsAgent : public PollTarget {
void DisableECDHEServerKeyReuse();
bool GetPeerChainLength(size_t* count);
void CheckCipherSuite(uint16_t cipher_suite);
void CheckPeerDelegCred(bool expected);
void SetResumptionTokenCallback();
bool MaybeSetResumptionToken();
void SetResumptionToken(const std::vector<uint8_t>& resumption_token) {
Expand Down

0 comments on commit 88b7fd5

Please sign in to comment.