-
Notifications
You must be signed in to change notification settings - Fork 154
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
End to end tests are now executed in the folowing modes: - pion client + pion server - openssl client + pion server - pion client + openssl server OpenSSL is launched using `exec.Command` and therefore `openssl` command must be available before running these tests. Tests are enabled via `openssl` tag.
- Loading branch information
1 parent
b2bba83
commit e950e1f
Showing
7 changed files
with
423 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
name: E2E | ||
on: | ||
pull_request: | ||
branches: | ||
- master | ||
push: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
e2e-test: | ||
name: Test | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: checkout | ||
uses: actions/checkout@v2 | ||
- name: test | ||
run: | | ||
docker build -t pion-dtls-e2e -f e2e/Dockerfile . | ||
docker run -i --rm pion-dtls-e2e |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
FROM golang:1.13-alpine3.11 | ||
|
||
RUN apk add --no-cache \ | ||
openssl | ||
|
||
ENV CGO_ENABLED=0 | ||
|
||
COPY . /go/src/github.com/pion/dtls | ||
WORKDIR /go/src/github.com/pion/dtls/e2e | ||
|
||
CMD ["go", "test", "-tags=openssl", "-v", "."] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,246 @@ | ||
// +build openssl,!js | ||
|
||
package e2e | ||
|
||
import ( | ||
"crypto/x509" | ||
"encoding/pem" | ||
"errors" | ||
"fmt" | ||
"io/ioutil" | ||
"net" | ||
"os" | ||
"os/exec" | ||
"strings" | ||
"testing" | ||
"time" | ||
|
||
"github.com/pion/dtls/v2" | ||
) | ||
|
||
func serverOpenSSL(c *comm) { | ||
go func() { | ||
c.serverMutex.Lock() | ||
defer c.serverMutex.Unlock() | ||
|
||
cfg := c.serverConfig | ||
|
||
// create openssl arguments | ||
args := []string{"s_server", | ||
"-dtls1_2", | ||
"-quiet", | ||
"-verify_quiet", | ||
"-verify_return_error", | ||
fmt.Sprintf("-accept=%d", c.serverPort), | ||
} | ||
ciphers := ciphersOpenSSL(cfg) | ||
if ciphers != "" { | ||
args = append(args, fmt.Sprintf("-cipher=%s", ciphers)) | ||
} | ||
|
||
// psk arguments | ||
if cfg.PSK != nil { | ||
psk, err := cfg.PSK(nil) | ||
if err != nil { | ||
c.errChan <- err | ||
return | ||
} | ||
args = append(args, fmt.Sprintf("-psk=%X", psk)) | ||
if len(cfg.PSKIdentityHint) > 0 { | ||
args = append(args, fmt.Sprintf("-psk_hint=%s", cfg.PSKIdentityHint)) | ||
} | ||
} | ||
|
||
// certs arguments | ||
if len(cfg.Certificates) > 0 { | ||
// create temporary cert files | ||
certPEM, keyPEM, err := writeTempPEM(cfg) | ||
if err != nil { | ||
c.errChan <- err | ||
return | ||
} | ||
args = append(args, | ||
fmt.Sprintf("-cert=%s", certPEM), | ||
fmt.Sprintf("-key=%s", keyPEM)) | ||
defer func() { | ||
_ = os.Remove(certPEM) | ||
_ = os.Remove(keyPEM) | ||
}() | ||
} else { | ||
args = append(args, "-nocert") | ||
} | ||
|
||
// launch command | ||
// #nosec G204 | ||
cmd := exec.CommandContext(c.ctx, "openssl", args...) | ||
var inner net.Conn | ||
inner, c.serverConn = net.Pipe() | ||
cmd.Stdin = inner | ||
cmd.Stdout = inner | ||
cmd.Stderr = os.Stderr | ||
if err := cmd.Start(); err != nil { | ||
c.errChan <- err | ||
_ = inner.Close() | ||
return | ||
} | ||
|
||
// Ensure that server has started | ||
time.Sleep(500 * time.Millisecond) | ||
|
||
c.serverReady <- struct{}{} | ||
simpleReadWrite(c.errChan, c.serverChan, c.serverConn, c.messageRecvCount) | ||
}() | ||
} | ||
|
||
func clientOpenSSL(c *comm) { | ||
select { | ||
case <-c.serverReady: | ||
// OK | ||
case <-time.After(time.Second): | ||
c.errChan <- errors.New("waiting on serverReady err: timeout") | ||
} | ||
|
||
c.clientMutex.Lock() | ||
defer c.clientMutex.Unlock() | ||
|
||
cfg := c.clientConfig | ||
|
||
// create openssl arguments | ||
args := []string{"s_client", | ||
"-dtls1_2", | ||
"-quiet", | ||
"-verify_quiet", | ||
"-verify_return_error", | ||
"-servername=localhost", | ||
fmt.Sprintf("-connect=127.0.0.1:%d", c.serverPort), | ||
} | ||
ciphers := ciphersOpenSSL(cfg) | ||
if ciphers != "" { | ||
args = append(args, fmt.Sprintf("-cipher=%s", ciphers)) | ||
} | ||
|
||
// psk arguments | ||
if cfg.PSK != nil { | ||
psk, err := cfg.PSK(nil) | ||
if err != nil { | ||
c.errChan <- err | ||
return | ||
} | ||
args = append(args, fmt.Sprintf("-psk=%X", psk)) | ||
} | ||
|
||
// certificate arguments | ||
if len(cfg.Certificates) > 0 { | ||
// create temporary cert files | ||
certPEM, keyPEM, err := writeTempPEM(cfg) | ||
if err != nil { | ||
c.errChan <- err | ||
return | ||
} | ||
args = append(args, fmt.Sprintf("-CAfile=%s", certPEM)) | ||
defer func() { | ||
_ = os.Remove(certPEM) | ||
_ = os.Remove(keyPEM) | ||
}() | ||
} | ||
|
||
// launch command | ||
// #nosec G204 | ||
cmd := exec.CommandContext(c.ctx, "openssl", args...) | ||
var inner net.Conn | ||
inner, c.clientConn = net.Pipe() | ||
cmd.Stdin = inner | ||
cmd.Stdout = inner | ||
cmd.Stderr = os.Stderr | ||
if err := cmd.Start(); err != nil { | ||
c.errChan <- err | ||
_ = inner.Close() | ||
return | ||
} | ||
|
||
simpleReadWrite(c.errChan, c.clientChan, c.clientConn, c.messageRecvCount) | ||
} | ||
|
||
func ciphersOpenSSL(cfg *dtls.Config) string { | ||
// See https://tls.mbed.org/supported-ssl-ciphersuites | ||
translate := map[dtls.CipherSuiteID]string{ | ||
dtls.TLS_ECDHE_ECDSA_WITH_AES_128_CCM: "ECDHE-ECDSA-AES128-CCM", | ||
dtls.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: "ECDHE-ECDSA-AES128-CCM8", | ||
dtls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "ECDHE-ECDSA-AES128-GCM-SHA256", | ||
dtls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: "ECDHE-RSA-AES128-GCM-SHA256", | ||
|
||
dtls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: "ECDHE-ECDSA-AES256-SHA", | ||
dtls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: "ECDHE-RSA-AES128-SHA", | ||
|
||
dtls.TLS_PSK_WITH_AES_128_CCM: "PSK-AES128-CCM", | ||
dtls.TLS_PSK_WITH_AES_128_CCM_8: "PSK-AES128-CCM8", | ||
dtls.TLS_PSK_WITH_AES_128_GCM_SHA256: "PSK-AES128-GCM-SHA256", | ||
} | ||
|
||
var ciphers []string | ||
for _, c := range cfg.CipherSuites { | ||
if text, ok := translate[c]; ok { | ||
ciphers = append(ciphers, text) | ||
} | ||
} | ||
return strings.Join(ciphers, ";") | ||
} | ||
|
||
func writeTempPEM(cfg *dtls.Config) (string, string, error) { | ||
certOut, err := ioutil.TempFile("", "cert.pem") | ||
if err != nil { | ||
return "", "", fmt.Errorf("failed to create temporary file: %w", err) | ||
} | ||
keyOut, err := ioutil.TempFile("", "key.pem") | ||
if err != nil { | ||
return "", "", fmt.Errorf("failed to create temporary file: %w", err) | ||
} | ||
|
||
cert := cfg.Certificates[0] | ||
derBytes := cert.Certificate[0] | ||
if err = pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { | ||
return "", "", fmt.Errorf("failed to write data to cert.pem: %w", err) | ||
} | ||
if err = certOut.Close(); err != nil { | ||
return "", "", fmt.Errorf("error closing cert.pem: %w", err) | ||
} | ||
|
||
priv := cert.PrivateKey | ||
var privBytes []byte | ||
privBytes, err = x509.MarshalPKCS8PrivateKey(priv) | ||
if err != nil { | ||
return "", "", fmt.Errorf("unable to marshal private key: %w", err) | ||
} | ||
if err = pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil { | ||
return "", "", fmt.Errorf("failed to write data to key.pem: %w", err) | ||
} | ||
if err = keyOut.Close(); err != nil { | ||
return "", "", fmt.Errorf("error closing key.pem: %w", err) | ||
} | ||
return certOut.Name(), keyOut.Name(), nil | ||
} | ||
|
||
func TestPionOpenSSLE2ESimple(t *testing.T) { | ||
t.Run("OpenSSLServer", func(t *testing.T) { | ||
testPionE2ESimple(t, serverOpenSSL, clientPion) | ||
}) | ||
t.Run("OpenSSLClient", func(t *testing.T) { | ||
testPionE2ESimple(t, serverPion, clientOpenSSL) | ||
}) | ||
} | ||
func TestPionOpenSSLE2ESimplePSK(t *testing.T) { | ||
t.Run("OpenSSLServer", func(t *testing.T) { | ||
testPionE2ESimplePSK(t, serverOpenSSL, clientPion) | ||
}) | ||
t.Run("OpenSSLClient", func(t *testing.T) { | ||
testPionE2ESimplePSK(t, serverPion, clientOpenSSL) | ||
}) | ||
} | ||
func TestPionOpenSSLE2EMTUs(t *testing.T) { | ||
t.Run("OpenSSLServer", func(t *testing.T) { | ||
testPionE2EMTUs(t, serverOpenSSL, clientPion) | ||
}) | ||
t.Run("OpenSSLClient", func(t *testing.T) { | ||
testPionE2EMTUs(t, serverPion, clientOpenSSL) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// +build openssl,go1.13,!js | ||
|
||
package e2e | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestPionOpenSSLE2ESimpleED25519(t *testing.T) { | ||
t.Skip("TODO: make ED25519 test work with openssl") | ||
t.Run("OpenSSLServer", func(t *testing.T) { | ||
testPionE2ESimpleED25519(t, serverOpenSSL, clientPion) | ||
}) | ||
t.Run("OpenSSLClient", func(t *testing.T) { | ||
testPionE2ESimpleED25519(t, serverPion, clientOpenSSL) | ||
}) | ||
} |
Oops, something went wrong.