Kaynağa Gözat

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 yıl önce
committed by Adam Langley
ebeveyn
işleme
61f95277d4
7 değiştirilmiş dosya ile 140 ekleme ve 25 silme
  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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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);


Yükleniyor…
İptal
Kaydet