Переглянути джерело

Add tests for OCSP stapling and SCT lists.

We forgot to add those when we implemented the features. (Also relevant because
they will provide test coverage later for configuring features when using the
generic method tables rather than *_client_method.)

Change-Id: Ie08b27de893095e01a05a7084775676616459807
Reviewed-on: https://boringssl-review.googlesource.com/2410
Reviewed-by: Adam Langley <agl@google.com>
kris/onging/CECPQ3_patch15
David Benjamin 10 роки тому
committed by Adam Langley
джерело
коміт
61f95277d4
7 змінених файлів з 140 додано та 25 видалено
  1. +41
    -10
      ssl/test/bssl_shim.cc
  2. +17
    -12
      ssl/test/runner/common.go
  3. +41
    -2
      ssl/test/runner/handshake_messages.go
  4. +4
    -0
      ssl/test/runner/handshake_server.go
  5. +24
    -0
      ssl/test/runner/runner.go
  6. +9
    -1
      ssl/test/test_config.cc
  7. +4
    -0
      ssl/test/test_config.h

+ 41
- 10
ssl/test/bssl_shim.cc Переглянути файл

@@ -423,17 +423,25 @@ static int do_exchange(SSL_SESSION **out_session,
SSL_set_psk_client_callback(ssl, psk_client_callback);
SSL_set_psk_server_callback(ssl, psk_server_callback);
}
if (!config->psk_identity.empty()) {
if (!SSL_use_psk_identity_hint(ssl, config->psk_identity.c_str())) {
BIO_print_errors_fp(stdout);
return 1;
}
if (!config->psk_identity.empty() &&
!SSL_use_psk_identity_hint(ssl, config->psk_identity.c_str())) {
BIO_print_errors_fp(stdout);
return 1;
}
if (!config->srtp_profiles.empty()) {
if (!SSL_set_srtp_profiles(ssl, config->srtp_profiles.c_str())) {
BIO_print_errors_fp(stdout);
return 1;
}
if (!config->srtp_profiles.empty() &&
!SSL_set_srtp_profiles(ssl, config->srtp_profiles.c_str())) {
BIO_print_errors_fp(stdout);
return 1;
}
if (config->enable_ocsp_stapling &&
!SSL_enable_ocsp_stapling(ssl)) {
BIO_print_errors_fp(stdout);
return 1;
}
if (config->enable_signed_cert_timestamps &&
!SSL_enable_signed_cert_timestamps(ssl)) {
BIO_print_errors_fp(stdout);
return 1;
}

BIO *bio = BIO_new_fd(fd, 1 /* take ownership */);
@@ -555,6 +563,29 @@ static int do_exchange(SSL_SESSION **out_session,
}
}

if (!config->expected_ocsp_response.empty()) {
const uint8_t *data;
size_t len;
SSL_get0_ocsp_response(ssl, &data, &len);
if (config->expected_ocsp_response.size() != len ||
memcmp(config->expected_ocsp_response.data(), data, len) != 0) {
fprintf(stderr, "OCSP response mismatch\n");
return 2;
}
}

if (!config->expected_signed_cert_timestamps.empty()) {
const uint8_t *data;
size_t len;
SSL_get0_signed_cert_timestamp_list(ssl, &data, &len);
if (config->expected_signed_cert_timestamps.size() != len ||
memcmp(config->expected_signed_cert_timestamps.data(),
data, len) != 0) {
fprintf(stderr, "SCT list mismatch\n");
return 2;
}
}

if (config->renegotiate) {
if (config->async) {
fprintf(stderr, "--renegotiate is not supported with --async.\n");


+ 17
- 12
ssl/test/runner/common.go Переглянути файл

@@ -72,18 +72,19 @@ const (

// TLS extension numbers
const (
extensionServerName uint16 = 0
extensionStatusRequest uint16 = 5
extensionSupportedCurves uint16 = 10
extensionSupportedPoints uint16 = 11
extensionSignatureAlgorithms uint16 = 13
extensionUseSRTP uint16 = 14
extensionALPN uint16 = 16
extensionExtendedMasterSecret uint16 = 23
extensionSessionTicket uint16 = 35
extensionNextProtoNeg uint16 = 13172 // not IANA assigned
extensionRenegotiationInfo uint16 = 0xff01
extensionChannelID uint16 = 30032 // not IANA assigned
extensionServerName uint16 = 0
extensionStatusRequest uint16 = 5
extensionSupportedCurves uint16 = 10
extensionSupportedPoints uint16 = 11
extensionSignatureAlgorithms uint16 = 13
extensionUseSRTP uint16 = 14
extensionALPN uint16 = 16
extensionSignedCertificateTimestamp uint16 = 18
extensionExtendedMasterSecret uint16 = 23
extensionSessionTicket uint16 = 35
extensionNextProtoNeg uint16 = 13172 // not IANA assigned
extensionRenegotiationInfo uint16 = 0xff01
extensionChannelID uint16 = 30032 // not IANA assigned
)

// TLS signaling cipher suite values
@@ -731,6 +732,10 @@ type Certificate struct {
// OCSPStaple contains an optional OCSP response which will be served
// to clients that request it.
OCSPStaple []byte
// SignedCertificateTimestampList contains an optional encoded
// SignedCertificateTimestampList structure which will be
// served to clients that request it.
SignedCertificateTimestampList []byte
// Leaf is the parsed form of the leaf certificate, which may be
// initialized using x509.ParseCertificate to reduce per-handshake
// processing for TLS clients doing client authentication. If nil, the


+ 41
- 2
ssl/test/runner/handshake_messages.go Переглянути файл

@@ -31,6 +31,7 @@ type clientHelloMsg struct {
extendedMasterSecret bool
srtpProtectionProfiles []uint16
srtpMasterKeyIdentifier string
sctListSupported bool
}

func (m *clientHelloMsg) equal(i interface{}) bool {
@@ -63,7 +64,8 @@ func (m *clientHelloMsg) equal(i interface{}) bool {
m.npnLast == m1.npnLast &&
m.extendedMasterSecret == m1.extendedMasterSecret &&
eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier
m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
m.sctListSupported == m1.sctListSupported
}

func (m *clientHelloMsg) marshal() []byte {
@@ -133,6 +135,9 @@ func (m *clientHelloMsg) marshal() []byte {
extensionsLength += 1 + len(m.srtpMasterKeyIdentifier)
numExtensions++
}
if m.sctListSupported {
numExtensions++
}
if numExtensions > 0 {
extensionsLength += 4 * numExtensions
length += 2 + extensionsLength
@@ -366,6 +371,11 @@ func (m *clientHelloMsg) marshal() []byte {
copy(z[1:], []byte(m.srtpMasterKeyIdentifier))
z = z[1+mkiLen:]
}
if m.sctListSupported {
z[0] = byte(extensionSignedCertificateTimestamp >> 8)
z[1] = byte(extensionSignedCertificateTimestamp & 0xff)
z = z[4:]
}

m.raw = x

@@ -589,6 +599,11 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
return false
}
m.srtpMasterKeyIdentifier = string(d[1:])
case extensionSignedCertificateTimestamp:
if length != 0 {
return false
}
m.sctListSupported = true
}
data = data[length:]
}
@@ -615,6 +630,7 @@ type serverHelloMsg struct {
extendedMasterSecret bool
srtpProtectionProfile uint16
srtpMasterKeyIdentifier string
sctList []byte
}

func (m *serverHelloMsg) equal(i interface{}) bool {
@@ -641,7 +657,8 @@ func (m *serverHelloMsg) equal(i interface{}) bool {
m.channelIDRequested == m1.channelIDRequested &&
m.extendedMasterSecret == m1.extendedMasterSecret &&
m.srtpProtectionProfile == m1.srtpProtectionProfile &&
m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier
m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
bytes.Equal(m.sctList, m1.sctList)
}

func (m *serverHelloMsg) marshal() []byte {
@@ -692,6 +709,10 @@ func (m *serverHelloMsg) marshal() []byte {
extensionsLength += 2 + 2 + 1 + len(m.srtpMasterKeyIdentifier)
numExtensions++
}
if m.sctList != nil {
extensionsLength += len(m.sctList)
numExtensions++
}

if numExtensions > 0 {
extensionsLength += 4 * numExtensions
@@ -808,6 +829,15 @@ func (m *serverHelloMsg) marshal() []byte {
copy(z[9:], []byte(m.srtpMasterKeyIdentifier))
z = z[9+l:]
}
if m.sctList != nil {
z[0] = byte(extensionSignedCertificateTimestamp >> 8)
z[1] = byte(extensionSignedCertificateTimestamp & 0xff)
l := len(m.sctList)
z[2] = byte(l >> 8)
z[3] = byte(l & 0xff)
copy(z[4:], m.sctList)
z = z[4+l:]
}

m.raw = x

@@ -934,6 +964,15 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
return false
}
m.srtpMasterKeyIdentifier = string(d[1:])
case extensionSignedCertificateTimestamp:
if length < 2 {
return false
}
l := int(data[0])<<8 | int(data[1])
if l != len(data)-2 {
return false
}
m.sctList = data[2:length]
}
data = data[length:]
}


+ 4
- 0
ssl/test/runner/handshake_server.go Переглянути файл

@@ -428,6 +428,10 @@ func (hs *serverHandshakeState) doFullHandshake() error {
hs.hello.ocspStapling = true
}

if hs.clientHello.sctListSupported && len(hs.cert.SignedCertificateTimestampList) > 0 {
hs.hello.sctList = hs.cert.SignedCertificateTimestampList
}

hs.hello.ticketSupported = hs.clientHello.ticketSupported && !config.SessionTicketsDisabled && c.vers > VersionSSL30
hs.hello.cipherSuite = hs.suite.id
c.extendedMasterSecret = hs.hello.extendedMasterSecret


+ 24
- 0
ssl/test/runner/runner.go Переглянути файл

@@ -45,17 +45,24 @@ var rsaCertificate, ecdsaCertificate Certificate
var channelIDKey *ecdsa.PrivateKey
var channelIDBytes []byte

var testOCSPResponse = []byte{1, 2, 3, 4}
var testSCTList = []byte{5, 6, 7, 8}

func initCertificates() {
var err error
rsaCertificate, err = LoadX509KeyPair(rsaCertificateFile, rsaKeyFile)
if err != nil {
panic(err)
}
rsaCertificate.OCSPStaple = testOCSPResponse
rsaCertificate.SignedCertificateTimestampList = testSCTList

ecdsaCertificate, err = LoadX509KeyPair(ecdsaCertificateFile, ecdsaKeyFile)
if err != nil {
panic(err)
}
ecdsaCertificate.OCSPStaple = testOCSPResponse
ecdsaCertificate.SignedCertificateTimestampList = testSCTList

channelIDPEMBlock, err := ioutil.ReadFile(channelIDKeyFile)
if err != nil {
@@ -1878,6 +1885,23 @@ func addExtensionTests() {
shouldFail: true,
expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:",
})
// Test OCSP stapling and SCT list.
testCases = append(testCases, testCase{
name: "OCSPStapling",
flags: []string{
"-enable-ocsp-stapling",
"-expect-ocsp-response",
base64.StdEncoding.EncodeToString(testOCSPResponse),
},
})
testCases = append(testCases, testCase{
name: "SignedCertificateTimestampList",
flags: []string{
"-enable-signed-cert-timestamps",
"-expect-signed-cert-timestamps",
base64.StdEncoding.EncodeToString(testSCTList),
},
})
}

func addResumptionVersionTests() {


+ 9
- 1
ssl/test/test_config.cc Переглянути файл

@@ -62,6 +62,9 @@ const BoolFlag kBoolFlags[] = {
{ "-renegotiate", &TestConfig::renegotiate },
{ "-allow-unsafe-legacy-renegotiation",
&TestConfig::allow_unsafe_legacy_renegotiation },
{ "-enable-ocsp-stapling", &TestConfig::enable_ocsp_stapling },
{ "-enable-signed-cert-timestamps",
&TestConfig::enable_signed_cert_timestamps },
};

const size_t kNumBoolFlags = sizeof(kBoolFlags) / sizeof(kBoolFlags[0]);
@@ -89,6 +92,9 @@ const size_t kNumStringFlags = sizeof(kStringFlags) / sizeof(kStringFlags[0]);
const StringFlag kBase64Flags[] = {
{ "-expect-certificate-types", &TestConfig::expected_certificate_types },
{ "-expect-channel-id", &TestConfig::expected_channel_id },
{ "-expect-ocsp-response", &TestConfig::expected_ocsp_response },
{ "-expect-signed-cert-timestamps",
&TestConfig::expected_signed_cert_timestamps },
};

const size_t kNumBase64Flags = sizeof(kBase64Flags) / sizeof(kBase64Flags[0]);
@@ -116,7 +122,9 @@ TestConfig::TestConfig()
expect_session_miss(false),
expect_extended_master_secret(false),
renegotiate(false),
allow_unsafe_legacy_renegotiation(false) {
allow_unsafe_legacy_renegotiation(false),
enable_ocsp_stapling(false),
enable_signed_cert_timestamps(false) {
}

bool ParseConfig(int argc, char **argv, TestConfig *out_config) {


+ 4
- 0
ssl/test/test_config.h Переглянути файл

@@ -59,6 +59,10 @@ struct TestConfig {
bool renegotiate;
bool allow_unsafe_legacy_renegotiation;
std::string srtp_profiles;
bool enable_ocsp_stapling;
std::string expected_ocsp_response;
bool enable_signed_cert_timestamps;
std::string expected_signed_cert_timestamps;
};

bool ParseConfig(int argc, char **argv, TestConfig *out_config);


Завантаження…
Відмінити
Зберегти