-
Notifications
You must be signed in to change notification settings - Fork 157
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Credentialz-5 "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind." * Credz library "This code is a Contribution to the OpenConfig Feature Profiles project ("Work") made under the Google Software Grant and Corporate Contributor License Agreement ("CLA") and governed by the Apache License 2.0. No other rights or licenses in or to any of Nokia's intellectual property are granted for any other purpose. This code is provided on an "as is" basis without any warranties of any kind."
- Loading branch information
Showing
3 changed files
with
233 additions
and
0 deletions.
There are no files selected for viewing
55 changes: 55 additions & 0 deletions
55
feature/security/gnsi/credentialz/tests/hiba_authentication/README.md
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,55 @@ | ||
# Credentialz-5: Hiba Authentication | ||
|
||
## Summary | ||
|
||
Test that Credentialz properly configures (hiba) certificate authentication. | ||
|
||
|
||
## Procedure | ||
|
||
* Follow the instructions for setting up a [HIBA CA](https://github.com/google/hiba/blob/main/CA.md) | ||
* Set DUT allowed authentication types to only public key using gnsi.Credentialz | ||
* Create a user `testuser` (with no certificate at this point) | ||
* Set the AuthorizedPrincipalsCommand by setting the tool to `TOOL_HIBA_DEFAULT` | ||
|
||
* Perform the following tests and assert the expected result: | ||
* Case 1: Failure | ||
* Authenticate with the `testuser` username and the previously created public key via SSH | ||
* Assert that authentication has failed (because the DUT doesn't have the Hiba host certificate at this point) | ||
* Ensure that access rejects telemetry counter is incremented `/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:access-rejects` | ||
* Case 2: Success | ||
* Configure the dut with the Hiba host certificate. | ||
* Authenticate with the `testuser` username the previously created public key via SSH | ||
* Assert that authentication has been successful | ||
* Ensure telemetry values for version and created-on match the values set by | ||
RotateHostParameters for | ||
`/oc-sys:system/oc-sys:ssh-server/oc-sys:state:active-host-certificate-version` | ||
and | ||
`/oc-sys:system/oc-sys:ssh-server/oc-sys:state:active-host-certificate-created-on` | ||
* Ensure that access accept telemetry counters are incremented after successful login | ||
`/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:access-accepts` | ||
`/oc-sys:system/oc-sys:ssh-server/oc-sys:state:counters:last-access-accept` | ||
|
||
|
||
## OpenConfig Path and RPC Coverage | ||
|
||
The below yaml defines the OC paths intended to be covered by this test. OC paths used for test setup are not listed here. | ||
|
||
```yaml | ||
paths: | ||
## State Paths ## | ||
/system/ssh-server/state/active-host-certificate-version: | ||
/system/ssh-server/state/active-host-certificate-created-on: | ||
/system/ssh-server/state/counters/access-accepts: | ||
/system/ssh-server/state/counters/last-access-accept: | ||
/system/ssh-server/state/counters/access-rejects: | ||
|
||
rpcs: | ||
gnsi: | ||
credentialz.v1.Credentialz.RotateHostParameters: | ||
``` | ||
## Minimum DUT platform requirement | ||
N/A |
163 changes: 163 additions & 0 deletions
163
feature/security/gnsi/credentialz/tests/hiba_authentication/hiba_authentication_test.go
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,163 @@ | ||
// Copyright 2024 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package hibaauthentication | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"testing" | ||
"time" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
"github.com/openconfig/featureprofiles/internal/security/credz" | ||
"github.com/openconfig/ondatra/gnmi" | ||
|
||
"github.com/openconfig/featureprofiles/internal/deviations" | ||
"github.com/openconfig/featureprofiles/internal/fptest" | ||
cpb "github.com/openconfig/gnsi/credentialz" | ||
"github.com/openconfig/ondatra" | ||
) | ||
|
||
const ( | ||
username = "testuser" | ||
hostCertificateVersion = "v1.0" | ||
) | ||
|
||
var ( | ||
hostCertificateCreatedOn = time.Now().Unix() | ||
) | ||
|
||
func TestMain(m *testing.M) { | ||
fptest.RunTests(m) | ||
} | ||
|
||
func TestCredentialz(t *testing.T) { | ||
dut := ondatra.DUT(t, "dut") | ||
target := credz.GetDutTarget(t, dut) | ||
|
||
// Create temporary directory for storing ssh keys/certificates. | ||
dir, err := os.MkdirTemp("", "") | ||
if err != nil { | ||
t.Fatalf("creating temp dir, err: %s", err) | ||
} | ||
defer func(dir string) { | ||
err = os.RemoveAll(dir) | ||
if err != nil { | ||
t.Logf("error removing temp directory, error: %s", err) | ||
} | ||
}(dir) | ||
|
||
credz.CreateHibaKeys(t, dir) | ||
credz.SetupUser(t, dut, username) | ||
|
||
// Set only public key authentication for our test. | ||
credz.RotateAuthenticationTypes(t, dut, []cpb.AuthenticationType{ | ||
cpb.AuthenticationType_AUTHENTICATION_TYPE_PUBKEY, | ||
}) | ||
|
||
// Setup hiba for authorized principals command. | ||
credz.RotateAuthorizedPrincipalCheck(t, dut, cpb.AuthorizedPrincipalCheckRequest_TOOL_HIBA_DEFAULT) | ||
|
||
t.Run("auth should fail hiba host certificate not present", func(t *testing.T) { | ||
var startingRejectCounter uint64 | ||
if !deviations.SSHServerCountersUnsupported(dut) { | ||
startingRejectCounter, _ = credz.GetRejectTelemetry(t, dut) | ||
} | ||
|
||
// Verify ssh with hiba fails as expected. | ||
_, err := credz.SSHWithCertificate(t, target, username, fmt.Sprintf("%s/users", dir)) | ||
if err == nil { | ||
t.Fatalf("Dialing ssh succeeded, but we expected to fail") | ||
} | ||
|
||
if !deviations.SSHServerCountersUnsupported(dut) { | ||
endingRejectCounter, _ := credz.GetRejectTelemetry(t, dut) | ||
if endingRejectCounter <= startingRejectCounter { | ||
t.Fatalf("SSH server reject counter did not increment after unsuccessful login. startCounter: %v, endCounter: %v", startingRejectCounter, endingRejectCounter) | ||
} | ||
} | ||
}) | ||
|
||
t.Run("auth should succeed ssh public key authorized for user with hiba granted certificate", func(t *testing.T) { | ||
// Push host key/certificate to the dut. | ||
credz.RotateAuthenticationArtifacts(t, | ||
dut, | ||
fmt.Sprintf("%s/hosts", dir), | ||
fmt.Sprintf("%s/hosts", dir), | ||
hostCertificateVersion, | ||
uint64(hostCertificateCreatedOn), | ||
) | ||
|
||
// Setup trusted user ca on the dut. | ||
credz.RotateTrustedUserCA(t, dut, dir) | ||
|
||
var startingAcceptCounter, startingLastAcceptTime uint64 | ||
if !deviations.SSHServerCountersUnsupported(dut) { | ||
startingAcceptCounter, startingLastAcceptTime = credz.GetAcceptTelemetry(t, dut) | ||
} | ||
|
||
_, err := credz.SSHWithCertificate(t, target, username, fmt.Sprintf("%s/users", dir)) | ||
if err != nil { | ||
t.Fatalf("Dialing ssh failed, but we expected to succeed, errror: %s", err) | ||
} | ||
|
||
// Verify ssh counters. | ||
if !deviations.SSHServerCountersUnsupported(dut) { | ||
endingAcceptCounter, endingLastAcceptTime := credz.GetAcceptTelemetry(t, dut) | ||
if endingAcceptCounter <= startingAcceptCounter { | ||
t.Fatalf("SSH server accept counter did not increment after successful login. startCounter: %v, endCounter: %v", startingAcceptCounter, endingAcceptCounter) | ||
} | ||
if startingLastAcceptTime == endingLastAcceptTime { | ||
t.Fatalf("SSH server accept last timestamp did not update after successful login. Timestamp: %v", endingLastAcceptTime) | ||
} | ||
} | ||
|
||
// Verify host certificate telemetry. | ||
sshServer := gnmi.Get(t, dut, gnmi.OC().System().SshServer().State()) | ||
gotHostCertificateVersion := sshServer.GetActiveHostCertificateVersion() | ||
if !cmp.Equal(gotHostCertificateVersion, hostCertificateVersion) { | ||
t.Fatalf( | ||
"Telemetry reports host certificate version is not correct\n\tgot: %s\n\twant: %s", | ||
gotHostCertificateVersion, hostCertificateVersion, | ||
) | ||
} | ||
gotHostCertificateCreatedOn := sshServer.GetActiveHostCertificateCreatedOn() | ||
if !cmp.Equal(time.Unix(0, int64(gotHostCertificateCreatedOn)), time.Unix(hostCertificateCreatedOn, 0)) { | ||
t.Fatalf( | ||
"Telemetry reports host certificate created on is not correct\n\tgot: %d\n\twant: %d", | ||
gotHostCertificateCreatedOn, hostCertificateCreatedOn, | ||
) | ||
} | ||
}) | ||
|
||
t.Cleanup(func() { | ||
// Cleanup to remove previous policy which only allowed key auth to make sure we don't leave dut in a | ||
// state where we can't reset config for further tests. | ||
credz.RotateAuthenticationTypes(t, dut, []cpb.AuthenticationType{ | ||
cpb.AuthenticationType_AUTHENTICATION_TYPE_PASSWORD, | ||
cpb.AuthenticationType_AUTHENTICATION_TYPE_PUBKEY, | ||
cpb.AuthenticationType_AUTHENTICATION_TYPE_KBDINTERACTIVE, | ||
}) | ||
|
||
// Remove user ca so subsequent fail cases work. | ||
credz.RotateTrustedUserCA(t, dut, "") | ||
|
||
// Clear hiba for authorized principals command. | ||
credz.RotateAuthorizedPrincipalCheck(t, dut, cpb.AuthorizedPrincipalCheckRequest_TOOL_UNSPECIFIED) | ||
|
||
// Remove host artifacts from the dut. | ||
credz.RotateAuthenticationArtifacts(t, dut, "", "", "", 0) | ||
}) | ||
} |
15 changes: 15 additions & 0 deletions
15
feature/security/gnsi/credentialz/tests/hiba_authentication/metadata.textproto
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,15 @@ | ||
# proto-file: github.com/openconfig/featureprofiles/proto/metadata.proto | ||
# proto-message: Metadata | ||
|
||
uuid: "4083a01e-9b52-44c0-aa5c-994e78be66fe" | ||
plan_id: "Credentialz-5" | ||
description: "Hiba Authentication" | ||
testbed: TESTBED_DUT | ||
platform_exceptions: { | ||
platform: { | ||
vendor: NOKIA | ||
} | ||
deviations: { | ||
ssh_server_counters_unsupported: true | ||
} | ||
} |