certificates: [Bug]: RA mode won't start up with Vault + SCEP

Steps to Reproduce

  1. Follow Vault RA mode setup docs.
  2. Start up the RA and confirm it’s working.
  3. Add a SCEP provisioner by running step ca provisioner add scepca --type SCEP --challenge "abc123" --encryption-algorithm-identifier 2
  4. Restart the RA.

Your Environment

  • OS -macOS
  • step-ca Version - 0.24.3-rc.5-144-gf9db22d3
  • step Version - CLI/0.24.2-rc.3-138-g01d4e9e8

Expected Behavior

I expected the RA to start up with a SCEP provisioner.

Actual Behavior

$ step-ca
badger 2023/09/26 14:14:37 INFO: All 1 tables opened in 0s
badger 2023/09/26 14:14:37 INFO: Replaying file id: 0 at offset: 8467
badger 2023/09/26 14:14:37 INFO: Replay took: 79.208µs
panic: runtime error: index out of range [0] with length 0

goroutine 1 [running]:
github.com/smallstep/certificates/authority.(*Authority).init(0x14000732280)
	/Users/carl/code/certificates/authority/authority.go:681 +0x28f0
github.com/smallstep/certificates/authority.New(0x140001d7180, {0x1400072aac0, 0x5, 0x1003869b8?})
	/Users/carl/code/certificates/authority/authority.go:140 +0xfc
github.com/smallstep/certificates/ca.(*CA).Init(0x1400072aa80, 0x140001d7180)
	/Users/carl/code/certificates/ca/ca.go:169 +0x520
github.com/smallstep/certificates/ca.New(0x140001d7180, {0x140006f3480, 0x7, 0x1029d8130?})
	/Users/carl/code/certificates/ca/ca.go:141 +0xe0
github.com/smallstep/certificates/commands.appAction(0x1400023f4a0)
	/Users/carl/code/certificates/commands/app.go:247 +0xcac
github.com/urfave/cli.HandleAction({0x1016efaa0?, 0x1019971c0?}, 0x5?)
	/Users/carl/go/pkg/mod/github.com/urfave/cli@v1.22.14/app.go:524 +0x58
github.com/urfave/cli.Command.Run({{0x101146044, 0x5}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x0, 0x0}, {0x1011c9454, ...}, ...}, ...)
	/Users/carl/go/pkg/mod/github.com/urfave/cli@v1.22.14/command.go:175 +0x4f0
main.main.func3(0x1400076ccd0?)
	/Users/carl/code/certificates/cmd/step-ca/main.go:201 +0x15c
github.com/urfave/cli.HandleAction({0x1016efaa0?, 0x140006f93e0?}, 0x1400012ca80?)
	/Users/carl/go/pkg/mod/github.com/urfave/cli@v1.22.14/app.go:524 +0x58
github.com/urfave/cli.(*App).Run(0x1400012ca80, {0x1400003a050, 0x1, 0x1})
	/Users/carl/go/pkg/mod/github.com/urfave/cli@v1.22.14/app.go:286 +0x548
main.main()
	/Users/carl/code/certificates/cmd/step-ca/main.go:204 +0x604

Additional Context

$ cat /Users/carl/.step/authorities/vault-test/config/ca.json
{
	"federatedRoots": null,
	"address": ":4443",
	"insecureAddress": ":3333",
	"dnsNames": [
		"localhost"
	],
	"logger": {
		"format": "text"
	},
	"db": {
		"type": "badgerv2",
		"dataSource": "/Users/carl/.step/authorities/vault-test/db",
		"badgerFileLoadingMode": ""
	},
	"authority": {
		"type": "vaultcas",
		"certificateAuthority": "http://127.0.0.1:8200",
		"certificateAuthorityFingerprint": "1edfb7fbdc0782f08893d972e359a7399a34b20d0dfcd446973ca461a265dfc7",
		"config": {
			"pkiMountPath": "pki_int1",
			"pkiRoleRSA": "rsa-role",
			"pkiRoleEC": "ec-role",
			"pkiRoleEd25519": "ed25519-role",
			"authType": "approle",
			"authMountPath": "approle",
			"namespace": "custom/vault/enterprise/namespace",
			"authOptions": {
				"roleID": "b9d4f032-4239-97b2-6198-1abe4c168bf5",
				"secretID": "82989f40-89a4-e77b-2810-a49149da33a1",
				"isWrappingToken": false
			}
		},
		"provisioners": [
			{
				"type": "JWK",
				"name": "carl@smallstep.com",
				"key": {
					"use": "sig",
					"kty": "EC",
					"kid": "UwxU8y4cw-Fg7gKbd8I76PYNiBYdGe6xlbCWcFH8atQ",
					"crv": "P-256",
					"alg": "ES256",
					"x": "u4kZJOGDIZnf2mY6963EffyHPMJAiZQnyvE1llpgZcM",
					"y": "jw4IAxplt49kz0WTcS6z7ji-YJuX-6gB6FNN6-sy8SA"
				},
				"encryptedKey": "eyJhbGciOiJQQkVTMi1IUzI1NitBMTI4S1ciLCJjdHkiOiJqd2sranNvbiIsImVuYyI6IkEyNTZHQ00iLCJwMmMiOjEwMDAwMCwicDJzIjoiY0otLWl1bXpCLWhCNlFOZHRSMWY1ZyJ9.GYOYWua8s5PVJXsqdwfffgI6CYpClRNlswtazvn62p29LQxRgJAItw.0Qgr4yGKCqJZemhD.nc7FzxBTsVafMlbuhdmITZZ_aJ9bOmsqrdWR6sdsqm1QhKjHIb4OdXuAb6z7JsBlsPsiv8yL4BNgsX2tH8vHE0lbU196De9rSEq8U7npr-pYO-WAy5ZG3Mdf8DPMyLVzg215fhH_kIoohDbuO1dxtqyVQuas2SEQ2RQe3maVMFbS9QfCjmuD8WiVIWfIsCyoybk4wvqFbq-7X9TRKJjIZLAqdvdAU5XkDG6VLJ0tapgub9A-HxyK_6TxtXwK8GTgox1rwTIteebReozm0gUj8dvEZRoYUZ0ADfBADww7A0EQPugG3OQ6r-MpD71B3kEkBDNQLZGR79Lu03m3x6I.VrkLEY7GFkcrpLAcuKIOPQ"
			},
			{
				"type": "ACME",
				"name": "acme"
			},
			{
				"type": "SCEP",
				"name": "scepca",
				"challenge": "abc123",
				"minimumPublicKeyLength": 2048,
				"encryptionAlgorithmIdentifier": 2,
				"options": {
					"x509": {},
					"ssh": {}
				},
				"claims": {
					"enableSSHCA": true,
					"disableRenewal": false,
					"allowRenewalAfterExpiry": false,
					"disableSmallstepExtensions": false
				}
			}
		],
		"template": {},
		"backdate": "1m0s"
	},
	"tls": {
		"cipherSuites": [
			"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
			"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
		],
		"minVersion": 1.2,
		"maxVersion": 1.3,
		"renegotiation": false
	},
	"commonName": "Step Online CA"
}

Contributing

Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you’ve opened one already).

About this issue

  • Original URL
  • State: open
  • Created 9 months ago
  • Reactions: 1
  • Comments: 21 (21 by maintainers)

Commits related to this issue

Most upvoted comments

@spieglt basically what @maraino describes above.

In the SCEP protocol clients encrypt messages to the CA (usually an RA, Registration Authority; and the RA communicates with the CA using some protocol). The “decrypter approach” refers to a configuration in which each SCEP provisioner can have its own “RSA decrypter certificate”. Clients can discover that decrypter certificate, and use it to encrypt messages to the public key. The SCEP provisioner decrypts the encrypted messages, incl. the CSR, and then makes the CAS sign the certificate using the intermediate key. In this setup, the SCEP provisioner with the decrypter cert operates as an RA in SCEP parlance; the CAS is the CA, and the protocol is effectively the CAS interface.

The reason that approach is likely to work and to be the simplest to support in your use case, is because the CAS interface does not need to provide a crypto.Decrypter (or a new function that provides for decryption), because the RSA decrypter certificate (+key) are used for that. So far, the CAS interface is focused on signing CSRs. But to support the SCEP protocol, it would need to support decryption operations too (or need an additional interface), if we were to use the same intermediate cert/key configured in the CAS for signing.

Okay, unfortunately I don’t understand much of that so I guess I have some more code to read. What is the “decrypter approach”? Having a working decrypter but not a working signer? And what is required for that? The Vault RA cert chain is RSA. How would I use the RSA decrypter configured as PEM cert + key while using Vault in RA mode? That question may not be coherent, apologies if so.

What I think @hslatman suggests is configuring the SCEP provisioner with an RSA certificate and key. This option was added a few weeks ago. You can see the fields here: https://github.com/smallstep/certificates/blob/7bfe11c68723194a583108e6cf984573459bda1e/authority/provisioner/scep.go#L47-L50

If you’re using step to configure the CA provisioner, step ca provisioner add has some extra flags to provide the decrypter, these are --scep-decrypter-certificate-file=<file> --scep-decrypter-key-file=<file>, --scep-decrypter-key-password-file=<file> and the still-experimental option --scep-decrypter-key-uri=<uri>.

I haven’t tested this configuration with VaultCAS, but I think it will work.

Hey @spieglt, started looking into it, but not much actual progress yet due to other priorities. This week I should have some more time available for this and other SCEP things.