2014-05-13 18:00:26 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright 2011 The WebRTC Project Authors. All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2022-03-17 15:47:49 +01:00
|
|
|
#include "rtc_base/ssl_stream_adapter.h"
|
|
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
#include <algorithm>
|
2016-04-26 03:13:22 -07:00
|
|
|
#include <memory>
|
2014-05-13 18:00:26 +00:00
|
|
|
#include <set>
|
|
|
|
|
#include <string>
|
|
|
|
|
|
2020-03-20 22:51:32 +01:00
|
|
|
#include "absl/memory/memory.h"
|
2022-03-17 15:47:49 +01:00
|
|
|
#include "absl/strings/string_view.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "rtc_base/buffer_queue.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "rtc_base/checks.h"
|
|
|
|
|
#include "rtc_base/gunit.h"
|
|
|
|
|
#include "rtc_base/helpers.h"
|
2019-03-28 13:30:15 +01:00
|
|
|
#include "rtc_base/memory/fifo_buffer.h"
|
2018-11-01 09:33:08 +01:00
|
|
|
#include "rtc_base/memory_stream.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "rtc_base/message_digest.h"
|
2020-09-25 16:00:51 +02:00
|
|
|
#include "rtc_base/openssl_stream_adapter.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "rtc_base/ssl_adapter.h"
|
|
|
|
|
#include "rtc_base/ssl_identity.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "rtc_base/stream.h"
|
2020-10-05 12:43:53 +00:00
|
|
|
#include "rtc_base/task_utils/pending_task_safety_flag.h"
|
|
|
|
|
#include "rtc_base/task_utils/to_queued_task.h"
|
2020-03-09 19:39:36 +01:00
|
|
|
#include "test/field_trial.h"
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2015-08-17 14:08:59 +02:00
|
|
|
using ::testing::Combine;
|
|
|
|
|
using ::testing::tuple;
|
2020-03-09 19:39:36 +01:00
|
|
|
using ::testing::Values;
|
|
|
|
|
using ::testing::WithParamInterface;
|
2015-08-17 14:08:59 +02:00
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
static const int kBlockSize = 4096;
|
|
|
|
|
static const char kExporterLabel[] = "label";
|
|
|
|
|
static const unsigned char kExporterContext[] = "context";
|
|
|
|
|
static int kExporterContextLen = sizeof(kExporterContext);
|
|
|
|
|
|
2020-03-09 19:39:36 +01:00
|
|
|
// A private key used for testing, broken into pieces in order to avoid
|
|
|
|
|
// issues with Git's checks for private keys in repos.
|
|
|
|
|
#define RSA_PRIVATE_KEY_HEADER "-----BEGIN RSA PRIVATE KEY-----\n"
|
|
|
|
|
|
|
|
|
|
static const char kRSA_PRIVATE_KEY_PEM[] = RSA_PRIVATE_KEY_HEADER
|
2014-05-13 18:00:26 +00:00
|
|
|
"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n"
|
|
|
|
|
"czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
|
|
|
|
|
"rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
|
|
|
|
|
"5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n"
|
|
|
|
|
"mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n"
|
|
|
|
|
"2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n"
|
|
|
|
|
"CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n"
|
|
|
|
|
"WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n"
|
|
|
|
|
"kdqANep0uwZciiNiWxsQrCHztywOvbFhdp8iYVFG9EK8DMY41Y5TxUwsHD+67zao\n"
|
|
|
|
|
"ZNqJAkEA1suLUP/GvL8IwuRneQd2tWDqqRQ/Td3qq03hP7e77XtF/buya3Ghclo5\n"
|
|
|
|
|
"54czUR89QyVfJEC6278nzA7n2h1uVQJAcG6mztNL6ja/dKZjYZye2CY44QjSlLo0\n"
|
|
|
|
|
"MTgTSjdfg/28fFn2Jjtqf9Pi/X+50LWI/RcYMC2no606wRk9kyOuIQJBAK6VSAim\n"
|
|
|
|
|
"1pOEjsYQn0X5KEIrz1G3bfCbB848Ime3U2/FWlCHMr6ch8kCZ5d1WUeJD3LbwMNG\n"
|
|
|
|
|
"UCXiYxSsu20QNVw=\n"
|
|
|
|
|
"-----END RSA PRIVATE KEY-----\n";
|
|
|
|
|
|
2020-03-09 19:39:36 +01:00
|
|
|
#undef RSA_PRIVATE_KEY_HEADER
|
|
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
static const char kCERT_PEM[] =
|
|
|
|
|
"-----BEGIN CERTIFICATE-----\n"
|
|
|
|
|
"MIIBmTCCAQKgAwIBAgIEbzBSAjANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDEwZX\n"
|
|
|
|
|
"ZWJSVEMwHhcNMTQwMTAyMTgyNDQ3WhcNMTQwMjAxMTgyNDQ3WjARMQ8wDQYDVQQD\n"
|
|
|
|
|
"EwZXZWJSVEMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYRkbhmI7kVA/rM\n"
|
|
|
|
|
"czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n"
|
|
|
|
|
"rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n"
|
|
|
|
|
"5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAEwDQYJKoZIhvcNAQELBQADgYEAUflI\n"
|
|
|
|
|
"VUe5Krqf5RVa5C3u/UTAOAUJBiDS3VANTCLBxjuMsvqOG0WvaYWP3HYPgrz0jXK2\n"
|
|
|
|
|
"LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n"
|
|
|
|
|
"UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n"
|
|
|
|
|
"-----END CERTIFICATE-----\n";
|
|
|
|
|
|
2017-11-16 16:58:02 -08:00
|
|
|
static const char kIntCert1[] =
|
|
|
|
|
"-----BEGIN CERTIFICATE-----\n"
|
|
|
|
|
"MIIEUjCCAjqgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBljELMAkGA1UEBhMCVVMx\n"
|
|
|
|
|
"EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS\n"
|
|
|
|
|
"BgNVBAoMC0dvb2dsZSwgSW5jMQwwCgYDVQQLDANHVFAxFzAVBgNVBAMMDnRlbGVw\n"
|
|
|
|
|
"aG9ueS5nb29nMR0wGwYJKoZIhvcNAQkBFg5ndHBAZ29vZ2xlLmNvbTAeFw0xNzA5\n"
|
|
|
|
|
"MjYwNDA5MDNaFw0yMDA2MjIwNDA5MDNaMGQxCzAJBgNVBAYTAlVTMQswCQYDVQQI\n"
|
|
|
|
|
"DAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEXMBUGA1UECgwOdGVsZXBob255\n"
|
|
|
|
|
"Lmdvb2cxFzAVBgNVBAMMDnRlbGVwaG9ueS5nb29nMIGfMA0GCSqGSIb3DQEBAQUA\n"
|
|
|
|
|
"A4GNADCBiQKBgQDJXWeeU1v1+wlqkVobzI3aN7Uh2iVQA9YCdq5suuabtiD/qoOD\n"
|
|
|
|
|
"NKpmQqsx7WZGGWSZTDFEBaUpvIK7Hb+nzRqk6iioPCFOFuarm6GxO1xVneImMuE6\n"
|
|
|
|
|
"tuWb3YZPr+ikChJbl11y5UcSbg0QsbeUc+jHl5umNvrL85Y+z8SP0rxbBwIDAQAB\n"
|
|
|
|
|
"o2AwXjAdBgNVHQ4EFgQU7tdZobqlN8R8V72FQnRxmqq8tKswHwYDVR0jBBgwFoAU\n"
|
|
|
|
|
"5GgKMUtcxkQ2dJrtNR5YOlIAPDswDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMC\n"
|
|
|
|
|
"AQYwDQYJKoZIhvcNAQELBQADggIBADObh9Z+z14FmP9zSenhFtq7hFnmNrSkklk8\n"
|
|
|
|
|
"eyYWXKfOuIriEQQBZsz76ZcnzStih8Rj+yQ0AXydk4fJ5LOwC2cUqQBar17g6Pd2\n"
|
|
|
|
|
"8g4SIL4azR9WvtiSvpuGlwp25b+yunaacDne6ebnf/MUiiKT5w61Xo3cEPVfl38e\n"
|
|
|
|
|
"/Up2l0bioid5enUTmg6LY6RxDO6tnZQkz3XD+nNSwT4ehtkqFpHYWjErj0BbkDM2\n"
|
|
|
|
|
"hiVc/JsYOZn3DmuOlHVHU6sKwqh3JEyvHO/d7DGzMGWHpHwv2mCTJq6l/sR95Tc2\n"
|
|
|
|
|
"GaQZgGDVNs9pdEouJCDm9e/PbQWRYhnat82PTkXx/6mDAAwdZlIi/pACzq8K4p7e\n"
|
|
|
|
|
"6hF0t8uKGnXJubHPXxlnJU6yxZ0yWmivAGjwWK4ur832gKlho4jeMDhiI/T3QPpl\n"
|
|
|
|
|
"iMNsIvxRhdD+GxJkQP1ezayw8s+Uc9KwKglrkBSRRDLCJUfPOvMmXLUDSTMX7kp4\n"
|
|
|
|
|
"/Ak1CA8dVLJIlfEjLBUuvAttlP7+7lsKNgxAjCxZkWLXIyGULzNPQwVWkGfCbrQs\n"
|
|
|
|
|
"XyMvSbFsSIb7blV7eLlmf9a+2RprUUkc2ALXLLCI9YQXmxm2beBfMyNmmebwBJzT\n"
|
|
|
|
|
"B0OR+5pFFNTJPoNlqpdrDsGrDu7JlUtk0ZLZzYyKXbgy2qXxfd4OWzXXjxpLMszZ\n"
|
|
|
|
|
"LDIpOAkj\n"
|
|
|
|
|
"-----END CERTIFICATE-----\n";
|
|
|
|
|
|
|
|
|
|
static const char kCACert[] =
|
|
|
|
|
"-----BEGIN CERTIFICATE-----\n"
|
|
|
|
|
"MIIGETCCA/mgAwIBAgIJAKN9r/BdbGUJMA0GCSqGSIb3DQEBCwUAMIGWMQswCQYD\n"
|
|
|
|
|
"VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4g\n"
|
|
|
|
|
"VmlldzEUMBIGA1UECgwLR29vZ2xlLCBJbmMxDDAKBgNVBAsMA0dUUDEXMBUGA1UE\n"
|
|
|
|
|
"AwwOdGVsZXBob255Lmdvb2cxHTAbBgkqhkiG9w0BCQEWDmd0cEBnb29nbGUuY29t\n"
|
|
|
|
|
"MB4XDTE3MDcyNzIzMDE0NVoXDTE3MDgyNjIzMDE0NVowgZYxCzAJBgNVBAYTAlVT\n"
|
|
|
|
|
"MRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRQw\n"
|
|
|
|
|
"EgYDVQQKDAtHb29nbGUsIEluYzEMMAoGA1UECwwDR1RQMRcwFQYDVQQDDA50ZWxl\n"
|
|
|
|
|
"cGhvbnkuZ29vZzEdMBsGCSqGSIb3DQEJARYOZ3RwQGdvb2dsZS5jb20wggIiMA0G\n"
|
|
|
|
|
"CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCfvpF7aBV5Hp1EHsWoIlL3GeHwh8dS\n"
|
|
|
|
|
"lv9VQCegN9rD06Ny7MgcED5AiK2vqXmUmOVS+7NbATkdVYN/eozDhKtN3Q3n87kJ\n"
|
|
|
|
|
"Nt/TD/TcZZHOZIGsRPbrf2URK26E/5KzTzbzXVBOA1e+gSj+EBbltGqb01ZO5ErF\n"
|
|
|
|
|
"iPGViPM/HpYKdq6mfz2bS5PhU67XZMM2zvToyReQ/Fjm/6PJhwKSRXSgZF5djPhk\n"
|
|
|
|
|
"2LfOKMLS0AeZtd2C4DFsCU41lfLUkybioDgFuzTQ3TFi1K8A07KYTMmLY/yQppnf\n"
|
|
|
|
|
"SpNX58shlVhM+Ed37K1Z0rU0OfVCZ5P+KKaSSfMranjlU7zeUIhZYjqq/EYrEhbS\n"
|
|
|
|
|
"dLnNHwgJrqxzId3kq8uuLM6+VB7JZKnZLfT90GdAbX4+tutNe21smmogF9f80vEy\n"
|
|
|
|
|
"gM4tOp9rXrvz9vCwWHXVY9kdKemdLAsREoO6MS9k2ctK4jj80o2dROuFC6Q3e7mz\n"
|
|
|
|
|
"RjvZr5Tvi464c2o9o/jNlJ0O6q7V2eQzohD+7VnV5QPpRGXxlIeqpR2zoAg+WtRS\n"
|
|
|
|
|
"4OgHOVYiD3M6uAlggJA5pcDjMfkEZ+pkhtVcT4qMCEoruk6GbyPxS565oSHu16bH\n"
|
|
|
|
|
"EjeCqbZOVND5T3oA7nz6aQSs8sJabt0jmxUkGVnE+4ZDIuuRtkRma+0P/96Mtqor\n"
|
|
|
|
|
"OlpNWY1OBDY64QIDAQABo2AwXjAdBgNVHQ4EFgQU5GgKMUtcxkQ2dJrtNR5YOlIA\n"
|
|
|
|
|
"PDswHwYDVR0jBBgwFoAU5GgKMUtcxkQ2dJrtNR5YOlIAPDswDwYDVR0TAQH/BAUw\n"
|
|
|
|
|
"AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIBAARQly5/bB6VUL2C\n"
|
|
|
|
|
"ykDYgWt48go407pAra6tL2kjpdfxV5PdL7iMZRkeht00vj+BVahIqZKrNOa/f5Fx\n"
|
|
|
|
|
"vlpahZFu0PDN436aQwRZ9qWut2qDOK0/z9Hhj6NWybquRFwMwqkPG/ivLMDU8Dmj\n"
|
|
|
|
|
"CIplpngPYNwXCs0KzdjSXYxqxJbwMjQXELD+/RcurY0oTtJMM1/2vKQMzw24UJqe\n"
|
|
|
|
|
"XLJAlsnd2AnWzWNUEviDZY89j9NdkHerBmV2gGzcU+X5lgOO5M8odBv0ZC9D+a6Z\n"
|
|
|
|
|
"QPZAOfdGVw60hhGvTW5s/s0dHwCpegRidhs0MD0fTmwwjYFBSmUx3Gztr4JTzOOr\n"
|
|
|
|
|
"7e5daJuak2ujQ5DqcGBvt1gePjSudb5brS7JQtN8tI/FyrnR4q/OuOwv1EvlC5RG\n"
|
|
|
|
|
"hLX+TXaWqFxB1Hd8ebKRR40mboFG6KcUI3lLBthDvQE7jnq48QfZMjlMQK0ZF1l7\n"
|
|
|
|
|
"SrlwRXWA74bU8CLJvnZKKo9p4TsTiDYGSYC6tNHKj5s3TGWL46oqGyZ0KdGNhrtC\n"
|
|
|
|
|
"rIGenMhth1vPYjyy0XuGBndXT85yi+IM2l8g8oU845+plxIhgpSI8bbC0oLwnhQ5\n"
|
|
|
|
|
"ARfsiYLkXDE7imSS0CSUmye76372mlzAIB1is4bBB/SzpPQtBuB9LDKtONgpSGHn\n"
|
|
|
|
|
"dGaXBy+qbVXVyGXaeEbIRjtJ6m92\n"
|
|
|
|
|
"-----END CERTIFICATE-----\n";
|
|
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
class SSLStreamAdapterTestBase;
|
|
|
|
|
|
2015-11-19 05:17:58 -08:00
|
|
|
class SSLDummyStreamBase : public rtc::StreamInterface,
|
|
|
|
|
public sigslot::has_slots<> {
|
2014-05-13 18:00:26 +00:00
|
|
|
public:
|
2015-11-19 05:17:58 -08:00
|
|
|
SSLDummyStreamBase(SSLStreamAdapterTestBase* test,
|
2022-03-17 15:47:49 +01:00
|
|
|
absl::string_view side,
|
2015-11-19 05:17:58 -08:00
|
|
|
rtc::StreamInterface* in,
|
2018-06-19 15:03:05 +02:00
|
|
|
rtc::StreamInterface* out)
|
|
|
|
|
: test_base_(test), side_(side), in_(in), out_(out), first_packet_(true) {
|
2015-11-19 05:17:58 -08:00
|
|
|
in_->SignalEvent.connect(this, &SSLDummyStreamBase::OnEventIn);
|
|
|
|
|
out_->SignalEvent.connect(this, &SSLDummyStreamBase::OnEventOut);
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
2015-11-19 05:17:58 -08:00
|
|
|
rtc::StreamState GetState() const override { return rtc::SS_OPEN; }
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
rtc::StreamResult Read(void* buffer,
|
|
|
|
|
size_t buffer_len,
|
|
|
|
|
size_t* read,
|
|
|
|
|
int* error) override {
|
2014-05-13 18:00:26 +00:00
|
|
|
rtc::StreamResult r;
|
|
|
|
|
|
|
|
|
|
r = in_->Read(buffer, buffer_len, read, error);
|
|
|
|
|
if (r == rtc::SR_BLOCK)
|
|
|
|
|
return rtc::SR_BLOCK;
|
|
|
|
|
if (r == rtc::SR_EOS)
|
|
|
|
|
return rtc::SR_EOS;
|
|
|
|
|
|
|
|
|
|
if (r != rtc::SR_SUCCESS) {
|
|
|
|
|
ADD_FAILURE();
|
|
|
|
|
return rtc::SR_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rtc::SR_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Catch readability events on in and pass them up.
|
2015-11-19 05:17:58 -08:00
|
|
|
void OnEventIn(rtc::StreamInterface* stream, int sig, int err) {
|
2014-05-13 18:00:26 +00:00
|
|
|
int mask = (rtc::SE_READ | rtc::SE_CLOSE);
|
|
|
|
|
|
|
|
|
|
if (sig & mask) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "SSLDummyStreamBase::OnEvent side=" << side_
|
|
|
|
|
<< " sig=" << sig << " forwarding upward";
|
2014-05-13 18:00:26 +00:00
|
|
|
PostEvent(sig & mask, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Catch writeability events on out and pass them up.
|
2015-11-19 05:17:58 -08:00
|
|
|
void OnEventOut(rtc::StreamInterface* stream, int sig, int err) {
|
2014-05-13 18:00:26 +00:00
|
|
|
if (sig & rtc::SE_WRITE) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "SSLDummyStreamBase::OnEvent side=" << side_
|
|
|
|
|
<< " sig=" << sig << " forwarding upward";
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
PostEvent(sig & rtc::SE_WRITE, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Write to the outgoing FifoBuffer
|
2018-06-19 15:03:05 +02:00
|
|
|
rtc::StreamResult WriteData(const void* data,
|
|
|
|
|
size_t data_len,
|
|
|
|
|
size_t* written,
|
|
|
|
|
int* error) {
|
2014-05-13 18:00:26 +00:00
|
|
|
return out_->Write(data, data_len, written, error);
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
rtc::StreamResult Write(const void* data,
|
|
|
|
|
size_t data_len,
|
|
|
|
|
size_t* written,
|
|
|
|
|
int* error) override;
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2015-11-19 05:17:58 -08:00
|
|
|
void Close() override {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_INFO) << "Closing outbound stream";
|
2014-05-13 18:00:26 +00:00
|
|
|
out_->Close();
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-05 12:43:53 +00:00
|
|
|
private:
|
|
|
|
|
void PostEvent(int events, int err) {
|
|
|
|
|
thread_->PostTask(webrtc::ToQueuedTask(task_safety_, [this, events, err]() {
|
|
|
|
|
SignalEvent(this, events, err);
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
webrtc::ScopedTaskSafety task_safety_;
|
|
|
|
|
rtc::Thread* const thread_ = rtc::Thread::Current();
|
2015-11-19 05:17:58 -08:00
|
|
|
SSLStreamAdapterTestBase* test_base_;
|
2014-05-13 18:00:26 +00:00
|
|
|
const std::string side_;
|
2015-11-19 05:17:58 -08:00
|
|
|
rtc::StreamInterface* in_;
|
|
|
|
|
rtc::StreamInterface* out_;
|
2014-05-13 18:00:26 +00:00
|
|
|
bool first_packet_;
|
|
|
|
|
};
|
|
|
|
|
|
2015-11-19 05:17:58 -08:00
|
|
|
class SSLDummyStreamTLS : public SSLDummyStreamBase {
|
|
|
|
|
public:
|
|
|
|
|
SSLDummyStreamTLS(SSLStreamAdapterTestBase* test,
|
2022-03-17 15:47:49 +01:00
|
|
|
absl::string_view side,
|
2015-11-19 05:17:58 -08:00
|
|
|
rtc::FifoBuffer* in,
|
2018-06-19 15:03:05 +02:00
|
|
|
rtc::FifoBuffer* out)
|
|
|
|
|
: SSLDummyStreamBase(test, side, in, out) {}
|
2015-11-19 05:17:58 -08:00
|
|
|
};
|
|
|
|
|
|
2020-09-29 13:04:01 +02:00
|
|
|
class BufferQueueStream : public rtc::StreamInterface {
|
2015-11-19 05:17:58 -08:00
|
|
|
public:
|
|
|
|
|
BufferQueueStream(size_t capacity, size_t default_size)
|
2020-09-29 13:04:01 +02:00
|
|
|
: buffer_(capacity, default_size) {}
|
2015-11-19 05:17:58 -08:00
|
|
|
|
|
|
|
|
// Implementation of abstract StreamInterface methods.
|
|
|
|
|
|
|
|
|
|
// A buffer queue stream is always "open".
|
|
|
|
|
rtc::StreamState GetState() const override { return rtc::SS_OPEN; }
|
|
|
|
|
|
|
|
|
|
// Reading a buffer queue stream will either succeed or block.
|
2018-06-19 15:03:05 +02:00
|
|
|
rtc::StreamResult Read(void* buffer,
|
|
|
|
|
size_t buffer_len,
|
|
|
|
|
size_t* read,
|
|
|
|
|
int* error) override {
|
2020-09-29 13:04:01 +02:00
|
|
|
const bool was_writable = buffer_.is_writable();
|
|
|
|
|
if (!buffer_.ReadFront(buffer, buffer_len, read))
|
2015-11-19 05:17:58 -08:00
|
|
|
return rtc::SR_BLOCK;
|
2020-09-29 13:04:01 +02:00
|
|
|
|
|
|
|
|
if (!was_writable)
|
|
|
|
|
NotifyWritableForTest();
|
|
|
|
|
|
2015-11-19 05:17:58 -08:00
|
|
|
return rtc::SR_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Writing to a buffer queue stream will either succeed or block.
|
2018-06-19 15:03:05 +02:00
|
|
|
rtc::StreamResult Write(const void* data,
|
|
|
|
|
size_t data_len,
|
|
|
|
|
size_t* written,
|
|
|
|
|
int* error) override {
|
2020-09-29 13:04:01 +02:00
|
|
|
const bool was_readable = buffer_.is_readable();
|
|
|
|
|
if (!buffer_.WriteBack(data, data_len, written))
|
2015-11-19 05:17:58 -08:00
|
|
|
return rtc::SR_BLOCK;
|
2020-09-29 13:04:01 +02:00
|
|
|
|
|
|
|
|
if (!was_readable)
|
|
|
|
|
NotifyReadableForTest();
|
|
|
|
|
|
2015-11-19 05:17:58 -08:00
|
|
|
return rtc::SR_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// A buffer queue stream can not be closed.
|
|
|
|
|
void Close() override {}
|
|
|
|
|
|
|
|
|
|
protected:
|
2020-09-29 13:04:01 +02:00
|
|
|
void NotifyReadableForTest() { PostEvent(rtc::SE_READ, 0); }
|
|
|
|
|
void NotifyWritableForTest() { PostEvent(rtc::SE_WRITE, 0); }
|
2015-11-19 05:17:58 -08:00
|
|
|
|
2020-09-29 13:04:01 +02:00
|
|
|
private:
|
2020-10-05 12:43:53 +00:00
|
|
|
void PostEvent(int events, int err) {
|
|
|
|
|
thread_->PostTask(webrtc::ToQueuedTask(task_safety_, [this, events, err]() {
|
|
|
|
|
SignalEvent(this, events, err);
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtc::Thread* const thread_ = rtc::Thread::Current();
|
|
|
|
|
webrtc::ScopedTaskSafety task_safety_;
|
2020-09-29 13:04:01 +02:00
|
|
|
rtc::BufferQueue buffer_;
|
2015-11-19 05:17:58 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class SSLDummyStreamDTLS : public SSLDummyStreamBase {
|
|
|
|
|
public:
|
|
|
|
|
SSLDummyStreamDTLS(SSLStreamAdapterTestBase* test,
|
2022-03-17 15:47:49 +01:00
|
|
|
absl::string_view side,
|
2015-11-19 05:17:58 -08:00
|
|
|
BufferQueueStream* in,
|
2018-06-19 15:03:05 +02:00
|
|
|
BufferQueueStream* out)
|
|
|
|
|
: SSLDummyStreamBase(test, side, in, out) {}
|
2015-11-19 05:17:58 -08:00
|
|
|
};
|
|
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
static const int kFifoBufferSize = 4096;
|
2015-11-19 05:17:58 -08:00
|
|
|
static const int kBufferCapacity = 1;
|
|
|
|
|
static const size_t kDefaultBufferSize = 2048;
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2019-04-09 15:11:12 +02:00
|
|
|
class SSLStreamAdapterTestBase : public ::testing::Test,
|
2014-05-13 18:00:26 +00:00
|
|
|
public sigslot::has_slots<> {
|
|
|
|
|
public:
|
2015-10-08 09:42:49 -07:00
|
|
|
SSLStreamAdapterTestBase(
|
2022-03-17 15:47:49 +01:00
|
|
|
absl::string_view client_cert_pem,
|
|
|
|
|
absl::string_view client_private_key_pem,
|
2015-10-08 09:42:49 -07:00
|
|
|
bool dtls,
|
|
|
|
|
rtc::KeyParams client_key_type = rtc::KeyParams(rtc::KT_DEFAULT),
|
|
|
|
|
rtc::KeyParams server_key_type = rtc::KeyParams(rtc::KT_DEFAULT))
|
2015-11-19 05:17:58 -08:00
|
|
|
: client_cert_pem_(client_cert_pem),
|
|
|
|
|
client_private_key_pem_(client_private_key_pem),
|
|
|
|
|
client_key_type_(client_key_type),
|
|
|
|
|
server_key_type_(server_key_type),
|
2017-02-27 14:06:41 -08:00
|
|
|
client_stream_(nullptr),
|
|
|
|
|
server_stream_(nullptr),
|
2015-08-17 14:08:59 +02:00
|
|
|
delay_(0),
|
|
|
|
|
mtu_(1460),
|
|
|
|
|
loss_(0),
|
|
|
|
|
lose_first_packet_(false),
|
|
|
|
|
damage_(false),
|
|
|
|
|
dtls_(dtls),
|
|
|
|
|
handshake_wait_(5000),
|
2019-04-01 18:25:23 +00:00
|
|
|
identities_set_(false) {
|
2014-05-13 18:00:26 +00:00
|
|
|
// Set use of the test RNG to get predictable loss patterns.
|
|
|
|
|
rtc::SetRandomTestMode(true);
|
2015-11-19 05:17:58 -08:00
|
|
|
}
|
|
|
|
|
|
2017-10-24 10:08:26 -07:00
|
|
|
~SSLStreamAdapterTestBase() override {
|
2015-11-19 05:17:58 -08:00
|
|
|
// Put it back for the next test.
|
|
|
|
|
rtc::SetRandomTestMode(false);
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-19 12:20:51 -08:00
|
|
|
void SetUp() override {
|
2015-11-19 05:17:58 -08:00
|
|
|
CreateStreams();
|
|
|
|
|
|
2020-03-20 22:51:32 +01:00
|
|
|
client_ssl_ =
|
|
|
|
|
rtc::SSLStreamAdapter::Create(absl::WrapUnique(client_stream_));
|
|
|
|
|
server_ssl_ =
|
|
|
|
|
rtc::SSLStreamAdapter::Create(absl::WrapUnique(server_stream_));
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Set up the slots
|
|
|
|
|
client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
|
|
|
|
|
server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
|
|
|
|
|
|
2020-03-20 22:51:32 +01:00
|
|
|
std::unique_ptr<rtc::SSLIdentity> client_identity;
|
2015-11-19 05:17:58 -08:00
|
|
|
if (!client_cert_pem_.empty() && !client_private_key_pem_.empty()) {
|
2020-03-20 22:51:32 +01:00
|
|
|
client_identity = rtc::SSLIdentity::CreateFromPEMStrings(
|
2015-11-19 05:17:58 -08:00
|
|
|
client_private_key_pem_, client_cert_pem_);
|
2014-05-13 18:00:26 +00:00
|
|
|
} else {
|
2020-03-20 22:51:32 +01:00
|
|
|
client_identity = rtc::SSLIdentity::Create("client", client_key_type_);
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
2020-03-20 22:51:32 +01:00
|
|
|
auto server_identity = rtc::SSLIdentity::Create("server", server_key_type_);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2020-03-20 22:51:32 +01:00
|
|
|
client_ssl_->SetIdentity(std::move(client_identity));
|
|
|
|
|
server_ssl_->SetIdentity(std::move(server_identity));
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
2015-11-19 12:20:51 -08:00
|
|
|
void TearDown() override {
|
2015-11-19 05:17:58 -08:00
|
|
|
client_ssl_.reset(nullptr);
|
|
|
|
|
server_ssl_.reset(nullptr);
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
2015-11-19 05:17:58 -08:00
|
|
|
virtual void CreateStreams() = 0;
|
|
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
// Recreate the client/server identities with the specified validity period.
|
2021-07-26 16:03:14 +02:00
|
|
|
// `not_before` and `not_after` are offsets from the current time in number
|
2014-05-13 18:00:26 +00:00
|
|
|
// of seconds.
|
|
|
|
|
void ResetIdentitiesWithValidity(int not_before, int not_after) {
|
2015-11-19 05:17:58 -08:00
|
|
|
CreateStreams();
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2020-03-20 22:51:32 +01:00
|
|
|
client_ssl_ =
|
|
|
|
|
rtc::SSLStreamAdapter::Create(absl::WrapUnique(client_stream_));
|
|
|
|
|
server_ssl_ =
|
|
|
|
|
rtc::SSLStreamAdapter::Create(absl::WrapUnique(server_stream_));
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
client_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
|
|
|
|
|
server_ssl_->SignalEvent.connect(this, &SSLStreamAdapterTestBase::OnEvent);
|
|
|
|
|
|
2015-12-01 13:06:34 +01:00
|
|
|
time_t now = time(nullptr);
|
|
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
rtc::SSLIdentityParams client_params;
|
2015-10-08 09:42:49 -07:00
|
|
|
client_params.key_params = rtc::KeyParams(rtc::KT_DEFAULT);
|
2014-05-13 18:00:26 +00:00
|
|
|
client_params.common_name = "client";
|
2015-12-01 13:06:34 +01:00
|
|
|
client_params.not_before = now + not_before;
|
|
|
|
|
client_params.not_after = now + not_after;
|
2020-03-20 22:51:32 +01:00
|
|
|
auto client_identity = rtc::SSLIdentity::CreateForTest(client_params);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
rtc::SSLIdentityParams server_params;
|
2015-10-08 09:42:49 -07:00
|
|
|
server_params.key_params = rtc::KeyParams(rtc::KT_DEFAULT);
|
2014-05-13 18:00:26 +00:00
|
|
|
server_params.common_name = "server";
|
2015-12-01 13:06:34 +01:00
|
|
|
server_params.not_before = now + not_before;
|
|
|
|
|
server_params.not_after = now + not_after;
|
2020-03-20 22:51:32 +01:00
|
|
|
auto server_identity = rtc::SSLIdentity::CreateForTest(server_params);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2020-03-20 22:51:32 +01:00
|
|
|
client_ssl_->SetIdentity(std::move(client_identity));
|
|
|
|
|
server_ssl_->SetIdentity(std::move(server_identity));
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
virtual void OnEvent(rtc::StreamInterface* stream, int sig, int err) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "SSLStreamAdapterTestBase::OnEvent sig=" << sig;
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
if (sig & rtc::SE_READ) {
|
|
|
|
|
ReadData(stream);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((stream == client_ssl_.get()) && (sig & rtc::SE_WRITE)) {
|
|
|
|
|
WriteData();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
void SetPeerIdentitiesByDigest(bool correct, bool expect_success) {
|
|
|
|
|
unsigned char server_digest[20];
|
|
|
|
|
size_t server_digest_len;
|
|
|
|
|
unsigned char client_digest[20];
|
|
|
|
|
size_t client_digest_len;
|
2014-05-13 18:00:26 +00:00
|
|
|
bool rv;
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
rtc::SSLPeerCertificateDigestError err;
|
|
|
|
|
rtc::SSLPeerCertificateDigestError expected_err =
|
|
|
|
|
expect_success
|
|
|
|
|
? rtc::SSLPeerCertificateDigestError::NONE
|
|
|
|
|
: rtc::SSLPeerCertificateDigestError::VERIFICATION_FAILED;
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_INFO) << "Setting peer identities by digest";
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2020-03-20 22:51:32 +01:00
|
|
|
rv = server_identity()->certificate().ComputeDigest(
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
rtc::DIGEST_SHA_1, server_digest, 20, &server_digest_len);
|
2014-05-13 18:00:26 +00:00
|
|
|
ASSERT_TRUE(rv);
|
2020-03-20 22:51:32 +01:00
|
|
|
rv = client_identity()->certificate().ComputeDigest(
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
rtc::DIGEST_SHA_1, client_digest, 20, &client_digest_len);
|
|
|
|
|
ASSERT_TRUE(rv);
|
|
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
if (!correct) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_INFO) << "Setting bogus digest for server cert";
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
server_digest[0]++;
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
rv = client_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, server_digest,
|
|
|
|
|
server_digest_len, &err);
|
|
|
|
|
EXPECT_EQ(expected_err, err);
|
|
|
|
|
EXPECT_EQ(expect_success, rv);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
if (!correct) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_INFO) << "Setting bogus digest for client cert";
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
client_digest[0]++;
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
rv = server_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, client_digest,
|
|
|
|
|
client_digest_len, &err);
|
|
|
|
|
EXPECT_EQ(expected_err, err);
|
|
|
|
|
EXPECT_EQ(expect_success, rv);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
identities_set_ = true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-20 12:48:41 +02:00
|
|
|
void SetupProtocolVersions(rtc::SSLProtocolVersion server_version,
|
|
|
|
|
rtc::SSLProtocolVersion client_version) {
|
|
|
|
|
server_ssl_->SetMaxProtocolVersion(server_version);
|
|
|
|
|
client_ssl_->SetMaxProtocolVersion(client_version);
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
void TestHandshake(bool expect_success = true) {
|
2018-06-19 15:03:05 +02:00
|
|
|
server_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS : rtc::SSL_MODE_TLS);
|
|
|
|
|
client_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS : rtc::SSL_MODE_TLS);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
if (!dtls_) {
|
|
|
|
|
// Make sure we simulate a reliable network for TLS.
|
|
|
|
|
// This is just a check to make sure that people don't write wrong
|
|
|
|
|
// tests.
|
2017-02-07 07:18:43 -08:00
|
|
|
RTC_CHECK_EQ(1460, mtu_);
|
|
|
|
|
RTC_CHECK(!loss_);
|
|
|
|
|
RTC_CHECK(!lose_first_packet_);
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!identities_set_)
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
SetPeerIdentitiesByDigest(true, true);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Start the handshake
|
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
|
|
server_ssl_->SetServerRole();
|
2016-08-11 12:01:49 -07:00
|
|
|
rv = server_ssl_->StartSSL();
|
2014-05-13 18:00:26 +00:00
|
|
|
ASSERT_EQ(0, rv);
|
|
|
|
|
|
2016-08-11 12:01:49 -07:00
|
|
|
rv = client_ssl_->StartSSL();
|
2014-05-13 18:00:26 +00:00
|
|
|
ASSERT_EQ(0, rv);
|
|
|
|
|
|
|
|
|
|
// Now run the handshake
|
|
|
|
|
if (expect_success) {
|
2018-06-19 15:03:05 +02:00
|
|
|
EXPECT_TRUE_WAIT((client_ssl_->GetState() == rtc::SS_OPEN) &&
|
|
|
|
|
(server_ssl_->GetState() == rtc::SS_OPEN),
|
2014-05-13 18:00:26 +00:00
|
|
|
handshake_wait_);
|
|
|
|
|
} else {
|
|
|
|
|
EXPECT_TRUE_WAIT(client_ssl_->GetState() == rtc::SS_CLOSED,
|
|
|
|
|
handshake_wait_);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-10 16:23:03 -08:00
|
|
|
// This tests that the handshake can complete before the identity is verified,
|
|
|
|
|
// and the identity will be verified after the fact. It also verifies that
|
|
|
|
|
// packets can't be read or written before the identity has been verified.
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
void TestHandshakeWithDelayedIdentity(bool valid_identity) {
|
|
|
|
|
server_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS : rtc::SSL_MODE_TLS);
|
|
|
|
|
client_ssl_->SetMode(dtls_ ? rtc::SSL_MODE_DTLS : rtc::SSL_MODE_TLS);
|
|
|
|
|
|
|
|
|
|
if (!dtls_) {
|
|
|
|
|
// Make sure we simulate a reliable network for TLS.
|
|
|
|
|
// This is just a check to make sure that people don't write wrong
|
|
|
|
|
// tests.
|
2017-02-07 07:18:43 -08:00
|
|
|
RTC_CHECK_EQ(1460, mtu_);
|
|
|
|
|
RTC_CHECK(!loss_);
|
|
|
|
|
RTC_CHECK(!lose_first_packet_);
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Start the handshake
|
|
|
|
|
server_ssl_->SetServerRole();
|
2020-12-10 16:23:03 -08:00
|
|
|
ASSERT_EQ(0, server_ssl_->StartSSL());
|
|
|
|
|
ASSERT_EQ(0, client_ssl_->StartSSL());
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
|
|
|
|
|
// Now run the handshake.
|
|
|
|
|
EXPECT_TRUE_WAIT(
|
|
|
|
|
client_ssl_->IsTlsConnected() && server_ssl_->IsTlsConnected(),
|
|
|
|
|
handshake_wait_);
|
|
|
|
|
|
|
|
|
|
// Until the identity has been verified, the state should still be
|
|
|
|
|
// SS_OPENING and writes should return SR_BLOCK.
|
|
|
|
|
EXPECT_EQ(rtc::SS_OPENING, client_ssl_->GetState());
|
|
|
|
|
EXPECT_EQ(rtc::SS_OPENING, server_ssl_->GetState());
|
|
|
|
|
unsigned char packet[1];
|
|
|
|
|
size_t sent;
|
|
|
|
|
EXPECT_EQ(rtc::SR_BLOCK, client_ssl_->Write(&packet, 1, &sent, 0));
|
|
|
|
|
EXPECT_EQ(rtc::SR_BLOCK, server_ssl_->Write(&packet, 1, &sent, 0));
|
|
|
|
|
|
2020-12-10 16:23:03 -08:00
|
|
|
// Collect both of the certificate digests; needs to be done before calling
|
|
|
|
|
// SetPeerCertificateDigest as that may reset the identity.
|
|
|
|
|
unsigned char server_digest[20];
|
|
|
|
|
size_t server_digest_len;
|
|
|
|
|
unsigned char client_digest[20];
|
|
|
|
|
size_t client_digest_len;
|
|
|
|
|
bool rv;
|
|
|
|
|
|
|
|
|
|
rv = server_identity()->certificate().ComputeDigest(
|
|
|
|
|
rtc::DIGEST_SHA_1, server_digest, 20, &server_digest_len);
|
|
|
|
|
ASSERT_TRUE(rv);
|
|
|
|
|
rv = client_identity()->certificate().ComputeDigest(
|
|
|
|
|
rtc::DIGEST_SHA_1, client_digest, 20, &client_digest_len);
|
|
|
|
|
ASSERT_TRUE(rv);
|
|
|
|
|
|
|
|
|
|
if (!valid_identity) {
|
|
|
|
|
RTC_LOG(LS_INFO) << "Setting bogus digest for client/server certs";
|
|
|
|
|
client_digest[0]++;
|
|
|
|
|
server_digest[0]++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set the peer certificate digest for the client.
|
|
|
|
|
rtc::SSLPeerCertificateDigestError err;
|
|
|
|
|
rtc::SSLPeerCertificateDigestError expected_err =
|
|
|
|
|
valid_identity
|
|
|
|
|
? rtc::SSLPeerCertificateDigestError::NONE
|
|
|
|
|
: rtc::SSLPeerCertificateDigestError::VERIFICATION_FAILED;
|
|
|
|
|
rv = client_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, server_digest,
|
|
|
|
|
server_digest_len, &err);
|
|
|
|
|
EXPECT_EQ(expected_err, err);
|
|
|
|
|
EXPECT_EQ(valid_identity, rv);
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
// State should then transition to SS_OPEN or SS_CLOSED based on validation
|
|
|
|
|
// of the identity.
|
|
|
|
|
if (valid_identity) {
|
|
|
|
|
EXPECT_EQ(rtc::SS_OPEN, client_ssl_->GetState());
|
2020-12-10 16:23:03 -08:00
|
|
|
// If the client sends a packet while the server still hasn't verified the
|
|
|
|
|
// client identity, the server should continue to return SR_BLOCK.
|
|
|
|
|
EXPECT_EQ(rtc::SR_SUCCESS, client_ssl_->Write(&packet, 1, &sent, 0));
|
|
|
|
|
EXPECT_EQ(rtc::SR_BLOCK, server_ssl_->Read(&packet, 1, 0, 0));
|
2020-11-15 13:01:15 -08:00
|
|
|
} else {
|
2020-12-10 07:55:28 +00:00
|
|
|
EXPECT_EQ(rtc::SS_CLOSED, client_ssl_->GetState());
|
2020-12-10 16:23:03 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set the peer certificate digest for the server.
|
|
|
|
|
rv = server_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, client_digest,
|
|
|
|
|
client_digest_len, &err);
|
|
|
|
|
EXPECT_EQ(expected_err, err);
|
|
|
|
|
EXPECT_EQ(valid_identity, rv);
|
|
|
|
|
if (valid_identity) {
|
|
|
|
|
EXPECT_EQ(rtc::SS_OPEN, server_ssl_->GetState());
|
|
|
|
|
} else {
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
EXPECT_EQ(rtc::SS_CLOSED, server_ssl_->GetState());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
rtc::StreamResult DataWritten(SSLDummyStreamBase* from,
|
|
|
|
|
const void* data,
|
|
|
|
|
size_t data_len,
|
|
|
|
|
size_t* written,
|
|
|
|
|
int* error) {
|
2014-05-13 18:00:26 +00:00
|
|
|
// Randomly drop loss_ percent of packets
|
Use suffixed {uint,int}{8,16,32,64}_t types.
Removes the use of uint8, etc. in favor of uint8_t.
BUG=webrtc:5024
R=henrik.lundin@webrtc.org, henrikg@webrtc.org, perkj@webrtc.org, solenberg@webrtc.org, stefan@webrtc.org, tina.legrand@webrtc.org
Review URL: https://codereview.webrtc.org/1362503003 .
Cr-Commit-Position: refs/heads/master@{#10196}
2015-10-07 12:23:21 +02:00
|
|
|
if (rtc::CreateRandomId() % 100 < static_cast<uint32_t>(loss_)) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "Randomly dropping packet, size=" << data_len;
|
2014-05-13 18:00:26 +00:00
|
|
|
*written = data_len;
|
|
|
|
|
return rtc::SR_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
if (dtls_ && (data_len > mtu_)) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "Dropping packet > mtu, size=" << data_len;
|
2014-05-13 18:00:26 +00:00
|
|
|
*written = data_len;
|
|
|
|
|
return rtc::SR_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Optionally damage application data (type 23). Note that we don't damage
|
|
|
|
|
// handshake packets and we damage the last byte to keep the header
|
|
|
|
|
// intact but break the MAC.
|
2018-06-19 15:03:05 +02:00
|
|
|
if (damage_ && (*static_cast<const unsigned char*>(data) == 23)) {
|
2014-05-13 18:00:26 +00:00
|
|
|
std::vector<char> buf(data_len);
|
|
|
|
|
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "Damaging packet";
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
memcpy(&buf[0], data, data_len);
|
|
|
|
|
buf[data_len - 1]++;
|
|
|
|
|
|
|
|
|
|
return from->WriteData(&buf[0], data_len, written, error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return from->WriteData(data, data_len, written, error);
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
void SetDelay(int delay) { delay_ = delay; }
|
2014-05-13 18:00:26 +00:00
|
|
|
int GetDelay() { return delay_; }
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
void SetLoseFirstPacket(bool lose) { lose_first_packet_ = lose; }
|
2014-05-13 18:00:26 +00:00
|
|
|
bool GetLoseFirstPacket() { return lose_first_packet_; }
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
void SetLoss(int percent) { loss_ = percent; }
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
void SetDamage() { damage_ = true; }
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
void SetMtu(size_t mtu) { mtu_ = mtu; }
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
void SetHandshakeWait(int wait) { handshake_wait_ = wait; }
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2015-11-18 19:41:53 -08:00
|
|
|
void SetDtlsSrtpCryptoSuites(const std::vector<int>& ciphers, bool client) {
|
2014-05-13 18:00:26 +00:00
|
|
|
if (client)
|
2015-11-18 19:41:53 -08:00
|
|
|
client_ssl_->SetDtlsSrtpCryptoSuites(ciphers);
|
2014-05-13 18:00:26 +00:00
|
|
|
else
|
2015-11-18 19:41:53 -08:00
|
|
|
server_ssl_->SetDtlsSrtpCryptoSuites(ciphers);
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
2015-11-18 19:41:53 -08:00
|
|
|
bool GetDtlsSrtpCryptoSuite(bool client, int* retval) {
|
2014-05-13 18:00:26 +00:00
|
|
|
if (client)
|
2015-11-18 19:41:53 -08:00
|
|
|
return client_ssl_->GetDtlsSrtpCryptoSuite(retval);
|
2014-05-13 18:00:26 +00:00
|
|
|
else
|
2015-11-18 19:41:53 -08:00
|
|
|
return server_ssl_->GetDtlsSrtpCryptoSuite(retval);
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
2016-04-26 03:13:22 -07:00
|
|
|
std::unique_ptr<rtc::SSLCertificate> GetPeerCertificate(bool client) {
|
2018-02-23 13:04:51 -08:00
|
|
|
std::unique_ptr<rtc::SSLCertChain> chain;
|
2014-05-13 18:00:26 +00:00
|
|
|
if (client)
|
2018-02-23 13:04:51 -08:00
|
|
|
chain = client_ssl_->GetPeerSSLCertChain();
|
2014-05-13 18:00:26 +00:00
|
|
|
else
|
2018-02-23 13:04:51 -08:00
|
|
|
chain = server_ssl_->GetPeerSSLCertChain();
|
2018-10-16 15:23:31 -07:00
|
|
|
return (chain && chain->GetSize()) ? chain->Get(0).Clone() : nullptr;
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
2015-10-05 12:43:27 -07:00
|
|
|
bool GetSslCipherSuite(bool client, int* retval) {
|
2015-02-11 22:34:36 +00:00
|
|
|
if (client)
|
2015-09-30 21:48:54 -07:00
|
|
|
return client_ssl_->GetSslCipherSuite(retval);
|
2015-02-11 22:34:36 +00:00
|
|
|
else
|
2015-09-30 21:48:54 -07:00
|
|
|
return server_ssl_->GetSslCipherSuite(retval);
|
2015-02-11 22:34:36 +00:00
|
|
|
}
|
|
|
|
|
|
2016-03-11 00:06:47 -08:00
|
|
|
int GetSslVersion(bool client) {
|
|
|
|
|
if (client)
|
|
|
|
|
return client_ssl_->GetSslVersion();
|
|
|
|
|
else
|
|
|
|
|
return server_ssl_->GetSslVersion();
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
bool ExportKeyingMaterial(const char* label,
|
|
|
|
|
const unsigned char* context,
|
2014-05-13 18:00:26 +00:00
|
|
|
size_t context_len,
|
|
|
|
|
bool use_context,
|
|
|
|
|
bool client,
|
2018-06-19 15:03:05 +02:00
|
|
|
unsigned char* result,
|
2014-05-13 18:00:26 +00:00
|
|
|
size_t result_len) {
|
|
|
|
|
if (client)
|
2018-06-19 15:03:05 +02:00
|
|
|
return client_ssl_->ExportKeyingMaterial(label, context, context_len,
|
|
|
|
|
use_context, result, result_len);
|
2014-05-13 18:00:26 +00:00
|
|
|
else
|
2018-06-19 15:03:05 +02:00
|
|
|
return server_ssl_->ExportKeyingMaterial(label, context, context_len,
|
|
|
|
|
use_context, result, result_len);
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// To be implemented by subclasses.
|
|
|
|
|
virtual void WriteData() = 0;
|
2018-06-19 15:03:05 +02:00
|
|
|
virtual void ReadData(rtc::StreamInterface* stream) = 0;
|
2014-05-13 18:00:26 +00:00
|
|
|
virtual void TestTransfer(int size) = 0;
|
|
|
|
|
|
|
|
|
|
protected:
|
2020-03-20 22:51:32 +01:00
|
|
|
rtc::SSLIdentity* client_identity() const {
|
|
|
|
|
if (!client_ssl_) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
return client_ssl_->GetIdentityForTesting();
|
|
|
|
|
}
|
|
|
|
|
rtc::SSLIdentity* server_identity() const {
|
|
|
|
|
if (!server_ssl_) {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
return server_ssl_->GetIdentityForTesting();
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-19 05:17:58 -08:00
|
|
|
std::string client_cert_pem_;
|
|
|
|
|
std::string client_private_key_pem_;
|
|
|
|
|
rtc::KeyParams client_key_type_;
|
|
|
|
|
rtc::KeyParams server_key_type_;
|
2018-06-19 15:03:05 +02:00
|
|
|
SSLDummyStreamBase* client_stream_; // freed by client_ssl_ destructor
|
|
|
|
|
SSLDummyStreamBase* server_stream_; // freed by server_ssl_ destructor
|
2016-04-26 03:13:22 -07:00
|
|
|
std::unique_ptr<rtc::SSLStreamAdapter> client_ssl_;
|
|
|
|
|
std::unique_ptr<rtc::SSLStreamAdapter> server_ssl_;
|
2014-05-13 18:00:26 +00:00
|
|
|
int delay_;
|
|
|
|
|
size_t mtu_;
|
|
|
|
|
int loss_;
|
|
|
|
|
bool lose_first_packet_;
|
|
|
|
|
bool damage_;
|
|
|
|
|
bool dtls_;
|
|
|
|
|
int handshake_wait_;
|
|
|
|
|
bool identities_set_;
|
|
|
|
|
};
|
|
|
|
|
|
2015-08-17 14:08:59 +02:00
|
|
|
class SSLStreamAdapterTestTLS
|
|
|
|
|
: public SSLStreamAdapterTestBase,
|
2015-10-08 09:42:49 -07:00
|
|
|
public WithParamInterface<tuple<rtc::KeyParams, rtc::KeyParams>> {
|
2014-05-13 18:00:26 +00:00
|
|
|
public:
|
2015-08-17 14:08:59 +02:00
|
|
|
SSLStreamAdapterTestTLS()
|
|
|
|
|
: SSLStreamAdapterTestBase("",
|
|
|
|
|
"",
|
|
|
|
|
false,
|
|
|
|
|
::testing::get<0>(GetParam()),
|
2015-11-19 05:17:58 -08:00
|
|
|
::testing::get<1>(GetParam())),
|
|
|
|
|
client_buffer_(kFifoBufferSize),
|
2018-06-19 15:03:05 +02:00
|
|
|
server_buffer_(kFifoBufferSize) {}
|
2015-11-19 05:17:58 -08:00
|
|
|
|
2015-11-19 12:20:51 -08:00
|
|
|
void CreateStreams() override {
|
2015-11-19 05:17:58 -08:00
|
|
|
client_stream_ =
|
|
|
|
|
new SSLDummyStreamTLS(this, "c2s", &client_buffer_, &server_buffer_);
|
|
|
|
|
server_stream_ =
|
|
|
|
|
new SSLDummyStreamTLS(this, "s2c", &server_buffer_, &client_buffer_);
|
|
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Test data transfer for TLS
|
2016-04-29 06:09:15 -07:00
|
|
|
void TestTransfer(int size) override {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_INFO) << "Starting transfer test with " << size << " bytes";
|
2014-05-13 18:00:26 +00:00
|
|
|
// Create some dummy data to send.
|
|
|
|
|
size_t received;
|
|
|
|
|
|
|
|
|
|
send_stream_.ReserveSize(size);
|
|
|
|
|
for (int i = 0; i < size; ++i) {
|
|
|
|
|
char ch = static_cast<char>(i);
|
2017-02-27 14:06:41 -08:00
|
|
|
send_stream_.Write(&ch, 1, nullptr, nullptr);
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
send_stream_.Rewind();
|
|
|
|
|
|
|
|
|
|
// Prepare the receive stream.
|
|
|
|
|
recv_stream_.ReserveSize(size);
|
|
|
|
|
|
|
|
|
|
// Start sending
|
|
|
|
|
WriteData();
|
|
|
|
|
|
|
|
|
|
// Wait for the client to close
|
|
|
|
|
EXPECT_TRUE_WAIT(server_ssl_->GetState() == rtc::SS_CLOSED, 10000);
|
|
|
|
|
|
|
|
|
|
// Now check the data
|
|
|
|
|
recv_stream_.GetSize(&received);
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ(static_cast<size_t>(size), received);
|
2018-06-19 15:03:05 +02:00
|
|
|
EXPECT_EQ(0,
|
|
|
|
|
memcmp(send_stream_.GetBuffer(), recv_stream_.GetBuffer(), size));
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
2016-04-29 06:09:15 -07:00
|
|
|
void WriteData() override {
|
2014-05-13 18:00:26 +00:00
|
|
|
size_t position, tosend, size;
|
|
|
|
|
rtc::StreamResult rv;
|
|
|
|
|
size_t sent;
|
|
|
|
|
char block[kBlockSize];
|
|
|
|
|
|
|
|
|
|
send_stream_.GetSize(&size);
|
|
|
|
|
if (!size)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
send_stream_.GetPosition(&position);
|
2017-02-27 14:06:41 -08:00
|
|
|
if (send_stream_.Read(block, sizeof(block), &tosend, nullptr) !=
|
2014-05-13 18:00:26 +00:00
|
|
|
rtc::SR_EOS) {
|
|
|
|
|
rv = client_ssl_->Write(block, tosend, &sent, 0);
|
|
|
|
|
|
|
|
|
|
if (rv == rtc::SR_SUCCESS) {
|
|
|
|
|
send_stream_.SetPosition(position + sent);
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "Sent: " << position + sent;
|
2014-05-13 18:00:26 +00:00
|
|
|
} else if (rv == rtc::SR_BLOCK) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "Blocked...";
|
2014-05-13 18:00:26 +00:00
|
|
|
send_stream_.SetPosition(position);
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
ADD_FAILURE();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Now close
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_INFO) << "Wrote " << position << " bytes. Closing";
|
2014-05-13 18:00:26 +00:00
|
|
|
client_ssl_->Close();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
void ReadData(rtc::StreamInterface* stream) override {
|
2014-05-13 18:00:26 +00:00
|
|
|
char buffer[1600];
|
|
|
|
|
size_t bread;
|
|
|
|
|
int err2;
|
|
|
|
|
rtc::StreamResult r;
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
r = stream->Read(buffer, sizeof(buffer), &bread, &err2);
|
|
|
|
|
|
|
|
|
|
if (r == rtc::SR_ERROR || r == rtc::SR_EOS) {
|
|
|
|
|
// Unfortunately, errors are the way that the stream adapter
|
2015-11-19 12:20:51 -08:00
|
|
|
// signals close in OpenSSL.
|
2014-05-13 18:00:26 +00:00
|
|
|
stream->Close();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (r == rtc::SR_BLOCK)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(rtc::SR_SUCCESS, r);
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "Read " << bread;
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2017-02-27 14:06:41 -08:00
|
|
|
recv_stream_.Write(buffer, bread, nullptr, nullptr);
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2015-11-19 05:17:58 -08:00
|
|
|
rtc::FifoBuffer client_buffer_;
|
|
|
|
|
rtc::FifoBuffer server_buffer_;
|
2014-05-13 18:00:26 +00:00
|
|
|
rtc::MemoryStream send_stream_;
|
|
|
|
|
rtc::MemoryStream recv_stream_;
|
|
|
|
|
};
|
|
|
|
|
|
2020-03-09 19:39:36 +01:00
|
|
|
class SSLStreamAdapterTestDTLSBase : public SSLStreamAdapterTestBase {
|
2014-05-13 18:00:26 +00:00
|
|
|
public:
|
2020-03-09 19:39:36 +01:00
|
|
|
SSLStreamAdapterTestDTLSBase(rtc::KeyParams param1, rtc::KeyParams param2)
|
|
|
|
|
: SSLStreamAdapterTestBase("", "", true, param1, param2),
|
2015-11-19 05:17:58 -08:00
|
|
|
client_buffer_(kBufferCapacity, kDefaultBufferSize),
|
|
|
|
|
server_buffer_(kBufferCapacity, kDefaultBufferSize),
|
2015-08-17 14:08:59 +02:00
|
|
|
packet_size_(1000),
|
|
|
|
|
count_(0),
|
|
|
|
|
sent_(0) {}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2022-03-17 15:47:49 +01:00
|
|
|
SSLStreamAdapterTestDTLSBase(absl::string_view cert_pem,
|
|
|
|
|
absl::string_view private_key_pem)
|
2018-06-19 15:03:05 +02:00
|
|
|
: SSLStreamAdapterTestBase(cert_pem, private_key_pem, true),
|
|
|
|
|
client_buffer_(kBufferCapacity, kDefaultBufferSize),
|
|
|
|
|
server_buffer_(kBufferCapacity, kDefaultBufferSize),
|
|
|
|
|
packet_size_(1000),
|
|
|
|
|
count_(0),
|
|
|
|
|
sent_(0) {}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2015-11-19 12:20:51 -08:00
|
|
|
void CreateStreams() override {
|
2015-11-19 05:17:58 -08:00
|
|
|
client_stream_ =
|
|
|
|
|
new SSLDummyStreamDTLS(this, "c2s", &client_buffer_, &server_buffer_);
|
|
|
|
|
server_stream_ =
|
|
|
|
|
new SSLDummyStreamDTLS(this, "s2c", &server_buffer_, &client_buffer_);
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-29 06:09:15 -07:00
|
|
|
void WriteData() override {
|
2018-06-19 15:03:05 +02:00
|
|
|
unsigned char* packet = new unsigned char[1600];
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2015-11-19 05:17:58 -08:00
|
|
|
while (sent_ < count_) {
|
2015-11-19 12:20:51 -08:00
|
|
|
unsigned int rand_state = sent_;
|
|
|
|
|
packet[0] = sent_;
|
|
|
|
|
for (size_t i = 1; i < packet_size_; i++) {
|
|
|
|
|
// This is a simple LC PRNG. Keep in synch with identical code below.
|
|
|
|
|
rand_state = (rand_state * 251 + 19937) >> 7;
|
|
|
|
|
packet[i] = rand_state & 0xff;
|
|
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
size_t sent;
|
2015-11-19 12:20:51 -08:00
|
|
|
rtc::StreamResult rv = client_ssl_->Write(packet, packet_size_, &sent, 0);
|
2014-05-13 18:00:26 +00:00
|
|
|
if (rv == rtc::SR_SUCCESS) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "Sent: " << sent_;
|
2014-05-13 18:00:26 +00:00
|
|
|
sent_++;
|
|
|
|
|
} else if (rv == rtc::SR_BLOCK) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "Blocked...";
|
2014-05-13 18:00:26 +00:00
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
ADD_FAILURE();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-11-19 05:17:58 -08:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
delete[] packet;
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
void ReadData(rtc::StreamInterface* stream) override {
|
2014-05-13 18:00:26 +00:00
|
|
|
unsigned char buffer[2000];
|
|
|
|
|
size_t bread;
|
|
|
|
|
int err2;
|
|
|
|
|
rtc::StreamResult r;
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
r = stream->Read(buffer, 2000, &bread, &err2);
|
|
|
|
|
|
|
|
|
|
if (r == rtc::SR_ERROR) {
|
|
|
|
|
// Unfortunately, errors are the way that the stream adapter
|
|
|
|
|
// signals close right now
|
|
|
|
|
stream->Close();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (r == rtc::SR_BLOCK)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(rtc::SR_SUCCESS, r);
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "Read " << bread;
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Now parse the datagram
|
|
|
|
|
ASSERT_EQ(packet_size_, bread);
|
2015-11-19 12:20:51 -08:00
|
|
|
unsigned char packet_num = buffer[0];
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2015-11-19 12:20:51 -08:00
|
|
|
unsigned int rand_state = packet_num;
|
|
|
|
|
for (size_t i = 1; i < packet_size_; i++) {
|
|
|
|
|
// This is a simple LC PRNG. Keep in synch with identical code above.
|
|
|
|
|
rand_state = (rand_state * 251 + 19937) >> 7;
|
|
|
|
|
ASSERT_EQ(rand_state & 0xff, buffer[i]);
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
|
|
|
|
received_.insert(packet_num);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-29 06:09:15 -07:00
|
|
|
void TestTransfer(int count) override {
|
2014-05-13 18:00:26 +00:00
|
|
|
count_ = count;
|
|
|
|
|
|
|
|
|
|
WriteData();
|
|
|
|
|
|
|
|
|
|
EXPECT_TRUE_WAIT(sent_ == count_, 10000);
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_INFO) << "sent_ == " << sent_;
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
if (damage_) {
|
|
|
|
|
WAIT(false, 2000);
|
|
|
|
|
EXPECT_EQ(0U, received_.size());
|
|
|
|
|
} else if (loss_ == 0) {
|
2018-06-19 15:03:05 +02:00
|
|
|
EXPECT_EQ_WAIT(static_cast<size_t>(sent_), received_.size(), 1000);
|
2014-05-13 18:00:26 +00:00
|
|
|
} else {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_INFO) << "Sent " << sent_ << " packets; received "
|
|
|
|
|
<< received_.size();
|
2014-05-13 18:00:26 +00:00
|
|
|
}
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2020-03-09 19:39:36 +01:00
|
|
|
protected:
|
2015-11-19 05:17:58 -08:00
|
|
|
BufferQueueStream client_buffer_;
|
|
|
|
|
BufferQueueStream server_buffer_;
|
2020-03-09 19:39:36 +01:00
|
|
|
|
|
|
|
|
private:
|
2014-05-13 18:00:26 +00:00
|
|
|
size_t packet_size_;
|
|
|
|
|
int count_;
|
|
|
|
|
int sent_;
|
|
|
|
|
std::set<int> received_;
|
|
|
|
|
};
|
|
|
|
|
|
2020-03-09 19:39:36 +01:00
|
|
|
class SSLStreamAdapterTestDTLS
|
|
|
|
|
: public SSLStreamAdapterTestDTLSBase,
|
|
|
|
|
public WithParamInterface<tuple<rtc::KeyParams, rtc::KeyParams>> {
|
|
|
|
|
public:
|
|
|
|
|
SSLStreamAdapterTestDTLS()
|
|
|
|
|
: SSLStreamAdapterTestDTLSBase(::testing::get<0>(GetParam()),
|
|
|
|
|
::testing::get<1>(GetParam())) {}
|
|
|
|
|
|
2022-03-17 15:47:49 +01:00
|
|
|
SSLStreamAdapterTestDTLS(absl::string_view cert_pem,
|
|
|
|
|
absl::string_view private_key_pem)
|
2020-03-09 19:39:36 +01:00
|
|
|
: SSLStreamAdapterTestDTLSBase(cert_pem, private_key_pem) {}
|
|
|
|
|
};
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
rtc::StreamResult SSLDummyStreamBase::Write(const void* data,
|
|
|
|
|
size_t data_len,
|
|
|
|
|
size_t* written,
|
|
|
|
|
int* error) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_VERBOSE) << "Writing to loopback " << data_len;
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
if (first_packet_) {
|
|
|
|
|
first_packet_ = false;
|
2015-11-19 05:17:58 -08:00
|
|
|
if (test_base_->GetLoseFirstPacket()) {
|
2017-11-09 11:09:25 +01:00
|
|
|
RTC_LOG(LS_INFO) << "Losing initial packet of length " << data_len;
|
2015-11-19 12:20:51 -08:00
|
|
|
*written = data_len; // Fake successful writing also to writer.
|
2014-05-13 18:00:26 +00:00
|
|
|
return rtc::SR_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-19 05:17:58 -08:00
|
|
|
return test_base_->DataWritten(this, data, data_len, written, error);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
class SSLStreamAdapterTestDTLSFromPEMStrings : public SSLStreamAdapterTestDTLS {
|
|
|
|
|
public:
|
2018-06-19 15:03:05 +02:00
|
|
|
SSLStreamAdapterTestDTLSFromPEMStrings()
|
|
|
|
|
: SSLStreamAdapterTestDTLS(kCERT_PEM, kRSA_PRIVATE_KEY_PEM) {}
|
2014-05-13 18:00:26 +00:00
|
|
|
};
|
|
|
|
|
|
2017-11-16 16:58:02 -08:00
|
|
|
// Test fixture for certificate chaining. Server will push more than one
|
|
|
|
|
// certificate.
|
|
|
|
|
class SSLStreamAdapterTestDTLSCertChain : public SSLStreamAdapterTestDTLS {
|
|
|
|
|
public:
|
2019-02-25 09:12:02 +01:00
|
|
|
SSLStreamAdapterTestDTLSCertChain() : SSLStreamAdapterTestDTLS("", "") {}
|
2017-11-16 16:58:02 -08:00
|
|
|
void SetUp() override {
|
|
|
|
|
CreateStreams();
|
|
|
|
|
|
2020-03-20 22:51:32 +01:00
|
|
|
client_ssl_ =
|
|
|
|
|
rtc::SSLStreamAdapter::Create(absl::WrapUnique(client_stream_));
|
|
|
|
|
server_ssl_ =
|
|
|
|
|
rtc::SSLStreamAdapter::Create(absl::WrapUnique(server_stream_));
|
2017-11-16 16:58:02 -08:00
|
|
|
|
|
|
|
|
// Set up the slots
|
|
|
|
|
client_ssl_->SignalEvent.connect(
|
|
|
|
|
reinterpret_cast<SSLStreamAdapterTestBase*>(this),
|
|
|
|
|
&SSLStreamAdapterTestBase::OnEvent);
|
|
|
|
|
server_ssl_->SignalEvent.connect(
|
|
|
|
|
reinterpret_cast<SSLStreamAdapterTestBase*>(this),
|
|
|
|
|
&SSLStreamAdapterTestBase::OnEvent);
|
|
|
|
|
|
2020-03-20 22:51:32 +01:00
|
|
|
std::unique_ptr<rtc::SSLIdentity> client_identity;
|
2017-11-16 16:58:02 -08:00
|
|
|
if (!client_cert_pem_.empty() && !client_private_key_pem_.empty()) {
|
2020-03-20 22:51:32 +01:00
|
|
|
client_identity = rtc::SSLIdentity::CreateFromPEMStrings(
|
2017-11-16 16:58:02 -08:00
|
|
|
client_private_key_pem_, client_cert_pem_);
|
|
|
|
|
} else {
|
2020-03-20 22:51:32 +01:00
|
|
|
client_identity = rtc::SSLIdentity::Create("client", client_key_type_);
|
2017-11-16 16:58:02 -08:00
|
|
|
}
|
|
|
|
|
|
2020-03-20 22:51:32 +01:00
|
|
|
client_ssl_->SetIdentity(std::move(client_identity));
|
2017-11-16 16:58:02 -08:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
// Basic tests: TLS
|
|
|
|
|
|
|
|
|
|
// Test that we can make a handshake work
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestTLS, TestTLSConnect) {
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake();
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2017-11-16 16:58:02 -08:00
|
|
|
TEST_P(SSLStreamAdapterTestTLS, GetPeerCertChainWithOneCertificate) {
|
|
|
|
|
TestHandshake();
|
|
|
|
|
std::unique_ptr<rtc::SSLCertChain> cert_chain =
|
|
|
|
|
client_ssl_->GetPeerSSLCertChain();
|
|
|
|
|
ASSERT_NE(nullptr, cert_chain);
|
|
|
|
|
EXPECT_EQ(1u, cert_chain->GetSize());
|
2018-02-23 13:04:51 -08:00
|
|
|
EXPECT_EQ(cert_chain->Get(0).ToPEMString(),
|
2020-03-20 22:51:32 +01:00
|
|
|
server_identity()->certificate().ToPEMString());
|
2017-11-16 16:58:02 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(SSLStreamAdapterTestDTLSCertChain, TwoCertHandshake) {
|
2020-03-20 22:51:32 +01:00
|
|
|
auto server_identity = rtc::SSLIdentity::CreateFromPEMChainStrings(
|
2017-11-16 16:58:02 -08:00
|
|
|
kRSA_PRIVATE_KEY_PEM, std::string(kCERT_PEM) + kCACert);
|
2020-03-20 22:51:32 +01:00
|
|
|
server_ssl_->SetIdentity(std::move(server_identity));
|
2017-11-16 16:58:02 -08:00
|
|
|
TestHandshake();
|
|
|
|
|
std::unique_ptr<rtc::SSLCertChain> peer_cert_chain =
|
|
|
|
|
client_ssl_->GetPeerSSLCertChain();
|
|
|
|
|
ASSERT_NE(nullptr, peer_cert_chain);
|
|
|
|
|
ASSERT_EQ(2u, peer_cert_chain->GetSize());
|
|
|
|
|
EXPECT_EQ(kCERT_PEM, peer_cert_chain->Get(0).ToPEMString());
|
|
|
|
|
EXPECT_EQ(kCACert, peer_cert_chain->Get(1).ToPEMString());
|
|
|
|
|
}
|
|
|
|
|
|
2017-12-01 17:25:45 -05:00
|
|
|
TEST_F(SSLStreamAdapterTestDTLSCertChain, TwoCertHandshakeWithCopy) {
|
2020-03-20 22:51:32 +01:00
|
|
|
server_ssl_->SetIdentity(rtc::SSLIdentity::CreateFromPEMChainStrings(
|
|
|
|
|
kRSA_PRIVATE_KEY_PEM, std::string(kCERT_PEM) + kCACert));
|
2017-12-01 17:25:45 -05:00
|
|
|
TestHandshake();
|
|
|
|
|
std::unique_ptr<rtc::SSLCertChain> peer_cert_chain =
|
|
|
|
|
client_ssl_->GetPeerSSLCertChain();
|
|
|
|
|
ASSERT_NE(nullptr, peer_cert_chain);
|
|
|
|
|
ASSERT_EQ(2u, peer_cert_chain->GetSize());
|
|
|
|
|
EXPECT_EQ(kCERT_PEM, peer_cert_chain->Get(0).ToPEMString());
|
|
|
|
|
EXPECT_EQ(kCACert, peer_cert_chain->Get(1).ToPEMString());
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-16 16:58:02 -08:00
|
|
|
TEST_F(SSLStreamAdapterTestDTLSCertChain, ThreeCertHandshake) {
|
2020-03-20 22:51:32 +01:00
|
|
|
server_ssl_->SetIdentity(rtc::SSLIdentity::CreateFromPEMChainStrings(
|
|
|
|
|
kRSA_PRIVATE_KEY_PEM, std::string(kCERT_PEM) + kIntCert1 + kCACert));
|
2017-11-16 16:58:02 -08:00
|
|
|
TestHandshake();
|
|
|
|
|
std::unique_ptr<rtc::SSLCertChain> peer_cert_chain =
|
|
|
|
|
client_ssl_->GetPeerSSLCertChain();
|
|
|
|
|
ASSERT_NE(nullptr, peer_cert_chain);
|
|
|
|
|
ASSERT_EQ(3u, peer_cert_chain->GetSize());
|
|
|
|
|
EXPECT_EQ(kCERT_PEM, peer_cert_chain->Get(0).ToPEMString());
|
|
|
|
|
EXPECT_EQ(kIntCert1, peer_cert_chain->Get(1).ToPEMString());
|
|
|
|
|
EXPECT_EQ(kCACert, peer_cert_chain->Get(2).ToPEMString());
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-25 16:38:46 +00:00
|
|
|
// Test that closing the connection on one side updates the other side.
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestTLS, TestTLSClose) {
|
2014-09-25 16:38:46 +00:00
|
|
|
TestHandshake();
|
|
|
|
|
client_ssl_->Close();
|
|
|
|
|
EXPECT_EQ_WAIT(rtc::SS_CLOSED, server_ssl_->GetState(), handshake_wait_);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-09-25 16:38:46 +00:00
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
// Test transfer -- trivial
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestTLS, TestTLSTransfer) {
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake();
|
|
|
|
|
TestTransfer(100000);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Test read-write after close.
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestTLS, ReadWriteAfterClose) {
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake();
|
|
|
|
|
TestTransfer(100000);
|
|
|
|
|
client_ssl_->Close();
|
|
|
|
|
|
|
|
|
|
rtc::StreamResult rv;
|
|
|
|
|
char block[kBlockSize];
|
|
|
|
|
size_t dummy;
|
|
|
|
|
|
|
|
|
|
// It's an error to write after closed.
|
2017-02-27 14:06:41 -08:00
|
|
|
rv = client_ssl_->Write(block, sizeof(block), &dummy, nullptr);
|
2014-05-13 18:00:26 +00:00
|
|
|
ASSERT_EQ(rtc::SR_ERROR, rv);
|
|
|
|
|
|
|
|
|
|
// But after closed read gives you EOS.
|
2017-02-27 14:06:41 -08:00
|
|
|
rv = client_ssl_->Read(block, sizeof(block), &dummy, nullptr);
|
2014-05-13 18:00:26 +00:00
|
|
|
ASSERT_EQ(rtc::SR_EOS, rv);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Test a handshake with a bogus peer digest
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestTLS, TestTLSBogusDigest) {
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
SetPeerIdentitiesByDigest(false, true);
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake(false);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
TEST_P(SSLStreamAdapterTestTLS, TestTLSDelayedIdentity) {
|
|
|
|
|
TestHandshakeWithDelayedIdentity(true);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
|
|
|
|
|
TEST_P(SSLStreamAdapterTestTLS, TestTLSDelayedIdentityWithBogusDigest) {
|
|
|
|
|
TestHandshakeWithDelayedIdentity(false);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
|
|
|
|
|
// Test that the correct error is returned when SetPeerCertificateDigest is
|
|
|
|
|
// called with an unknown algorithm.
|
|
|
|
|
TEST_P(SSLStreamAdapterTestTLS,
|
|
|
|
|
TestSetPeerCertificateDigestWithUnknownAlgorithm) {
|
|
|
|
|
unsigned char server_digest[20];
|
|
|
|
|
size_t server_digest_len;
|
|
|
|
|
bool rv;
|
|
|
|
|
rtc::SSLPeerCertificateDigestError err;
|
|
|
|
|
|
2020-03-20 22:51:32 +01:00
|
|
|
rv = server_identity()->certificate().ComputeDigest(
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
rtc::DIGEST_SHA_1, server_digest, 20, &server_digest_len);
|
|
|
|
|
ASSERT_TRUE(rv);
|
|
|
|
|
|
|
|
|
|
rv = client_ssl_->SetPeerCertificateDigest("unknown algorithm", server_digest,
|
|
|
|
|
server_digest_len, &err);
|
|
|
|
|
EXPECT_EQ(rtc::SSLPeerCertificateDigestError::UNKNOWN_ALGORITHM, err);
|
|
|
|
|
EXPECT_FALSE(rv);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test that the correct error is returned when SetPeerCertificateDigest is
|
|
|
|
|
// called with an invalid digest length.
|
|
|
|
|
TEST_P(SSLStreamAdapterTestTLS, TestSetPeerCertificateDigestWithInvalidLength) {
|
|
|
|
|
unsigned char server_digest[20];
|
|
|
|
|
size_t server_digest_len;
|
|
|
|
|
bool rv;
|
|
|
|
|
rtc::SSLPeerCertificateDigestError err;
|
|
|
|
|
|
2020-03-20 22:51:32 +01:00
|
|
|
rv = server_identity()->certificate().ComputeDigest(
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
rtc::DIGEST_SHA_1, server_digest, 20, &server_digest_len);
|
|
|
|
|
ASSERT_TRUE(rv);
|
|
|
|
|
|
|
|
|
|
rv = client_ssl_->SetPeerCertificateDigest(rtc::DIGEST_SHA_1, server_digest,
|
|
|
|
|
server_digest_len - 1, &err);
|
|
|
|
|
EXPECT_EQ(rtc::SSLPeerCertificateDigestError::INVALID_LENGTH, err);
|
|
|
|
|
EXPECT_FALSE(rv);
|
|
|
|
|
}
|
|
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
// Test moving a bunch of data
|
|
|
|
|
|
|
|
|
|
// Basic tests: DTLS
|
|
|
|
|
// Test that we can make a handshake work
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnect) {
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake();
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Test that we can make a handshake work if the first packet in
|
|
|
|
|
// each direction is lost. This gives us predictable loss
|
|
|
|
|
// rather than having to tune random
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacket) {
|
2014-05-13 18:00:26 +00:00
|
|
|
SetLoseFirstPacket(true);
|
|
|
|
|
TestHandshake();
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Test a handshake with loss and delay
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSConnectWithLostFirstPacketDelay2s) {
|
2014-05-13 18:00:26 +00:00
|
|
|
SetLoseFirstPacket(true);
|
|
|
|
|
SetDelay(2000);
|
|
|
|
|
SetHandshakeWait(20000);
|
|
|
|
|
TestHandshake();
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Test a handshake with small MTU
|
2014-10-09 07:52:03 +00:00
|
|
|
// Disabled due to https://code.google.com/p/webrtc/issues/detail?id=3910
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, DISABLED_TestDTLSConnectWithSmallMtu) {
|
2014-05-13 18:00:26 +00:00
|
|
|
SetMtu(700);
|
|
|
|
|
SetHandshakeWait(20000);
|
|
|
|
|
TestHandshake();
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Test transfer -- trivial
|
2015-11-19 05:17:58 -08:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransfer) {
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake();
|
|
|
|
|
TestTransfer(100);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2015-11-19 05:17:58 -08:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithLoss) {
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake();
|
|
|
|
|
SetLoss(10);
|
|
|
|
|
TestTransfer(100);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2015-11-19 05:17:58 -08:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSTransferWithDamage) {
|
2014-05-13 18:00:26 +00:00
|
|
|
SetDamage(); // Must be called first because first packet
|
|
|
|
|
// write happens at end of handshake.
|
|
|
|
|
TestHandshake();
|
|
|
|
|
TestTransfer(100);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSDelayedIdentity) {
|
|
|
|
|
TestHandshakeWithDelayedIdentity(true);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
|
|
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSDelayedIdentityWithBogusDigest) {
|
|
|
|
|
TestHandshakeWithDelayedIdentity(false);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
Relanding: Allow the DTLS fingerprint verification to occur after the handshake.
This means the DTLS handshake can make progress while the SDP answer
containing the fingerprint is still in transit. If the signaling path
if significantly slower than the media path, this can have a moderate
impact on call setup time.
Of course, until the fingerprint is verified no media can be sent. Any
attempted write will result in SR_BLOCK.
This essentially fulfills the requirements of RFC 4572, Section 6.2:
Note that when the offer/answer model is being used, it is possible
for a media connection to outrace the answer back to the offerer.
Thus, if the offerer has offered a 'setup:passive' or 'setup:actpass'
role, it MUST (as specified in RFC 4145 [2]) begin listening for an
incoming connection as soon as it sends its offer. However, it MUST
NOT assume that the data transmitted over the TLS connection is valid
until it has received a matching fingerprint in an SDP answer. If
the fingerprint, once it arrives, does not match the client's
certificate, the server endpoint MUST terminate the media connection
with a bad_certificate error, as stated in the previous paragraph.
BUG=webrtc:6387
Review-Url: https://codereview.webrtc.org/2163683003
Cr-Commit-Position: refs/heads/master@{#14461}
2016-09-30 11:55:43 -07:00
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
// Test DTLS-SRTP with all high ciphers
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHigh) {
|
2015-11-18 19:41:53 -08:00
|
|
|
std::vector<int> high;
|
2021-07-26 17:27:42 +02:00
|
|
|
high.push_back(rtc::kSrtpAes128CmSha1_80);
|
2015-11-18 19:41:53 -08:00
|
|
|
SetDtlsSrtpCryptoSuites(high, true);
|
|
|
|
|
SetDtlsSrtpCryptoSuites(high, false);
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake();
|
|
|
|
|
|
2015-11-18 19:41:53 -08:00
|
|
|
int client_cipher;
|
|
|
|
|
ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
|
|
|
|
|
int server_cipher;
|
|
|
|
|
ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
ASSERT_EQ(client_cipher, server_cipher);
|
2021-07-26 17:27:42 +02:00
|
|
|
ASSERT_EQ(client_cipher, rtc::kSrtpAes128CmSha1_80);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Test DTLS-SRTP with all low ciphers
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpLow) {
|
2015-11-18 19:41:53 -08:00
|
|
|
std::vector<int> low;
|
2021-07-26 17:27:42 +02:00
|
|
|
low.push_back(rtc::kSrtpAes128CmSha1_32);
|
2015-11-18 19:41:53 -08:00
|
|
|
SetDtlsSrtpCryptoSuites(low, true);
|
|
|
|
|
SetDtlsSrtpCryptoSuites(low, false);
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake();
|
|
|
|
|
|
2015-11-18 19:41:53 -08:00
|
|
|
int client_cipher;
|
|
|
|
|
ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
|
|
|
|
|
int server_cipher;
|
|
|
|
|
ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
ASSERT_EQ(client_cipher, server_cipher);
|
2021-07-26 17:27:42 +02:00
|
|
|
ASSERT_EQ(client_cipher, rtc::kSrtpAes128CmSha1_32);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Test DTLS-SRTP with a mismatch -- should not converge
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpHighLow) {
|
2015-11-18 19:41:53 -08:00
|
|
|
std::vector<int> high;
|
2021-07-26 17:27:42 +02:00
|
|
|
high.push_back(rtc::kSrtpAes128CmSha1_80);
|
2015-11-18 19:41:53 -08:00
|
|
|
std::vector<int> low;
|
2021-07-26 17:27:42 +02:00
|
|
|
low.push_back(rtc::kSrtpAes128CmSha1_32);
|
2015-11-18 19:41:53 -08:00
|
|
|
SetDtlsSrtpCryptoSuites(high, true);
|
|
|
|
|
SetDtlsSrtpCryptoSuites(low, false);
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake();
|
|
|
|
|
|
2015-11-18 19:41:53 -08:00
|
|
|
int client_cipher;
|
|
|
|
|
ASSERT_FALSE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
|
|
|
|
|
int server_cipher;
|
|
|
|
|
ASSERT_FALSE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// Test DTLS-SRTP with each side being mixed -- should select high
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpMixed) {
|
2015-11-18 19:41:53 -08:00
|
|
|
std::vector<int> mixed;
|
2021-07-26 17:27:42 +02:00
|
|
|
mixed.push_back(rtc::kSrtpAes128CmSha1_80);
|
|
|
|
|
mixed.push_back(rtc::kSrtpAes128CmSha1_32);
|
2015-11-18 19:41:53 -08:00
|
|
|
SetDtlsSrtpCryptoSuites(mixed, true);
|
|
|
|
|
SetDtlsSrtpCryptoSuites(mixed, false);
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake();
|
|
|
|
|
|
2015-11-18 19:41:53 -08:00
|
|
|
int client_cipher;
|
|
|
|
|
ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
|
|
|
|
|
int server_cipher;
|
|
|
|
|
ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
ASSERT_EQ(client_cipher, server_cipher);
|
2021-07-26 17:27:42 +02:00
|
|
|
ASSERT_EQ(client_cipher, rtc::kSrtpAes128CmSha1_80);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2014-05-13 18:00:26 +00:00
|
|
|
|
2016-08-04 05:20:32 -07:00
|
|
|
// Test DTLS-SRTP with all GCM-128 ciphers.
|
|
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpGCM128) {
|
|
|
|
|
std::vector<int> gcm128;
|
2021-07-26 17:27:42 +02:00
|
|
|
gcm128.push_back(rtc::kSrtpAeadAes128Gcm);
|
2016-08-04 05:20:32 -07:00
|
|
|
SetDtlsSrtpCryptoSuites(gcm128, true);
|
|
|
|
|
SetDtlsSrtpCryptoSuites(gcm128, false);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
|
|
|
|
|
int client_cipher;
|
|
|
|
|
ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
|
|
|
|
|
int server_cipher;
|
|
|
|
|
ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(client_cipher, server_cipher);
|
2021-07-26 17:27:42 +02:00
|
|
|
ASSERT_EQ(client_cipher, rtc::kSrtpAeadAes128Gcm);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2016-08-04 05:20:32 -07:00
|
|
|
|
|
|
|
|
// Test DTLS-SRTP with all GCM-256 ciphers.
|
|
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpGCM256) {
|
|
|
|
|
std::vector<int> gcm256;
|
2021-07-26 17:27:42 +02:00
|
|
|
gcm256.push_back(rtc::kSrtpAeadAes256Gcm);
|
2016-08-04 05:20:32 -07:00
|
|
|
SetDtlsSrtpCryptoSuites(gcm256, true);
|
|
|
|
|
SetDtlsSrtpCryptoSuites(gcm256, false);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
|
|
|
|
|
int client_cipher;
|
|
|
|
|
ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
|
|
|
|
|
int server_cipher;
|
|
|
|
|
ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(client_cipher, server_cipher);
|
2021-07-26 17:27:42 +02:00
|
|
|
ASSERT_EQ(client_cipher, rtc::kSrtpAeadAes256Gcm);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2016-08-04 05:20:32 -07:00
|
|
|
|
|
|
|
|
// Test DTLS-SRTP with mixed GCM-128/-256 ciphers -- should not converge.
|
|
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpGCMMismatch) {
|
|
|
|
|
std::vector<int> gcm128;
|
2021-07-26 17:27:42 +02:00
|
|
|
gcm128.push_back(rtc::kSrtpAeadAes128Gcm);
|
2016-08-04 05:20:32 -07:00
|
|
|
std::vector<int> gcm256;
|
2021-07-26 17:27:42 +02:00
|
|
|
gcm256.push_back(rtc::kSrtpAeadAes256Gcm);
|
2016-08-04 05:20:32 -07:00
|
|
|
SetDtlsSrtpCryptoSuites(gcm128, true);
|
|
|
|
|
SetDtlsSrtpCryptoSuites(gcm256, false);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
|
|
|
|
|
int client_cipher;
|
|
|
|
|
ASSERT_FALSE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
|
|
|
|
|
int server_cipher;
|
|
|
|
|
ASSERT_FALSE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2016-08-04 05:20:32 -07:00
|
|
|
|
|
|
|
|
// Test DTLS-SRTP with both GCM-128/-256 ciphers -- should select GCM-256.
|
|
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpGCMMixed) {
|
|
|
|
|
std::vector<int> gcmBoth;
|
2021-07-26 17:27:42 +02:00
|
|
|
gcmBoth.push_back(rtc::kSrtpAeadAes256Gcm);
|
|
|
|
|
gcmBoth.push_back(rtc::kSrtpAeadAes128Gcm);
|
2016-08-04 05:20:32 -07:00
|
|
|
SetDtlsSrtpCryptoSuites(gcmBoth, true);
|
|
|
|
|
SetDtlsSrtpCryptoSuites(gcmBoth, false);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
|
|
|
|
|
int client_cipher;
|
|
|
|
|
ASSERT_TRUE(GetDtlsSrtpCryptoSuite(true, &client_cipher));
|
|
|
|
|
int server_cipher;
|
|
|
|
|
ASSERT_TRUE(GetDtlsSrtpCryptoSuite(false, &server_cipher));
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(client_cipher, server_cipher);
|
2021-07-26 17:27:42 +02:00
|
|
|
ASSERT_EQ(client_cipher, rtc::kSrtpAeadAes256Gcm);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2016-08-04 05:20:32 -07:00
|
|
|
|
|
|
|
|
// Test SRTP cipher suite lengths.
|
|
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSSrtpKeyAndSaltLengths) {
|
|
|
|
|
int key_len;
|
|
|
|
|
int salt_len;
|
|
|
|
|
|
2021-07-26 17:27:42 +02:00
|
|
|
ASSERT_FALSE(rtc::GetSrtpKeyAndSaltLengths(rtc::kSrtpInvalidCryptoSuite,
|
2018-06-19 15:03:05 +02:00
|
|
|
&key_len, &salt_len));
|
2016-08-04 05:20:32 -07:00
|
|
|
|
2021-07-26 17:27:42 +02:00
|
|
|
ASSERT_TRUE(rtc::GetSrtpKeyAndSaltLengths(rtc::kSrtpAes128CmSha1_32, &key_len,
|
|
|
|
|
&salt_len));
|
2018-06-19 15:03:05 +02:00
|
|
|
ASSERT_EQ(128 / 8, key_len);
|
|
|
|
|
ASSERT_EQ(112 / 8, salt_len);
|
2016-08-04 05:20:32 -07:00
|
|
|
|
2021-07-26 17:27:42 +02:00
|
|
|
ASSERT_TRUE(rtc::GetSrtpKeyAndSaltLengths(rtc::kSrtpAes128CmSha1_80, &key_len,
|
|
|
|
|
&salt_len));
|
2018-06-19 15:03:05 +02:00
|
|
|
ASSERT_EQ(128 / 8, key_len);
|
|
|
|
|
ASSERT_EQ(112 / 8, salt_len);
|
2016-08-04 05:20:32 -07:00
|
|
|
|
2021-07-26 17:27:42 +02:00
|
|
|
ASSERT_TRUE(rtc::GetSrtpKeyAndSaltLengths(rtc::kSrtpAeadAes128Gcm, &key_len,
|
|
|
|
|
&salt_len));
|
2018-06-19 15:03:05 +02:00
|
|
|
ASSERT_EQ(128 / 8, key_len);
|
|
|
|
|
ASSERT_EQ(96 / 8, salt_len);
|
2016-08-04 05:20:32 -07:00
|
|
|
|
2021-07-26 17:27:42 +02:00
|
|
|
ASSERT_TRUE(rtc::GetSrtpKeyAndSaltLengths(rtc::kSrtpAeadAes256Gcm, &key_len,
|
|
|
|
|
&salt_len));
|
2018-06-19 15:03:05 +02:00
|
|
|
ASSERT_EQ(256 / 8, key_len);
|
|
|
|
|
ASSERT_EQ(96 / 8, salt_len);
|
2019-02-25 09:12:02 +01:00
|
|
|
}
|
2016-08-04 05:20:32 -07:00
|
|
|
|
2014-05-13 18:00:26 +00:00
|
|
|
// Test an exporter
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestDTLSExporter) {
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake();
|
|
|
|
|
unsigned char client_out[20];
|
|
|
|
|
unsigned char server_out[20];
|
|
|
|
|
|
|
|
|
|
bool result;
|
2018-06-19 15:03:05 +02:00
|
|
|
result = ExportKeyingMaterial(kExporterLabel, kExporterContext,
|
|
|
|
|
kExporterContextLen, true, true, client_out,
|
|
|
|
|
sizeof(client_out));
|
2014-05-13 18:00:26 +00:00
|
|
|
ASSERT_TRUE(result);
|
|
|
|
|
|
2018-06-19 15:03:05 +02:00
|
|
|
result = ExportKeyingMaterial(kExporterLabel, kExporterContext,
|
|
|
|
|
kExporterContextLen, true, false, server_out,
|
|
|
|
|
sizeof(server_out));
|
2014-05-13 18:00:26 +00:00
|
|
|
ASSERT_TRUE(result);
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(!memcmp(client_out, server_out, sizeof(client_out)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test not yet valid certificates are not rejected.
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestCertNotYetValid) {
|
2014-05-13 18:00:26 +00:00
|
|
|
long one_day = 60 * 60 * 24;
|
|
|
|
|
// Make the certificates not valid until one day later.
|
|
|
|
|
ResetIdentitiesWithValidity(one_day, one_day);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test expired certificates are not rejected.
|
2015-08-17 14:08:59 +02:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestCertExpired) {
|
2014-05-13 18:00:26 +00:00
|
|
|
long one_day = 60 * 60 * 24;
|
|
|
|
|
// Make the certificates already expired.
|
|
|
|
|
ResetIdentitiesWithValidity(-one_day, -one_day);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test data transfer using certs created from strings.
|
2015-11-19 12:20:51 -08:00
|
|
|
TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestTransfer) {
|
2014-05-13 18:00:26 +00:00
|
|
|
TestHandshake();
|
|
|
|
|
TestTransfer(100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test getting the remote certificate.
|
2015-11-19 12:20:51 -08:00
|
|
|
TEST_F(SSLStreamAdapterTestDTLSFromPEMStrings, TestDTLSGetPeerCertificate) {
|
2014-05-13 18:00:26 +00:00
|
|
|
// Peer certificates haven't been received yet.
|
2016-04-06 05:15:06 -07:00
|
|
|
ASSERT_FALSE(GetPeerCertificate(true));
|
|
|
|
|
ASSERT_FALSE(GetPeerCertificate(false));
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
TestHandshake();
|
|
|
|
|
|
|
|
|
|
// The client should have a peer certificate after the handshake.
|
2016-04-26 03:13:22 -07:00
|
|
|
std::unique_ptr<rtc::SSLCertificate> client_peer_cert =
|
2016-04-06 05:15:06 -07:00
|
|
|
GetPeerCertificate(true);
|
|
|
|
|
ASSERT_TRUE(client_peer_cert);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// It's not kCERT_PEM.
|
|
|
|
|
std::string client_peer_string = client_peer_cert->ToPEMString();
|
|
|
|
|
ASSERT_NE(kCERT_PEM, client_peer_string);
|
|
|
|
|
|
|
|
|
|
// The server should have a peer certificate after the handshake.
|
2016-04-26 03:13:22 -07:00
|
|
|
std::unique_ptr<rtc::SSLCertificate> server_peer_cert =
|
2016-04-06 05:15:06 -07:00
|
|
|
GetPeerCertificate(false);
|
|
|
|
|
ASSERT_TRUE(server_peer_cert);
|
2014-05-13 18:00:26 +00:00
|
|
|
|
|
|
|
|
// It's kCERT_PEM
|
|
|
|
|
ASSERT_EQ(kCERT_PEM, server_peer_cert->ToPEMString());
|
|
|
|
|
}
|
2015-02-11 22:34:36 +00:00
|
|
|
|
2020-03-09 19:39:36 +01:00
|
|
|
// Test getting the used DTLS 1.2 ciphers.
|
|
|
|
|
// DTLS 1.2 enabled for client and server -> DTLS 1.2 will be used.
|
|
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuiteDtls12Both) {
|
|
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_12);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
|
|
|
|
|
int client_cipher;
|
|
|
|
|
ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
|
|
|
|
|
int server_cipher;
|
|
|
|
|
ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_12, GetSslVersion(true));
|
|
|
|
|
ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_12, GetSslVersion(false));
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(client_cipher, server_cipher);
|
|
|
|
|
ASSERT_TRUE(rtc::SSLStreamAdapter::IsAcceptableCipher(
|
|
|
|
|
server_cipher, ::testing::get<1>(GetParam()).type()));
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-11 22:34:36 +00:00
|
|
|
// Test getting the used DTLS ciphers.
|
2020-10-26 09:55:26 +01:00
|
|
|
// DTLS 1.2 is max version for client and server.
|
2019-04-01 18:25:23 +00:00
|
|
|
TEST_P(SSLStreamAdapterTestDTLS, TestGetSslCipherSuite) {
|
2020-10-26 09:55:26 +01:00
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_12);
|
2015-05-20 12:48:41 +02:00
|
|
|
TestHandshake();
|
|
|
|
|
|
2015-10-05 12:43:27 -07:00
|
|
|
int client_cipher;
|
2015-09-30 21:48:54 -07:00
|
|
|
ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
|
2015-10-05 12:43:27 -07:00
|
|
|
int server_cipher;
|
2015-09-30 21:48:54 -07:00
|
|
|
ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
|
2015-05-20 12:48:41 +02:00
|
|
|
|
2020-10-26 09:55:26 +01:00
|
|
|
ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_12, GetSslVersion(true));
|
|
|
|
|
ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_12, GetSslVersion(false));
|
2016-03-11 00:06:47 -08:00
|
|
|
|
2015-05-20 12:48:41 +02:00
|
|
|
ASSERT_EQ(client_cipher, server_cipher);
|
2016-03-11 00:06:47 -08:00
|
|
|
ASSERT_TRUE(rtc::SSLStreamAdapter::IsAcceptableCipher(
|
|
|
|
|
server_cipher, ::testing::get<1>(GetParam()).type()));
|
2015-05-20 12:48:41 +02:00
|
|
|
}
|
|
|
|
|
|
2020-03-09 19:39:36 +01:00
|
|
|
// The RSA keysizes here might look strange, why not include the RFC's size
|
|
|
|
|
// 2048?. The reason is test case slowness; testing two sizes to exercise
|
|
|
|
|
// parametrization is sufficient.
|
|
|
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
|
|
|
SSLStreamAdapterTestsTLS,
|
|
|
|
|
SSLStreamAdapterTestTLS,
|
|
|
|
|
Combine(Values(rtc::KeyParams::RSA(1024, 65537),
|
|
|
|
|
rtc::KeyParams::RSA(1152, 65537),
|
|
|
|
|
rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)),
|
|
|
|
|
Values(rtc::KeyParams::RSA(1024, 65537),
|
|
|
|
|
rtc::KeyParams::RSA(1152, 65537),
|
|
|
|
|
rtc::KeyParams::ECDSA(rtc::EC_NIST_P256))));
|
|
|
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
|
|
|
SSLStreamAdapterTestsDTLS,
|
|
|
|
|
SSLStreamAdapterTestDTLS,
|
|
|
|
|
Combine(Values(rtc::KeyParams::RSA(1024, 65537),
|
|
|
|
|
rtc::KeyParams::RSA(1152, 65537),
|
|
|
|
|
rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)),
|
|
|
|
|
Values(rtc::KeyParams::RSA(1024, 65537),
|
|
|
|
|
rtc::KeyParams::RSA(1152, 65537),
|
|
|
|
|
rtc::KeyParams::ECDSA(rtc::EC_NIST_P256))));
|
|
|
|
|
|
|
|
|
|
// Tests for enabling / disabling legacy TLS protocols in DTLS.
|
|
|
|
|
class SSLStreamAdapterTestDTLSLegacyProtocols
|
|
|
|
|
: public SSLStreamAdapterTestDTLSBase {
|
|
|
|
|
public:
|
|
|
|
|
SSLStreamAdapterTestDTLSLegacyProtocols()
|
|
|
|
|
: SSLStreamAdapterTestDTLSBase(rtc::KeyParams::ECDSA(rtc::EC_NIST_P256),
|
|
|
|
|
rtc::KeyParams::ECDSA(rtc::EC_NIST_P256)) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Do not use the SetUp version from the parent class.
|
|
|
|
|
void SetUp() override {}
|
|
|
|
|
|
|
|
|
|
// The legacy TLS protocols flag is read when the OpenSSLStreamAdapter is
|
|
|
|
|
// initialized, so we set the experiment while creationg client_ssl_
|
|
|
|
|
// and server_ssl_.
|
|
|
|
|
|
2022-03-17 15:47:49 +01:00
|
|
|
void ConfigureClient(absl::string_view experiment) {
|
|
|
|
|
webrtc::test::ScopedFieldTrials trial{std::string(experiment)};
|
2020-03-09 19:39:36 +01:00
|
|
|
client_stream_ =
|
|
|
|
|
new SSLDummyStreamDTLS(this, "c2s", &client_buffer_, &server_buffer_);
|
2020-03-20 22:51:32 +01:00
|
|
|
client_ssl_ =
|
|
|
|
|
rtc::SSLStreamAdapter::Create(absl::WrapUnique(client_stream_));
|
2020-03-09 19:39:36 +01:00
|
|
|
client_ssl_->SignalEvent.connect(
|
|
|
|
|
static_cast<SSLStreamAdapterTestBase*>(this),
|
|
|
|
|
&SSLStreamAdapterTestBase::OnEvent);
|
2020-03-20 22:51:32 +01:00
|
|
|
auto client_identity = rtc::SSLIdentity::Create("client", client_key_type_);
|
|
|
|
|
client_ssl_->SetIdentity(std::move(client_identity));
|
2020-03-09 19:39:36 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-17 15:47:49 +01:00
|
|
|
void ConfigureServer(absl::string_view experiment) {
|
|
|
|
|
webrtc::test::ScopedFieldTrials trial{std::string(experiment)};
|
2020-03-09 19:39:36 +01:00
|
|
|
server_stream_ =
|
|
|
|
|
new SSLDummyStreamDTLS(this, "s2c", &server_buffer_, &client_buffer_);
|
2020-03-20 22:51:32 +01:00
|
|
|
server_ssl_ =
|
|
|
|
|
rtc::SSLStreamAdapter::Create(absl::WrapUnique(server_stream_));
|
2020-03-09 19:39:36 +01:00
|
|
|
server_ssl_->SignalEvent.connect(
|
|
|
|
|
static_cast<SSLStreamAdapterTestBase*>(this),
|
|
|
|
|
&SSLStreamAdapterTestBase::OnEvent);
|
2020-03-20 22:51:32 +01:00
|
|
|
server_ssl_->SetIdentity(
|
|
|
|
|
rtc::SSLIdentity::Create("server", server_key_type_));
|
2020-03-09 19:39:36 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Test getting the used DTLS ciphers.
|
|
|
|
|
// DTLS 1.2 enabled for neither client nor server -> DTLS 1.0 will be used.
|
|
|
|
|
TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols, TestGetSslCipherSuite) {
|
2020-10-26 09:55:26 +01:00
|
|
|
ConfigureClient("WebRTC-LegacyTlsProtocols/Enabled/");
|
|
|
|
|
ConfigureServer("WebRTC-LegacyTlsProtocols/Enabled/");
|
2020-03-09 19:39:36 +01:00
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
|
|
|
|
|
int client_cipher;
|
|
|
|
|
ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
|
|
|
|
|
int server_cipher;
|
|
|
|
|
ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(true));
|
|
|
|
|
ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(false));
|
|
|
|
|
|
|
|
|
|
ASSERT_EQ(client_cipher, server_cipher);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-20 12:48:41 +02:00
|
|
|
// Test getting the used DTLS 1.2 ciphers.
|
|
|
|
|
// DTLS 1.2 enabled for client and server -> DTLS 1.2 will be used.
|
2020-03-09 19:39:36 +01:00
|
|
|
TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols,
|
|
|
|
|
TestGetSslCipherSuiteDtls12Both) {
|
|
|
|
|
ConfigureClient("");
|
|
|
|
|
ConfigureServer("");
|
2015-05-20 12:48:41 +02:00
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_12);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
|
2015-10-05 12:43:27 -07:00
|
|
|
int client_cipher;
|
2015-09-30 21:48:54 -07:00
|
|
|
ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
|
2015-10-05 12:43:27 -07:00
|
|
|
int server_cipher;
|
2015-09-30 21:48:54 -07:00
|
|
|
ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
|
2015-05-20 12:48:41 +02:00
|
|
|
|
2016-03-11 00:06:47 -08:00
|
|
|
ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_12, GetSslVersion(true));
|
|
|
|
|
ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_12, GetSslVersion(false));
|
|
|
|
|
|
2015-05-20 12:48:41 +02:00
|
|
|
ASSERT_EQ(client_cipher, server_cipher);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DTLS 1.2 enabled for client only -> DTLS 1.0 will be used.
|
2020-03-09 19:39:36 +01:00
|
|
|
TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols,
|
|
|
|
|
TestGetSslCipherSuiteDtls12Client) {
|
2020-10-26 09:55:26 +01:00
|
|
|
ConfigureClient("WebRTC-LegacyTlsProtocols/Enabled/");
|
|
|
|
|
ConfigureServer("WebRTC-LegacyTlsProtocols/Enabled/");
|
2015-05-20 12:48:41 +02:00
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_12);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
|
2015-10-05 12:43:27 -07:00
|
|
|
int client_cipher;
|
2015-09-30 21:48:54 -07:00
|
|
|
ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
|
2015-10-05 12:43:27 -07:00
|
|
|
int server_cipher;
|
2015-09-30 21:48:54 -07:00
|
|
|
ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
|
2015-05-20 12:48:41 +02:00
|
|
|
|
2016-03-11 00:06:47 -08:00
|
|
|
ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(true));
|
|
|
|
|
ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(false));
|
|
|
|
|
|
2015-05-20 12:48:41 +02:00
|
|
|
ASSERT_EQ(client_cipher, server_cipher);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DTLS 1.2 enabled for server only -> DTLS 1.0 will be used.
|
2020-03-09 19:39:36 +01:00
|
|
|
TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols,
|
|
|
|
|
TestGetSslCipherSuiteDtls12Server) {
|
2020-10-26 09:55:26 +01:00
|
|
|
ConfigureClient("WebRTC-LegacyTlsProtocols/Enabled/");
|
|
|
|
|
ConfigureServer("WebRTC-LegacyTlsProtocols/Enabled/");
|
2015-05-20 12:48:41 +02:00
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_10);
|
2015-02-11 22:34:36 +00:00
|
|
|
TestHandshake();
|
|
|
|
|
|
2015-10-05 12:43:27 -07:00
|
|
|
int client_cipher;
|
2015-09-30 21:48:54 -07:00
|
|
|
ASSERT_TRUE(GetSslCipherSuite(true, &client_cipher));
|
2015-10-05 12:43:27 -07:00
|
|
|
int server_cipher;
|
2015-09-30 21:48:54 -07:00
|
|
|
ASSERT_TRUE(GetSslCipherSuite(false, &server_cipher));
|
2015-02-11 22:34:36 +00:00
|
|
|
|
2016-03-11 00:06:47 -08:00
|
|
|
ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(true));
|
|
|
|
|
ASSERT_EQ(rtc::SSL_PROTOCOL_DTLS_10, GetSslVersion(false));
|
|
|
|
|
|
2015-02-11 22:34:36 +00:00
|
|
|
ASSERT_EQ(client_cipher, server_cipher);
|
|
|
|
|
}
|
2015-08-17 14:08:59 +02:00
|
|
|
|
2020-03-09 19:39:36 +01:00
|
|
|
// Client has legacy TLS versions disabled, server has DTLS 1.0 only.
|
|
|
|
|
// This is meant to cause a failure.
|
|
|
|
|
TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols,
|
|
|
|
|
TestGetSslVersionLegacyDisabledServer10) {
|
2020-10-26 09:55:26 +01:00
|
|
|
ConfigureClient("");
|
|
|
|
|
ConfigureServer("WebRTC-LegacyTlsProtocols/Enabled/");
|
2020-03-09 19:39:36 +01:00
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_12);
|
|
|
|
|
// Handshake should fail.
|
|
|
|
|
TestHandshake(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Both client and server have legacy TLS versions disabled and support
|
|
|
|
|
// DTLS 1.2. This should work.
|
|
|
|
|
TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols,
|
|
|
|
|
TestGetSslVersionLegacyDisabledServer12) {
|
2020-10-26 09:55:26 +01:00
|
|
|
ConfigureClient("");
|
|
|
|
|
ConfigureServer("");
|
2020-03-09 19:39:36 +01:00
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_12, rtc::SSL_PROTOCOL_DTLS_12);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Both client and server have legacy TLS versions enabled and support DTLS 1.0.
|
|
|
|
|
// This should work.
|
|
|
|
|
TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols,
|
|
|
|
|
TestGetSslVersionLegacyEnabledClient10Server10) {
|
|
|
|
|
ConfigureClient("WebRTC-LegacyTlsProtocols/Enabled/");
|
|
|
|
|
ConfigureServer("WebRTC-LegacyTlsProtocols/Enabled/");
|
|
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-26 09:55:26 +01:00
|
|
|
// Legacy protocols are disabled in the client, max TLS version is 1.0
|
2020-03-09 19:39:36 +01:00
|
|
|
// This should be a configuration error, and handshake should fail.
|
|
|
|
|
TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols,
|
|
|
|
|
TestGetSslVersionLegacyDisabledClient10Server10) {
|
2020-10-26 09:55:26 +01:00
|
|
|
ConfigureClient("");
|
|
|
|
|
ConfigureServer("WebRTC-LegacyTlsProtocols/Enabled/");
|
2020-03-09 19:39:36 +01:00
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10);
|
|
|
|
|
TestHandshake(false);
|
|
|
|
|
}
|
2020-09-25 16:00:51 +02:00
|
|
|
|
|
|
|
|
// Both client and server have legacy TLS versions enabled and support DTLS 1.0.
|
|
|
|
|
// This should work.
|
|
|
|
|
TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols,
|
|
|
|
|
TestGetSslVersionLegacyOverrideEnabledClient10Server10) {
|
|
|
|
|
rtc::SetAllowLegacyTLSProtocols(true);
|
|
|
|
|
ConfigureClient("");
|
|
|
|
|
ConfigureServer("");
|
|
|
|
|
// Remove override.
|
|
|
|
|
rtc::SetAllowLegacyTLSProtocols(absl::nullopt);
|
|
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10);
|
|
|
|
|
TestHandshake();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Client has legacy TLS disabled and server has legacy TLS enabled via
|
|
|
|
|
// override. Handshake for DTLS 1.0 should fail.
|
|
|
|
|
TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols,
|
|
|
|
|
TestGetSslVersionLegacyOverrideDisabledClient10EnabledServer10) {
|
|
|
|
|
rtc::SetAllowLegacyTLSProtocols(false);
|
|
|
|
|
ConfigureClient("");
|
|
|
|
|
rtc::SetAllowLegacyTLSProtocols(true);
|
|
|
|
|
ConfigureServer("");
|
|
|
|
|
// Remove override.
|
|
|
|
|
rtc::SetAllowLegacyTLSProtocols(absl::nullopt);
|
|
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10);
|
|
|
|
|
TestHandshake(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Client has legacy TLS enabled and server has legacy TLS disabled via
|
|
|
|
|
// override. Handshake for DTLS 1.0 should fail.
|
|
|
|
|
TEST_F(SSLStreamAdapterTestDTLSLegacyProtocols,
|
|
|
|
|
TestGetSslVersionLegacyOverrideEnabledClient10DisabledServer10) {
|
|
|
|
|
rtc::SetAllowLegacyTLSProtocols(true);
|
|
|
|
|
ConfigureClient("");
|
|
|
|
|
rtc::SetAllowLegacyTLSProtocols(false);
|
|
|
|
|
ConfigureServer("");
|
|
|
|
|
// Remove override.
|
|
|
|
|
rtc::SetAllowLegacyTLSProtocols(absl::nullopt);
|
|
|
|
|
SetupProtocolVersions(rtc::SSL_PROTOCOL_DTLS_10, rtc::SSL_PROTOCOL_DTLS_10);
|
|
|
|
|
TestHandshake(false);
|
|
|
|
|
}
|