From 2614cfd34fb8f31733f73f0587ae9d8c6de2bbc3 Mon Sep 17 00:00:00 2001 From: mohamedasifs123 Date: Thu, 16 Jan 2025 21:53:45 +0530 Subject: [PATCH] feat: adding unit tests for ipsec feat: adding unit tests for ipsec Signed-off-by: mohamedasifs123 feat: adding unit tests for ipsec Signed-off-by: mohamedasifs123 Update go.yml feat: adding unit tests for ipsec Signed-off-by: mohamedasifs123 --- .github/workflows/go.yml | 52 +- pkg/ipsec/ipsec_vici_test.go | 952 +++++++++++++++++++++++++++++++ tests/client/eap-tls.conf | 24 + tests/client/eap.conf | 24 + tests/client/ecdsa/clientKey.pem | 6 + tests/client/home.conf | 29 + tests/client/psk.conf | 25 + tests/client/swanctl.conf | 19 + tests/client/x509/clientCert.pem | 13 + tests/client/x509ca/caCert.pem | 13 + tests/docker-compose.yml | 67 +++ tests/server/eap.conf | 24 + tests/server/ecdsa/serverKey.pem | 6 + tests/server/psk.conf | 22 + tests/server/rw.conf | 28 + tests/server/swanctl.conf | 33 ++ tests/server/x509/serverCert.pem | 13 + tests/server/x509ca/caCert.pem | 13 + tests/strongswan.conf | 23 + 19 files changed, 1383 insertions(+), 3 deletions(-) create mode 100644 pkg/ipsec/ipsec_vici_test.go create mode 100644 tests/client/eap-tls.conf create mode 100644 tests/client/eap.conf create mode 100644 tests/client/ecdsa/clientKey.pem create mode 100644 tests/client/home.conf create mode 100644 tests/client/psk.conf create mode 100644 tests/client/swanctl.conf create mode 100644 tests/client/x509/clientCert.pem create mode 100644 tests/client/x509ca/caCert.pem create mode 100644 tests/docker-compose.yml create mode 100644 tests/server/eap.conf create mode 100644 tests/server/ecdsa/serverKey.pem create mode 100644 tests/server/psk.conf create mode 100644 tests/server/rw.conf create mode 100644 tests/server/swanctl.conf create mode 100644 tests/server/x509/serverCert.pem create mode 100644 tests/server/x509ca/caCert.pem create mode 100644 tests/strongswan.conf diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index c8390c0..effab3a 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -8,6 +8,52 @@ on: branches: [ "main" ] jobs: - call: - uses: opiproject/actions/.github/workflows/go.yml@main - secrets: inherit + build: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + go-version: [ '1.21', '1.22' ] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: ${{ matrix.go-version }} + + - name: Build + run: go build -v ./... + working-directory: cmd + + test: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build & Start containers + run: | + set -x + cd tests + docker compose up --build --force-recreate --detach + docker exec -i tests-go-test-1 go test -race -coverprofile=coverage.out -covermode=atomic -v ./... + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + + - name: Logs + if: always() + run: docker compose logs + + - name: Stop containers + if: always() + run: docker compose down --volumes --remove-orphans \ No newline at end of file diff --git a/pkg/ipsec/ipsec_vici_test.go b/pkg/ipsec/ipsec_vici_test.go new file mode 100644 index 0000000..214fd45 --- /dev/null +++ b/pkg/ipsec/ipsec_vici_test.go @@ -0,0 +1,952 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2022-2023 Intel Corporation, or its subsidiaries. + +// Package ipsec is the main package of the application +package ipsec + +import ( + "errors" + "log" + "strings" + "testing" + + pb "github.com/opiproject/opi-api/security/v1/gen/go" + "github.com/stretchr/testify/assert" +) + +func TestBuildProposal(t *testing.T) { + tests := []struct { + name string + prop *pb.Proposals + expected string + err error + }{ + { + name: "Nil Proposal", + prop: nil, + expected: "", + err: errors.New("proposal can't be nil"), + }, + { + name: "Empty Proposal", + prop: &pb.Proposals{}, + expected: "", + err: nil, + }, + { + name: "only Crypto Algorithm", + prop: &pb.Proposals{ + CryptoAlg: []pb.CryptoAlgorithm{pb.CryptoAlgorithm_CRYPTO_ALGORITHM_AES128}, + }, + expected: "aes128", + err: nil, + }, + { + name: "Multiple Crypto and Integrity Algorithms", + prop: &pb.Proposals{ + CryptoAlg: []pb.CryptoAlgorithm{pb.CryptoAlgorithm_CRYPTO_ALGORITHM_AES128, pb.CryptoAlgorithm_CRYPTO_ALGORITHM_AES256}, + IntegAlg: []pb.IntegAlgorithm{pb.IntegAlgorithm_INTEG_ALGORITHM_SHA256, pb.IntegAlgorithm_INTEG_ALGORITHM_SHA512}, + }, + expected: "aes128-aes256-sha256-sha512", + err: nil, + }, + { + name: "Complete Proposal with All Fields", + prop: &pb.Proposals{ + CryptoAlg: []pb.CryptoAlgorithm{pb.CryptoAlgorithm_CRYPTO_ALGORITHM_AES128}, + IntegAlg: []pb.IntegAlgorithm{pb.IntegAlgorithm_INTEG_ALGORITHM_SHA256}, + Prf: []pb.PRFunction{pb.PRFunction_PR_FUNCTION_SHA1}, + Dhgroups: []pb.DHGroups{pb.DHGroups_DH_GROUPS_MODP2048}, + }, + expected: "aes128-sha256-sha1-modp2048", + err: nil, + }, + { + name: "Only prf Group", + prop: &pb.Proposals{ + Prf: []pb.PRFunction{pb.PRFunction_PR_FUNCTION_AESCMAC, pb.PRFunction_PR_FUNCTION_SHA1, pb.PRFunction_PR_FUNCTION_SHA256, pb.PRFunction_PR_FUNCTION_SHA384, pb.PRFunction_PR_FUNCTION_SHA512}, + }, + expected: "aescmac-sha1-sha256-sha384-sha512", + err: nil, + }, + { + name: "Only DH Group", + prop: &pb.Proposals{ + Dhgroups: []pb.DHGroups{pb.DHGroups_DH_GROUPS_CURVE25519, pb.DHGroups_DH_GROUPS_MODP1024S160, pb.DHGroups_DH_GROUPS_MODP2048, pb.DHGroups_DH_GROUPS_MODP4096, pb.DHGroups_DH_GROUPS_MODP8192}, + }, + expected: "curve25519-modp1024s160-modp2048-modp4096-modp8192", + err: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := buildProposal(tt.prop) + if tt.err != nil { + if err == nil || !strings.Contains(err.Error(), tt.err.Error()) { + t.Errorf("Expected error: %v, got: %v", tt.err, err) + } + } else { + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + if result != tt.expected { + t.Errorf("Expected: %s, got: %s", tt.expected, result) + } + } + }) + } +} + +func TestListConn(t *testing.T) { + tests := []struct { + name string + listreq *pb.IPsecListConnsRequest + want *pb.IPsecListConnsResponse + expectedErr bool + }{ + { + name: "successes", + listreq: &pb.IPsecListConnsRequest{ + Ike: "home", + }, + want: &pb.IPsecListConnsResponse{ + Connection: []*pb.ListConnResp{ + { + Name: "home", + RemoteAddrs: []*pb.Addrs{ + { + Addr: "192.168.0.2", + }, + }, + Version: "IKEv2", + Unique: "UNIQUE_NO", + DpdDelay: 60, + Children: []*pb.ListChild{ + { + Name: "host", + Mode: "TUNNEL", + DpdAction: "trap", + CloseAction: "none", + }, + }, + }, + }, + }, + expectedErr: false, + }, + + { + name: "fail", + listreq: &pb.IPsecListConnsRequest{ + Ike: "fail", + }, + want: nil, + expectedErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + resp, err := listConns(tt.listreq) + + if tt.expectedErr { + assert.Error(t, err, "Expected an error but got none") + } else { + assert.NoError(t, err, "Did not expect an error") + } + if tt.want != nil && resp != nil { + assert.Equal(t, tt.want.Connection[0].Name, resp.Connection[0].Name) + assert.Equal(t, tt.want.Connection[0].Version, resp.Connection[0].Version) + assert.Equal(t, tt.want.Connection[0].Unique, resp.Connection[0].Unique) + assert.Equal(t, tt.want.Connection[0].DpdDelay, resp.Connection[0].DpdDelay) + assert.Equal(t, tt.want.Connection[0].Children[0].CloseAction, resp.Connection[0].Children[0].CloseAction) + assert.Equal(t, tt.want.Connection[0].Children[0].Mode, resp.Connection[0].Children[0].Mode) + } + }) + } +} + +func TestIpsecVersion(t *testing.T) { + resp, err := ipsecVersion() + + assert.NoError(t, err) + assert.Equal(t, "charon", resp.Daemon) + assert.Equal(t, "6.0.0", resp.Version) + assert.Equal(t, "Linux", resp.Sysname) + assert.Equal(t, "x86_64", resp.Machine) +} +func TestIpsecStats(t *testing.T) { + resp, err := ipsecStats() + if err != nil { + t.Fatalf("ipsecStats failed: %v", err) + } + + t.Log("IPsec Stats Output:\n", resp.Status) + + assert.NotNil(t, resp) +} + +func TestInitiateConn(t *testing.T) { + tests := []struct { + name string + initReq *pb.IPsecInitiateRequest + expectedError bool + }{ + { + name: "Valid Input", + initReq: &pb.IPsecInitiateRequest{ + Child: "eap", + Timeout: "300", + Loglevel: "2", + }, + expectedError: false, + }, + { + name: "Empty Fields", + initReq: &pb.IPsecInitiateRequest{ + Child: "", + Ike: "", + Timeout: "", + Loglevel: "", + }, + expectedError: true, + }, + { + name: "child only", + initReq: &pb.IPsecInitiateRequest{ + Child: "host", + Ike: "", + }, + expectedError: false, + }, + { + name: "invlaid child", + initReq: &pb.IPsecInitiateRequest{ + Child: "hostdummy", + Ike: "", + Timeout: "20", + Loglevel: "", + }, + expectedError: true, + }, + { + name: "incorrect connection and child", + initReq: &pb.IPsecInitiateRequest{ + Child: "net", + Ike: "incorrectike", + Timeout: "", + Loglevel: "2", + }, + expectedError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := initiateConn(tt.initReq) + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none") + } else { + assert.NoError(t, err, "Did not expect an error but got one") + } + }) + } +} +func TestRekeyConn(t *testing.T) { + tests := []struct { + name string + rekeyReq *pb.IPsecRekeyRequest + expectErr bool + }{ + { + name: "Success case", + rekeyReq: &pb.IPsecRekeyRequest{ + Child: "host", + Ike: "home", + Reauth: "yes", + }, + expectErr: false, + }, + { + name: "Child Only", + rekeyReq: &pb.IPsecRekeyRequest{ + Child: "eap", + }, + expectErr: false, + }, + + { + name: "Chile correct incorrect IKE", + rekeyReq: &pb.IPsecRekeyRequest{ + Child: "net", + Ike: "hom", + }, + expectErr: true, + }, + + { + name: "Incorrect ID", + rekeyReq: &pb.IPsecRekeyRequest{ + IkeId: 14, + ChildId: 44, + }, + expectErr: true, + }, + { + name: "Empty Response", + rekeyReq: &pb.IPsecRekeyRequest{}, + expectErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + success, matches, err := rekeyConn(tt.rekeyReq) + + log.Printf("Test Case: %s -> success=%s, matches=%d, err=%v", tt.name, success, matches, err) + + if tt.expectErr { + assert.NotNil(t, err, "Expected an error") + } else { + assert.Nil(t, err, "Expected no error") + assert.NotEmpty(t, success, "Success should not be empty") + assert.GreaterOrEqual(t, matches, uint32(0), "Matches should be 0 or more") + } + }) + } +} + +func TestListSas(t *testing.T) { + tests := []struct { + name string + req *pb.IPsecListSasRequest + want *pb.IPsecListSasResponse + expectErr bool + }{ + { + name: "Invalid IKE/Child ID", + req: &pb.IPsecListSasRequest{ + IkeId: 99999, + ChildId: 99999, + }, + want: nil, + expectErr: false, + }, + { + name: "Empty Request", + req: &pb.IPsecListSasRequest{}, + want: &pb.IPsecListSasResponse{ + Ikesas: []*pb.ListIkeSa{ + {Name: "home", + Uniqueid: "2", + Version: "2", + LocalHost: "192.168.0.3", + LocalPort: "4500", + LocalId: "client.strongswan.org", + RemoteHost: "192.168.0.2", + RemotePort: "4500", + RemoteId: "server.strongswan.org", + Initiator: "yes", + InitiatorSpi: "d47e69ccced1b166", + ResponderSpi: "5e8efa64e7a67d47", + EncrAlg: "AES_CBC", + EncrKeysize: "256", + IntegAlg: "HMAC_SHA2_256_128", + PrfAlg: "PRF_HMAC_SHA2_256", + DhGroup: "CURVE_25519", + Established: "820", + RekeyTime: "13497", + LocalVips: []string{"10.3.0.1"}, + Childsas: []*pb.ListChildSa{ + + {Name: "eap-tls-3", + Protocol: "ESP", + SpiIn: "c844bfee", + SpiOut: "c924d144", + EncrAlg: "AES_GCM_16", + EncrKeysize: "256", + }}, + }, + { + Name: "eap", + Uniqueid: "2", Version: "2", LocalHost: "192.168.0.3", + LocalPort: "4500", LocalId: "192.168.0.3", + RemoteHost: "192.168.0.2", + RemotePort: "4500", + RemoteId: "server.strongswan.org", + Initiator: "yes", + InitiatorSpi: "1c3638ad340706b5", + ResponderSpi: "74eb0bcde7b51c8e", + EncrAlg: "AES_CBC", + EncrKeysize: "256", + IntegAlg: "HMAC_SHA2_256_128", + PrfAlg: "PRF_HMAC_SHA2_256", + DhGroup: "CURVE_25519", + Established: "824", + RekeyTime: "12189", + LocalVips: []string{"10.3.0.2"}, + Childsas: []*pb.ListChildSa{{Name: "eap-2", + Protocol: "ESP", + SpiIn: "ce647fcb", + SpiOut: "cd0fa5df", + EncrAlg: "AES_GCM_16", + EncrKeysize: "256", + }, + }}, + { + Name: "home", + Uniqueid: "1", + Version: "2", + LocalHost: "192.168.0.3", + LocalPort: "4500", + LocalId: "client.strongswan.org", + RemoteHost: "192.168.0.2", + RemotePort: "4500", + RemoteId: "server.strongswan.org", + Initiator: "yes", + InitiatorSpi: "37e96a6869718fb9", + ResponderSpi: "af188e5f2d56669b", + EncrAlg: "AES_CBC", + EncrKeysize: "256", + IntegAlg: "HMAC_SHA2_256_128", + PrfAlg: "PRF_HMAC_SHA2_256", + DhGroup: "CURVE_25519", + Established: "42", + RekeyTime: "13179", + LocalVips: []string{"10.3.0.1"}, + }, + }, + }, + expectErr: false, + }, + { + name: "Partial Request - Ike Only", + req: &pb.IPsecListSasRequest{ + Ike: "eap", + }, + want: &pb.IPsecListSasResponse{ + Ikesas: []*pb.ListIkeSa{ + { + Name: "eap", + Uniqueid: "1", Version: "2", LocalHost: "192.168.0.3", + LocalPort: "4500", LocalId: "192.168.0.3", + RemoteHost: "192.168.0.2", + RemotePort: "4500", + RemoteId: "server.strongswan.org", + Initiator: "yes", + InitiatorSpi: "1c3638ad340706b5", + ResponderSpi: "74eb0bcde7b51c8e", + EncrAlg: "AES_CBC", + EncrKeysize: "256", + IntegAlg: "HMAC_SHA2_256_128", + PrfAlg: "PRF_HMAC_SHA2_256", + DhGroup: "CURVE_25519", + Established: "824", + RekeyTime: "12189", + LocalVips: []string{"10.3.0.2"}, + Childsas: []*pb.ListChildSa{{Name: "eap-2", + Protocol: "ESP", + SpiIn: "ce647fcb", + SpiOut: "cd0fa5df", + EncrAlg: "AES_GCM_16", + EncrKeysize: "256", + DhGroup: "CURVE_25519", + }, + }}, + }, + }, + expectErr: false, + }, + { + name: "Partial Request - Child Only", + req: &pb.IPsecListSasRequest{ + Child: "eap-tls", + }, + want: &pb.IPsecListSasResponse{ + Ikesas: []*pb.ListIkeSa{ + + {Name: "home", + Uniqueid: "2", + Version: "2", + LocalHost: "192.168.0.3", + LocalPort: "4500", + LocalId: "client.strongswan.org", + RemoteHost: "192.168.0.2", + RemotePort: "4500", + RemoteId: "server.strongswan.org", + Initiator: "yes", + InitiatorSpi: "d47e69ccced1b166", + ResponderSpi: "5e8efa64e7a67d47", + EncrAlg: "AES_CBC", + EncrKeysize: "256", + IntegAlg: "HMAC_SHA2_256_128", + PrfAlg: "PRF_HMAC_SHA2_256", + DhGroup: "CURVE_25519", + + LocalVips: []string{"10.3.0.1"}, + Childsas: []*pb.ListChildSa{ + + {Name: "eap-tls-3", + Protocol: "ESP", + SpiIn: "c844bfee", + SpiOut: "c924d144", + EncrAlg: "AES_GCM_16", + EncrKeysize: "256", + }}, + }, + }, + }, + expectErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + resp, err := listSas(tt.req) + + if tt.expectErr { + assert.Error(t, err, "Expected an error but got none") + } else { + assert.NoError(t, err, "Did not expect an error") + } + if tt.want != nil && resp != nil { + assert.Equal(t, resp.Ikesas[0].Name, tt.want.Ikesas[0].Name) + assert.Equal(t, resp.Ikesas[0].Uniqueid, tt.want.Ikesas[0].Uniqueid) + assert.Equal(t, resp.Ikesas[0].Version, tt.want.Ikesas[0].Version) + assert.Equal(t, resp.Ikesas[0].LocalHost, tt.want.Ikesas[0].LocalHost) + assert.Equal(t, resp.Ikesas[0].LocalPort, tt.want.Ikesas[0].LocalPort) + assert.Equal(t, resp.Ikesas[0].LocalId, tt.want.Ikesas[0].LocalId) + assert.Equal(t, resp.Ikesas[0].RemoteHost, tt.want.Ikesas[0].RemoteHost) + assert.Equal(t, resp.Ikesas[0].RemotePort, tt.want.Ikesas[0].RemotePort) + assert.Equal(t, resp.Ikesas[0].RemoteId, tt.want.Ikesas[0].RemoteId) + assert.Equal(t, resp.Ikesas[0].Initiator, tt.want.Ikesas[0].Initiator) + assert.Equal(t, resp.Ikesas[0].EncrAlg, tt.want.Ikesas[0].EncrAlg) + assert.Equal(t, resp.Ikesas[0].EncrKeysize, tt.want.Ikesas[0].EncrKeysize) + assert.Equal(t, resp.Ikesas[0].IntegAlg, tt.want.Ikesas[0].IntegAlg) + assert.Equal(t, resp.Ikesas[0].PrfAlg, tt.want.Ikesas[0].PrfAlg) + assert.Equal(t, resp.Ikesas[0].DhGroup, tt.want.Ikesas[0].DhGroup) + assert.Equal(t, resp.Ikesas[0].Name, tt.want.Ikesas[0].Name) + } + }) + } +} +func TestTerminateConn(t *testing.T) { + tests := []struct { + name string + termReq *pb.IPsecTerminateRequest + expectedError bool + }{ + { + name: "Valid Input", + termReq: &pb.IPsecTerminateRequest{ + Child: "eap", + Timeout: "30", + Force: "yes", + Loglevel: "2", + }, + expectedError: false, + }, + { + name: "no Timeout", + termReq: &pb.IPsecTerminateRequest{ + Child: "host", + Force: "yes", + Loglevel: "2", + }, + expectedError: false, + }, + + { + name: "Empty Fields", + termReq: &pb.IPsecTerminateRequest{ + Child: "", + Ike: "", + ChildId: 0, + IkeId: 0, + Timeout: "", + Force: "", + Loglevel: "", + }, + expectedError: true, + }, + + { + name: "incorrect id", + termReq: &pb.IPsecTerminateRequest{ + + ChildId: 4, + IkeId: 4, + Timeout: "", + Force: "", + Loglevel: "", + }, + expectedError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := terminateConn(tt.termReq) + + if tt.expectedError { + assert.Error(t, err, "Expected an error but got none") + } else { + assert.NoError(t, err, "Did not expect an error but got one") + } + }) + } +} // go test -timeout 30s -run ^TestInitiateConn$ github.com/opiproject/opi-strongswan-bridge/pkg/ipsec +func TestLoadConn(t *testing.T) { + tests := []struct { + name string + connReq *pb.IPsecLoadConnRequest + expectErr bool + }{{ + name: "Valid LoadConnRequest", + connReq: &pb.IPsecLoadConnRequest{Connection: &pb.Connection{ + Name: "ikev1-l2tp-chap-auth-in-l2tp", + Version: "1", + RekeyTime: 2, + DpdDelay: 30, + DpdTimeout: 90, + ReauthTime: 2, + Children: []*pb.Child{ + { + Name: "ikev1-l2tp-chap-auth-in-l2tp", + RekeyTime: 0, + }, + }, + }}, + expectErr: false, + }, { + name: "Valid LoadConnRequest all fields", + connReq: &pb.IPsecLoadConnRequest{Connection: &pb.Connection{ + Name: "conn", + Version: "2", + Proposals: &pb.Proposals{ + CryptoAlg: []pb.CryptoAlgorithm{ + pb.CryptoAlgorithm_CRYPTO_ALGORITHM_AES256GCM128, + }, + IntegAlg: []pb.IntegAlgorithm{ + pb.IntegAlgorithm_INTEG_ALGORITHM_SHA256, + }, + Prf: []pb.PRFunction{ + pb.PRFunction_PR_FUNCTION_SHA1, + }, + Dhgroups: []pb.DHGroups{ + pb.DHGroups_DH_GROUPS_MODP768, + }, + }, + Pools: &pb.Pools{ + Pool: []string{ + "10.3.0.0/24", + }, + }, + DpdDelay: 30, + LocalAuth: &pb.LocalAuth{ + Auth: pb.AuthType_AUTH_TYPE_PUBKEY, + Id: "server.strongswan.org", + + Certs: &pb.Certs{ + Cert: []string{ + "MIICADCCAYWgAwIBAgIIWpEKfsh+QqYwCgYIKoZIzj0EAwMwNTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMB4XDTIwMDMwOTEyMDMzOFoXDTI0MDMwOTEyMDMzOFowPTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMR4wHAYDVQQDExVzZXJ2ZXIuc3Ryb25nc3dhbi5vcmcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASvt8McyFuyGVggth+Izf/qB+SQHgKxHEgvAB+6Gj52xrcdxZl0/cXwL5NG3rxur3dzBzEuJRb/oYxqgNcZrT/28239tAN8PHkST0u+kFwZF3PTDXdyrkGT3PKv7Kb6dWWjWjBYMB8GA1UdIwQYMBaAFLjSYIqHz0jucV3YUSAjWsGq5feyMCAGA1UdEQQZMBeCFXNlcnZlci5zdHJvbmdzd2FuLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDATAKBggqhkjOPQQDAwNpADBmAjEA9TJ6mQykJfTD/MK4FqxAX4bTowM3LvMzniEBbDVCct3oLW2VqU8A12MEwYlj4FulAjEAlYCiquZUoPrV19gdN3MaXJe/7dwEjXczD1/5T4UjrWUbS+D7J5/DsEMYM10LNXgB", + }, + }, + }, + RemoteAuth: &pb.RemoteAuth{ + Auth: pb.AuthType_AUTH_TYPE_PUBKEY, + CaCerts: &pb.CaCerts{ + Cacert: []string{ + "MIIB3zCCAWWgAwIBAgIIY2hNABEgfdwwCgYIKoZIzj0EAwMwNTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMB4XDTI0MDMyMDE1MDEwNFoXDTM0MDMyMDE1MDEwNFowNTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEaBYrQANrXYQ18O9V2vKhBL7ovUm08g/R8wqFGvUe00bnvD/abQ/TITDhi/OYt2mw6TjCNGbcfoR4g4sc8nbm4SWCDklPCchiBUE3U038Q1pgurYil4SEP9aN770ik4PGo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUDGF7Wkdff6c4YPYn0r66emv6elcwCgYIKoZIzj0EAwMDaAAwZQIwMbH3l4rQkFpr8Hh4yRBOn7BedBLgXehNXRpG15zHN+DmgGdZOQ5+3kiOjLTqBWYSAjEA0WDLGsF3XSHCQfEWF5zyXomMpPdg8ZuqBHeSBJQMvmL4S+dfkLd/TP1L+R+7nQjn", + }, + }, + }, + Children: []*pb.Child{ + + { + Name: "nett", + LocalTs: &pb.TrafficSelectors{ + Ts: []*pb.TrafficSelectors_TrafficSelector{ + { + Cidr: "10.1.0.0/24", + }, + }, + }, + RekeyTime: 0, + }, + { + Name: "hostt", + + RekeyTime: 0, + }, + }, + }}, + expectErr: false, + }, + { + name: "with multiple chiilds", + connReq: &pb.IPsecLoadConnRequest{ + Connection: &pb.Connection{ + Name: "Con", + Version: "2", + RekeyTime: 0, + DpdDelay: 30, + DpdTimeout: 90, + LocalAddrs: []*pb.Addrs{ + {Addr: "192.168.1.1"}, + {Addr: "192.168.1.2"}, + }, + RemoteAddrs: []*pb.Addrs{ + {Addr: "10.0.0.1"}, + }, + LocalPort: 500, + RemotePort: 500, + Proposals: &pb.Proposals{ + CryptoAlg: []pb.CryptoAlgorithm{ + pb.CryptoAlgorithm_CRYPTO_ALGORITHM_AES256GCM128, + }, + IntegAlg: []pb.IntegAlgorithm{ + pb.IntegAlgorithm_INTEG_ALGORITHM_SHA256, + }, + Prf: []pb.PRFunction{ + pb.PRFunction_PR_FUNCTION_SHA1, + }, + Dhgroups: []pb.DHGroups{ + pb.DHGroups_DH_GROUPS_MODP768, + }, + }, + Vips: &pb.Vips{ + Vip: []string{ + "1.1.1.1", + "2.2.2.2", + }, + }, + Dscp: 000001, + Encap: "no", + Mobike: "yes", + ReauthTime: 0, + Pools: &pb.Pools{ + Pool: []string{ + "1.1.1.1", + "2.2.2.2", + }, + }, + LocalAuth: &pb.LocalAuth{ + Auth: pb.AuthType_AUTH_TYPE_EAP, + Id: "id", + EapId: "id", + AaaId: "id", + XauthId: "id", + }, + RemoteAuth: &pb.RemoteAuth{ + Auth: pb.AuthType_AUTH_TYPE_EAP, + Id: "id", + }, + Children: []*pb.Child{ + { + Name: "ikev1", + RekeyTime: 2, + LifeTime: 2, + RandTime: 2, + EspProposals: &pb.Proposals{ + CryptoAlg: []pb.CryptoAlgorithm{ + pb.CryptoAlgorithm_CRYPTO_ALGORITHM_AES256GCM128, + }, + IntegAlg: []pb.IntegAlgorithm{ + pb.IntegAlgorithm_INTEG_ALGORITHM_SHA256, + }, + Prf: []pb.PRFunction{ + pb.PRFunction_PR_FUNCTION_SHA1, + }, + Dhgroups: []pb.DHGroups{ + pb.DHGroups_DH_GROUPS_MODP768, + }, + }, + MarkIn: uint32(0x00000000), + MarkOut: uint32(0x00000000), + SetMarkIn: uint32(0x00000000), + SetMarkOut: uint32(0x00000000), + Inactivity: uint32(0), + + LocalTs: &pb.TrafficSelectors{ + Ts: []*pb.TrafficSelectors_TrafficSelector{ + { + Cidr: "10.1.0.0/16", + }, + { + Cidr: "10.2.0.0/16", + }, + }, + }, + + RemoteTs: &pb.TrafficSelectors{ + Ts: []*pb.TrafficSelectors_TrafficSelector{ + { + Cidr: "10.1.0.2/16", + }, + { + Cidr: "10.2.0.2/16", + }, + }, + }, + }, + }}, + }, + expectErr: false, + }, + } + + // Run test cases + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + log.Printf("Running test case: %s", tc.name) + err := loadConn(tc.connReq) + + if tc.expectErr && err == nil { + t.Fatalf("Expected an error but got nil") + } + if !tc.expectErr && err != nil { + t.Fatalf("Did not expect an error but got: %v", err) + } + log.Printf("Test case passed: %s", tc.name) + }) + } +} +func TestUnloadConn(t *testing.T) { + type args struct { + connreq *pb.IPsecUnloadConnRequest + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "Unload Connection", + args: args{ + connreq: &pb.IPsecUnloadConnRequest{ + Name: "conn", + }, + }, + wantErr: false, + }, + { + + name: "Empty Name", + args: args{ + connreq: &pb.IPsecUnloadConnRequest{ + Name: "", + }, + }, + wantErr: true, + }, + + { + name: "Invalid Name", + args: args{ + connreq: &pb.IPsecUnloadConnRequest{ + Name: "noo", + }, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := unloadConn(tt.args.connreq); (err != nil) != tt.wantErr { + t.Errorf("unloadConn() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestListCert(t *testing.T) { + type args struct { + listreq *pb.IPsecListCertsRequest + } + tests := []struct { + name string + args args + want *pb.IPsecListCertsResponse + wantErr bool + }{ + { + name: "All Fields", + args: args{ + listreq: &pb.IPsecListCertsRequest{ + Type: "ANY", + Flag: "X509_CERTIFICATE_FLAG_CA ", + Subject: "C=CH, O=Cyber, CN=Cyber Root CA", + }, + }, + want: &pb.IPsecListCertsResponse{ + Certs: []*pb.ListCert{ + + { + Flag: pb.X509CertificateFlag_X509_CERTIFICATE_FLAG_CA, + Data: "MIIB3zCCAWWgAwIBAgIIY2hNABEgfdwwCgYIKoZIzj0EAwMwNTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMB4XDTI0MDMyMDE1MDEwNFoXDTM0MDMyMDE1MDEwNFowNTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEaBYrQANrXYQ18O9V2vKhBL7ovUm08g/R8wqFGvUe00bnvD/abQ/TITDhi/OYt2mw6TjCNGbcfoR4g4sc8nbm4SWCDklPCchiBUE3U038Q1pgurYil4SEP9aN770ik4PGo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUDGF7Wkdff6c4YPYn0r66emv6elcwCgYIKoZIzj0EAwMDaAAwZQIwMbH3l4rQkFpr8Hh4yRBOn7BedBLgXehNXRpG15zHN+DmgGdZOQ5+3kiOjLTqBWYSAjEA0WDLGsF3XSHCQfEWF5zyXomMpPdg8ZuqBHeSBJQMvmL4S+dfkLd/TP1L+R+7nQjn", + }, + {}, + }, + }, + wantErr: false, + }, + { + name: "Any type", + args: args{ + listreq: &pb.IPsecListCertsRequest{ + Type: "ANY", + }, + }, + want: &pb.IPsecListCertsResponse{ + Certs: []*pb.ListCert{ + { + Data: "MIIB/jCCAYWgAwIBAgIIdjhAuCUYRAowCgYIKoZIzj0EAwMwNTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMB4XDTI0MDMyMDE1MDEwNFoXDTI4MDMyMDE1MDEwNFowPTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMR4wHAYDVQQDExVzZXJ2ZXIuc3Ryb25nc3dhbi5vcmcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASg6vN2xsiEnhYhyUsSaR/36nLeaFiWaQNWg2yDs1s7uUd1cV5blykLCLlZkWrsCevAUSd31bk0zwE5sejbmpr6QT/gx1vk0SX00X8J5fBJuWrc11t8zibT0M3DSizMkCKjWjBYMB8GA1UdIwQYMBaAFAxhe1pHX3+nOGD2J9K+unpr+npXMCAGA1UdEQQZMBeCFXNlcnZlci5zdHJvbmdzd2FuLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDATAKBggqhkjOPQQDAwNnADBkAjB9FEikOg5H7G0nLi32b76gs/+hQc1bD76aUGlB9jMM0194Xv6np2WXW1vaJEcdPzICMFqJeIPbztLv5dXZ48vX9jsOAxFfL5hF+noqP2XEyWWjdFoOdl2OOCItO6Vtgj5wFw==", + }, + { + Hasprivkey: "yes", + Data: "MIIB/jCCAYWgAwIBAgIICMc07G3AzUkwCgYIKoZIzj0EAwMwNTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMB4XDTI0MDMyMDE1MDEwNFoXDTI4MDMyMDE1MDEwNFowPTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMR4wHAYDVQQDExVjbGllbnQuc3Ryb25nc3dhbi5vcmcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATDL1oHZ5vUCPHuehNQEu6QBSLCgmHPgumNgvuN7mJGonygw9NQIRL1OD/gBAgy+6uaq/EjGv0+8/wK+wvOW6z+nJbm2fR51z+ix7OjkBOvSBv+v8QbcUsEsU72LvBTLeqjWjBYMB8GA1UdIwQYMBaAFAxhe1pHX3+nOGD2J9K+unpr+npXMCAGA1UdEQQZMBeCFWNsaWVudC5zdHJvbmdzd2FuLm9yZzATBgNVHSUEDDAKBggrBgEFBQcDAjAKBggqhkjOPQQDAwNnADBkAjAo+M9G3gKmrYY+flGXN3VqztMvtil9vTXeFYABQ+UUXtDz5pY379bvV/rHdcamJCQCMB1ilfGVHqrcDzcAwp4QlzEboXwcXOx9QZSVbSXafRIJZ8zSxZePmRAVC1DsSTXjdA==", + }, + { + Flag: pb.X509CertificateFlag_X509_CERTIFICATE_FLAG_CA, + Data: "MIIB3zCCAWWgAwIBAgIIY2hNABEgfdwwCgYIKoZIzj0EAwMwNTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMB4XDTI0MDMyMDE1MDEwNFoXDTM0MDMyMDE1MDEwNFowNTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEaBYrQANrXYQ18O9V2vKhBL7ovUm08g/R8wqFGvUe00bnvD/abQ/TITDhi/OYt2mw6TjCNGbcfoR4g4sc8nbm4SWCDklPCchiBUE3U038Q1pgurYil4SEP9aN770ik4PGo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUDGF7Wkdff6c4YPYn0r66emv6elcwCgYIKoZIzj0EAwMDaAAwZQIwMbH3l4rQkFpr8Hh4yRBOn7BedBLgXehNXRpG15zHN+DmgGdZOQ5+3kiOjLTqBWYSAjEA0WDLGsF3XSHCQfEWF5zyXomMpPdg8ZuqBHeSBJQMvmL4S+dfkLd/TP1L+R+7nQjn", + }, + {}, + }, + }, + wantErr: false, + }, + + { + name: "only subject", + args: args{ + listreq: &pb.IPsecListCertsRequest{ + Subject: "C=CH, O=Cyber, CN=Cyber Root CA", + }, + }, + want: &pb.IPsecListCertsResponse{ + Certs: []*pb.ListCert{ + { + Flag: pb.X509CertificateFlag_X509_CERTIFICATE_FLAG_CA, + Data: "MIIB3zCCAWWgAwIBAgIIY2hNABEgfdwwCgYIKoZIzj0EAwMwNTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMB4XDTI0MDMyMDE1MDEwNFoXDTM0MDMyMDE1MDEwNFowNTELMAkGA1UEBhMCQ0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEaBYrQANrXYQ18O9V2vKhBL7ovUm08g/R8wqFGvUe00bnvD/abQ/TITDhi/OYt2mw6TjCNGbcfoR4g4sc8nbm4SWCDklPCchiBUE3U038Q1pgurYil4SEP9aN770ik4PGo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUDGF7Wkdff6c4YPYn0r66emv6elcwCgYIKoZIzj0EAwMDaAAwZQIwMbH3l4rQkFpr8Hh4yRBOn7BedBLgXehNXRpG15zHN+DmgGdZOQ5+3kiOjLTqBWYSAjEA0WDLGsF3XSHCQfEWF5zyXomMpPdg8ZuqBHeSBJQMvmL4S+dfkLd/TP1L+R+7nQjn", + }, + {}, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := listCerts(tt.args.listreq) + if (err != nil) != tt.wantErr { + t.Errorf("listCerts() error = %v, wantErr %v", err, tt.wantErr) + return + } + + assert.Equal(t, len(got.Certs), len(tt.want.Certs)) + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/tests/client/eap-tls.conf b/tests/client/eap-tls.conf new file mode 100644 index 0000000..6de8808 --- /dev/null +++ b/tests/client/eap-tls.conf @@ -0,0 +1,24 @@ +eap-tls { + remote_addrs = 192.168.0.2 + vips = 0.0.0.0 + + local { + auth = eap-tls + eap_id = client.strongswan.org + } + remote { + auth = pubkey + id = server.strongswan.org + } + children { + eap-tls { + remote_ts = 10.1.0.0/16,192.168.0.2 + + esp_proposals = aes256gcm128-x25519 + dpd_action = trap + } + } + version = 2 + proposals = aes256-sha256-x25519 + dpd_delay = 60s +} diff --git a/tests/client/eap.conf b/tests/client/eap.conf new file mode 100644 index 0000000..6d7fe94 --- /dev/null +++ b/tests/client/eap.conf @@ -0,0 +1,24 @@ +eap { + remote_addrs = 192.168.0.2 + vips = 0.0.0.0 + + local { + auth = eap-md5 + eap_id = hacker + } + remote { + auth = pubkey + id = server.strongswan.org + } + children { + eap { + remote_ts = 10.1.0.0/16,192.168.0.2 + + esp_proposals = aes256gcm128-x25519 + dpd_action = trap + } + } + version = 2 + proposals = aes256-sha256-x25519 + dpd_delay = 60s +} diff --git a/tests/client/ecdsa/clientKey.pem b/tests/client/ecdsa/clientKey.pem new file mode 100644 index 0000000..ad97458 --- /dev/null +++ b/tests/client/ecdsa/clientKey.pem @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDBL+uDhSo1oLO97RxcNy8GZGgmhludFDVhvqmXJVTbZXcMRP+R/Dpu9 +FrSQwFunuTSgBwYFK4EEACKhZANiAATDL1oHZ5vUCPHuehNQEu6QBSLCgmHPgumN +gvuN7mJGonygw9NQIRL1OD/gBAgy+6uaq/EjGv0+8/wK+wvOW6z+nJbm2fR51z+i +x7OjkBOvSBv+v8QbcUsEsU72LvBTLeo= +-----END EC PRIVATE KEY----- diff --git a/tests/client/home.conf b/tests/client/home.conf new file mode 100644 index 0000000..2e59a9a --- /dev/null +++ b/tests/client/home.conf @@ -0,0 +1,29 @@ +home { + remote_addrs = 192.168.0.2 + vips = 0.0.0.0 + + local { + auth = pubkey + certs = clientCert.pem + id = client.strongswan.org + } + remote { + auth = pubkey + id = server.strongswan.org + } + children { + net { + remote_ts = 10.1.0.0/16 + + esp_proposals = aes256gcm128-chacha20poly1305-x25519-ke1_mlkem768 + dpd_action = trap + } + host { + esp_proposals = aes256gcm128-chacha20poly1305-x25519-ke1_mlkem768 + dpd_action = trap + } + } + version = 2 + proposals = aes256-sha256-x25519-ke1_mlkem768 + dpd_delay = 60s +} diff --git a/tests/client/psk.conf b/tests/client/psk.conf new file mode 100644 index 0000000..9f1f1dd --- /dev/null +++ b/tests/client/psk.conf @@ -0,0 +1,25 @@ +psk { + remote_addrs = 192.168.0.2 + vips = 0.0.0.0 + + local { + auth = psk + id = hacker@strongswan.org + } + remote { + auth = psk + id = server.strongswan.org + } + children { + psk { + remote_ts = 10.1.0.0/16 + + esp_proposals = chacha20poly1305-x25519-ke1_mlkem512 + dpd_action = trap + } + } + version = 2 + proposals = aes256-sha256-x25519-ke1_mlkem512 + dpd_delay = 60s + send_certreq = no +} diff --git a/tests/client/swanctl.conf b/tests/client/swanctl.conf new file mode 100644 index 0000000..29e5696 --- /dev/null +++ b/tests/client/swanctl.conf @@ -0,0 +1,19 @@ +connections { + + include home.conf + include psk.conf + include eap.conf + include eap-tls.conf +} + +secrets { + + ike-hacker { + id = hacker@strongswan.org + secret = 0sH7+o6wysMoaELv5OBihKVa3F + } + eap-hacker { + id = hacker + secret = K8FW9/N0VIAJ + } +} diff --git a/tests/client/x509/clientCert.pem b/tests/client/x509/clientCert.pem new file mode 100644 index 0000000..ab79281 --- /dev/null +++ b/tests/client/x509/clientCert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIICMc07G3AzUkwCgYIKoZIzj0EAwMwNTELMAkGA1UEBhMC +Q0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMB4XDTI0 +MDMyMDE1MDEwNFoXDTI4MDMyMDE1MDEwNFowPTELMAkGA1UEBhMCQ0gxDjAMBgNV +BAoTBUN5YmVyMR4wHAYDVQQDExVjbGllbnQuc3Ryb25nc3dhbi5vcmcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATDL1oHZ5vUCPHuehNQEu6QBSLCgmHPgumNgvuN7mJG +onygw9NQIRL1OD/gBAgy+6uaq/EjGv0+8/wK+wvOW6z+nJbm2fR51z+ix7OjkBOv +SBv+v8QbcUsEsU72LvBTLeqjWjBYMB8GA1UdIwQYMBaAFAxhe1pHX3+nOGD2J9K+ +unpr+npXMCAGA1UdEQQZMBeCFWNsaWVudC5zdHJvbmdzd2FuLm9yZzATBgNVHSUE +DDAKBggrBgEFBQcDAjAKBggqhkjOPQQDAwNnADBkAjAo+M9G3gKmrYY+flGXN3Vq +ztMvtil9vTXeFYABQ+UUXtDz5pY379bvV/rHdcamJCQCMB1ilfGVHqrcDzcAwp4Q +lzEboXwcXOx9QZSVbSXafRIJZ8zSxZePmRAVC1DsSTXjdA== +-----END CERTIFICATE----- diff --git a/tests/client/x509ca/caCert.pem b/tests/client/x509ca/caCert.pem new file mode 100644 index 0000000..85ff961 --- /dev/null +++ b/tests/client/x509ca/caCert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB3zCCAWWgAwIBAgIIY2hNABEgfdwwCgYIKoZIzj0EAwMwNTELMAkGA1UEBhMC +Q0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMB4XDTI0 +MDMyMDE1MDEwNFoXDTM0MDMyMDE1MDEwNFowNTELMAkGA1UEBhMCQ0gxDjAMBgNV +BAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAEaBYrQANrXYQ18O9V2vKhBL7ovUm08g/R8wqFGvUe00bnvD/abQ/T +ITDhi/OYt2mw6TjCNGbcfoR4g4sc8nbm4SWCDklPCchiBUE3U038Q1pgurYil4SE +P9aN770ik4PGo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQUDGF7Wkdff6c4YPYn0r66emv6elcwCgYIKoZIzj0EAwMDaAAwZQIw +MbH3l4rQkFpr8Hh4yRBOn7BedBLgXehNXRpG15zHN+DmgGdZOQ5+3kiOjLTqBWYS +AjEA0WDLGsF3XSHCQfEWF5zyXomMpPdg8ZuqBHeSBJQMvmL4S+dfkLd/TP1L+R+7 +nQjn +-----END CERTIFICATE----- diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml new file mode 100644 index 0000000..e82c4b8 --- /dev/null +++ b/tests/docker-compose.yml @@ -0,0 +1,67 @@ +version: "3" + +services: + vpn-server: + image: strongx509/strongswan:latest + cap_add: + - NET_ADMIN + - SYS_ADMIN + - SYS_MODULE + stdin_open: true + tty: true + volumes: + - ./server:/etc/swanctl + - ./strongswan.conf:/etc/strongswan.conf + - /var/run + networks: + internet: + ipv4_address: 192.168.0.2 + intranet: + ipv4_address: 10.1.0.2 + command: './charon' + + go-test: + image: golang + volumes: + - ../.:/app + depends_on: + - vpn-client + volumes_from: + - vpn-client:rw + stdin_open: true + tty: true + networks: + - internet + - intranet + working_dir: /app + + vpn-client: + image: strongx509/strongswan:latest + depends_on: + - vpn-server + cap_add: + - NET_ADMIN + - SYS_ADMIN + - SYS_MODULE + stdin_open: true + tty: true + volumes: + - ./client:/etc/swanctl + - ./strongswan.conf:/etc/strongswan.conf + - /var/run + networks: + internet: + ipv4_address: 192.168.0.3 + command: './charon' + +networks: + internet: + ipam: + driver: default + config: + - subnet: 192.168.0.0/24 + intranet: + ipam: + driver: default + config: + - subnet: 10.1.0.0/16 diff --git a/tests/server/eap.conf b/tests/server/eap.conf new file mode 100644 index 0000000..8566ee8 --- /dev/null +++ b/tests/server/eap.conf @@ -0,0 +1,24 @@ +eap { + pools = rw_pool + + local { + auth = pubkey + certs = serverCert.pem + id = server.strongswan.org + } + remote { + auth = eap-dynamic + eap_id = %any + } + children { + eap { + local_ts = 10.1.0.0/24,192.168.0.2 + + esp_proposals = aes256gcm128-chacha20poly1305-x25519-ke1_mlkem768-ke1_mlkem512-ke1_none + dpd_action = clear + } + } + version = 2 + proposals = aes256-sha256-x25519-ke1_mlkem768-ke1_mlkem512-ke1_none + dpd_delay = 60s +} diff --git a/tests/server/ecdsa/serverKey.pem b/tests/server/ecdsa/serverKey.pem new file mode 100644 index 0000000..492fa7c --- /dev/null +++ b/tests/server/ecdsa/serverKey.pem @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDCAVWp859/rJOo9+GHYCgZsn9CtSmbU5s+WFDt5hBSy3OgfXODXbzJ4 +FkCiejAmeFugBwYFK4EEACKhZANiAASg6vN2xsiEnhYhyUsSaR/36nLeaFiWaQNW +g2yDs1s7uUd1cV5blykLCLlZkWrsCevAUSd31bk0zwE5sejbmpr6QT/gx1vk0SX0 +0X8J5fBJuWrc11t8zibT0M3DSizMkCI= +-----END EC PRIVATE KEY----- diff --git a/tests/server/psk.conf b/tests/server/psk.conf new file mode 100644 index 0000000..eee4353 --- /dev/null +++ b/tests/server/psk.conf @@ -0,0 +1,22 @@ +psk { + pools = rw_pool + + local { + auth = psk + id = server.strongswan.org + } + remote { + auth = psk + } + children { + psk { + local_ts = 10.1.0.0/24 + + esp_proposals = aes256gcm128-chacha20poly1305-x25519-ke1_mlkem768-ke1_mlkem512-ke1_none + dpd_action = clear + } + } + version = 2 + proposals = aes256-sha256-x25519-ke1_mlkem768-ke1_mlkem512-ke1_none + dpd_delay = 60s +} diff --git a/tests/server/rw.conf b/tests/server/rw.conf new file mode 100644 index 0000000..e13b1c4 --- /dev/null +++ b/tests/server/rw.conf @@ -0,0 +1,28 @@ +rw { + pools = rw_pool + + local { + auth = pubkey + certs = serverCert.pem + id = server.strongswan.org + } + remote { + auth = pubkey + cacerts = caCert.pem + } + children { + net { + local_ts = 10.1.0.0/24 + + esp_proposals = aes256gcm128-chacha20poly1305-x25519-ke1_mlkem768-ke1_mlkem512-ke1_none + dpd_action = clear + } + host { + esp_proposals = aes256gcm128-chacha20poly1305-x25519-ke1_mlkem768-ke1_mlkem512-ke1_none + dpd_action = clear + } + } + version = 2 + proposals = aes256-sha256-x25519-ke1_mlkem768-ke1_mlkem512-ke1_none + dpd_delay = 60s +} diff --git a/tests/server/swanctl.conf b/tests/server/swanctl.conf new file mode 100644 index 0000000..e94ebf7 --- /dev/null +++ b/tests/server/swanctl.conf @@ -0,0 +1,33 @@ +connections { + + include rw.conf + include psk.conf + include eap.conf +} + +pools { + + rw_pool { + addrs = 10.3.0.0/24 + } +} + +secrets { + + ike-jane { + id = jane@strongswan.org + secret = 0sTtd7IOin6FuyjLsWtiM9o/1c + } + ike-hacker { + id = hacker@strongswan.org + secret = 0sH7+o6wysMoaELv5OBihKVa3F + } + eap-jane { + id = jane + secret = 3s9RFGdWE5EW + } + eap-hacker { + id = hacker + secret = K8FW9/N0VIAJ + } +} diff --git a/tests/server/x509/serverCert.pem b/tests/server/x509/serverCert.pem new file mode 100644 index 0000000..7e10213 --- /dev/null +++ b/tests/server/x509/serverCert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdjhAuCUYRAowCgYIKoZIzj0EAwMwNTELMAkGA1UEBhMC +Q0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMB4XDTI0 +MDMyMDE1MDEwNFoXDTI4MDMyMDE1MDEwNFowPTELMAkGA1UEBhMCQ0gxDjAMBgNV +BAoTBUN5YmVyMR4wHAYDVQQDExVzZXJ2ZXIuc3Ryb25nc3dhbi5vcmcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAASg6vN2xsiEnhYhyUsSaR/36nLeaFiWaQNWg2yDs1s7 +uUd1cV5blykLCLlZkWrsCevAUSd31bk0zwE5sejbmpr6QT/gx1vk0SX00X8J5fBJ +uWrc11t8zibT0M3DSizMkCKjWjBYMB8GA1UdIwQYMBaAFAxhe1pHX3+nOGD2J9K+ +unpr+npXMCAGA1UdEQQZMBeCFXNlcnZlci5zdHJvbmdzd2FuLm9yZzATBgNVHSUE +DDAKBggrBgEFBQcDATAKBggqhkjOPQQDAwNnADBkAjB9FEikOg5H7G0nLi32b76g +s/+hQc1bD76aUGlB9jMM0194Xv6np2WXW1vaJEcdPzICMFqJeIPbztLv5dXZ48vX +9jsOAxFfL5hF+noqP2XEyWWjdFoOdl2OOCItO6Vtgj5wFw== +-----END CERTIFICATE----- diff --git a/tests/server/x509ca/caCert.pem b/tests/server/x509ca/caCert.pem new file mode 100644 index 0000000..85ff961 --- /dev/null +++ b/tests/server/x509ca/caCert.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB3zCCAWWgAwIBAgIIY2hNABEgfdwwCgYIKoZIzj0EAwMwNTELMAkGA1UEBhMC +Q0gxDjAMBgNVBAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMB4XDTI0 +MDMyMDE1MDEwNFoXDTM0MDMyMDE1MDEwNFowNTELMAkGA1UEBhMCQ0gxDjAMBgNV +BAoTBUN5YmVyMRYwFAYDVQQDEw1DeWJlciBSb290IENBMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAEaBYrQANrXYQ18O9V2vKhBL7ovUm08g/R8wqFGvUe00bnvD/abQ/T +ITDhi/OYt2mw6TjCNGbcfoR4g4sc8nbm4SWCDklPCchiBUE3U038Q1pgurYil4SE +P9aN770ik4PGo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQUDGF7Wkdff6c4YPYn0r66emv6elcwCgYIKoZIzj0EAwMDaAAwZQIw +MbH3l4rQkFpr8Hh4yRBOn7BedBLgXehNXRpG15zHN+DmgGdZOQ5+3kiOjLTqBWYS +AjEA0WDLGsF3XSHCQfEWF5zyXomMpPdg8ZuqBHeSBJQMvmL4S+dfkLd/TP1L+R+7 +nQjn +-----END CERTIFICATE----- diff --git a/tests/strongswan.conf b/tests/strongswan.conf new file mode 100644 index 0000000..d5532d6 --- /dev/null +++ b/tests/strongswan.conf @@ -0,0 +1,23 @@ +# strongSwan configuration file + +charon { + start-scripts { + creds = swanctl --load-creds + conns = swanctl --load-conns + pools = swanctl --load-pools + } + filelog { + stderr { + default = 1 + } + } + eap-dynamic { + prefer_user = yes + preferred = md5, tls + } +} + +libtls { + version_max = 1.3 + suites = TLS_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384 +}