198 lines
4.8 KiB
Go
198 lines
4.8 KiB
Go
|
/*
|
||
|
Copyright 2022 CAcert Inc.
|
||
|
SPDX-License-Identifier: Apache-2.0
|
||
|
|
||
|
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 hsm_test
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"os/exec"
|
||
|
"path"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
|
||
|
"git.cacert.org/cacert-gosigner/pkg/config"
|
||
|
"git.cacert.org/cacert-gosigner/pkg/hsm"
|
||
|
)
|
||
|
|
||
|
func TestCaConfigOption(t *testing.T) {
|
||
|
testSignerConfig := config.SignerConfig{}
|
||
|
|
||
|
theContext := hsm.SetupContext(hsm.CaConfigOption(&testSignerConfig))
|
||
|
|
||
|
assert.Equal(t, &testSignerConfig, hsm.GetSignerConfig(theContext))
|
||
|
}
|
||
|
|
||
|
func TestGetSignerConfig_empty(t *testing.T) {
|
||
|
theContext := hsm.SetupContext()
|
||
|
|
||
|
assert.Nil(t, hsm.GetSignerConfig(theContext))
|
||
|
}
|
||
|
|
||
|
func TestSetupModeOption(t *testing.T) {
|
||
|
theContext := hsm.SetupContext(hsm.SetupModeOption())
|
||
|
|
||
|
assert.True(t, hsm.IsSetupMode(theContext))
|
||
|
}
|
||
|
|
||
|
func TestIsSetupMode_not_set(t *testing.T) {
|
||
|
theContext := hsm.SetupContext()
|
||
|
|
||
|
assert.False(t, hsm.IsSetupMode(theContext))
|
||
|
}
|
||
|
|
||
|
func TestVerboseLoggingOption(t *testing.T) {
|
||
|
theContext := hsm.SetupContext(hsm.VerboseLoggingOption())
|
||
|
|
||
|
assert.True(t, hsm.IsVerbose(theContext))
|
||
|
}
|
||
|
|
||
|
func TestIsVerbose_not_set(t *testing.T) {
|
||
|
theContext := hsm.SetupContext()
|
||
|
|
||
|
assert.False(t, hsm.IsVerbose(theContext))
|
||
|
}
|
||
|
|
||
|
const testSignerConfig = `---
|
||
|
Settings:
|
||
|
organization:
|
||
|
organization: ["Acme CAs Ltd."]
|
||
|
validity-years:
|
||
|
root: 30
|
||
|
intermediary: 10
|
||
|
url-patterns:
|
||
|
ocsp: http://ocsp.example.org/
|
||
|
crl: http://crl.example.org/%s.crl
|
||
|
issuer: http://%s.cas.example.org/
|
||
|
CAs:
|
||
|
root:
|
||
|
common-name: "Acme CAs root"
|
||
|
key-info:
|
||
|
algorithm: EC
|
||
|
ecc-curve: secp521r1
|
||
|
sub1:
|
||
|
common-name: "Acme CAs server sub CA"
|
||
|
parent: root
|
||
|
key-info:
|
||
|
algorithm: EC
|
||
|
ecc-curve: secp256r1
|
||
|
sub2:
|
||
|
common-name: "Acme CAs people sub CA"
|
||
|
parent: root
|
||
|
key-info:
|
||
|
algorithm: EC
|
||
|
ecc-curve: secp256r1
|
||
|
KeyStorage:
|
||
|
default:
|
||
|
type: softhsm
|
||
|
label: acme-test-hsm
|
||
|
`
|
||
|
|
||
|
func TestSetupContext(t *testing.T) {
|
||
|
testConfig, err := config.LoadConfiguration(strings.NewReader(testSignerConfig))
|
||
|
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
theContext := hsm.SetupContext(hsm.SetupModeOption(), hsm.VerboseLoggingOption(), hsm.CaConfigOption(testConfig))
|
||
|
|
||
|
assert.True(t, hsm.IsSetupMode(theContext))
|
||
|
assert.True(t, hsm.IsVerbose(theContext))
|
||
|
assert.Equal(t, hsm.GetSignerConfig(theContext), testConfig)
|
||
|
}
|
||
|
|
||
|
func TestGetP11Context_missing_SetupContext(t *testing.T) {
|
||
|
p11Context, err := hsm.GetP11Context(context.Background(), &config.CaCertificateEntry{Storage: "default"})
|
||
|
|
||
|
assert.Error(t, err)
|
||
|
assert.ErrorContains(t, err, "type assertion failed, use hsm.SetupContext first")
|
||
|
assert.Nil(t, p11Context)
|
||
|
}
|
||
|
|
||
|
func TestGetP11Context_unknown_storage(t *testing.T) {
|
||
|
testConfig, err := config.LoadConfiguration(strings.NewReader(testSignerConfig))
|
||
|
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
theContext := hsm.SetupContext(hsm.SetupModeOption(), hsm.CaConfigOption(testConfig))
|
||
|
|
||
|
definition := &config.CaCertificateEntry{Storage: "undefined"}
|
||
|
|
||
|
p11Context, err := hsm.GetP11Context(theContext, definition)
|
||
|
|
||
|
assert.Error(t, err)
|
||
|
assert.ErrorContains(t, err, "key storage undefined not available")
|
||
|
assert.Nil(t, p11Context)
|
||
|
}
|
||
|
|
||
|
func TestGetP11Context(t *testing.T) {
|
||
|
testConfig, err := config.LoadConfiguration(strings.NewReader(testSignerConfig))
|
||
|
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
tempdir := t.TempDir()
|
||
|
|
||
|
tokenDir := path.Join(tempdir, "tokens")
|
||
|
softhsmConfig := path.Join(tempdir, "softhsm2.conf")
|
||
|
|
||
|
err = os.Mkdir(tokenDir, 0o700)
|
||
|
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
err = os.WriteFile(softhsmConfig, []byte(fmt.Sprintf("directories.tokendir = %s", tokenDir)), 0o600)
|
||
|
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
t.Setenv("SOFTHSM2_CONF", softhsmConfig)
|
||
|
|
||
|
err = exec.Command(
|
||
|
"softhsm2-util",
|
||
|
"--init-token",
|
||
|
"--free",
|
||
|
"--label",
|
||
|
"acme-test-hsm",
|
||
|
"--so-pin",
|
||
|
"12345678",
|
||
|
"--pin",
|
||
|
"123456",
|
||
|
).Run()
|
||
|
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
t.Setenv("TOKEN_PIN_ACME_TEST_HSM", "123456")
|
||
|
|
||
|
theContext := hsm.SetupContext(hsm.CaConfigOption(testConfig))
|
||
|
|
||
|
definition, err := testConfig.GetCADefinition("root")
|
||
|
|
||
|
require.NoError(t, err)
|
||
|
|
||
|
p11Context1, err := hsm.GetP11Context(theContext, definition)
|
||
|
|
||
|
assert.NoError(t, err)
|
||
|
assert.NotNil(t, p11Context1)
|
||
|
|
||
|
p11Context2, err := hsm.GetP11Context(theContext, definition)
|
||
|
|
||
|
assert.NoError(t, err)
|
||
|
assert.NotNil(t, p11Context1)
|
||
|
assert.Equal(t, p11Context1, p11Context2)
|
||
|
}
|