certificates: SCEP from Cisco router failing (HTTP GET not implemented (correctly))
Subject of the issue
I am trying to use step-ca as SCEP server for my Cisco homelab. I am confident that Cisco implementation is working but step-ca complains about invalid base64 data in the request.
There seems to be a problem in the decoding of the HTTP GET request (it uses base64.URLEncoding which in case of Cisco should be base64.StdEncoding and I noticed that step-a dit not implement SCEP using HTTP GET requests for the PKIOperation in the Get handler.
I got it working with minor changes (merely reading the TODO and copying existing code), see below.
Please include my changes in the next version, or, at least, provide a proper error message when an SCEP client uses the PKIOperation method over HTTP GET. At this moment the client receives an status 200 with an empty response, which is not correct and not in line with the spec.
Your environment
- OS - Debian (Raspbian) 11.3 armv7
- Client: Cisco 1100 running IOS-XE 16.09
- step-ca version: 0.19.0
Steps to reproduce
working configuration (just run step ca init and add this provisioner to the configuration as per the documentation on configuration of a SCEP provisioner:
{
"type": "SCEP",
"name": "scepca",
"forceCN": true,
"challenge": "secret1234"
}
On the Cisco side I am using this configuration:
! generate an RSA key pair for the router
crypto key generate rsa label STEP-CA-KEY modulus 2048
! define a trustpoint for SCEP with step-ca
crypto pki trustpoint STEP-CA
enrollment retry count 100
enrollment retry period 60
enrollment url http://192.168.1.1:80/scep/stepca
serial-number none
fqdn router.mydomain.tld
subject-name CN=router.mydomain.tld,dc=mydomain,dc=tld
revocation-check none
rsakeypair STEP-CA-KEY
auto-enroll 10 regenerate
! Import the root CA fro the step-ca responder, this command requires confirmation
crypto pki authenticate STEP-CA
! and start the enrollment with step-ca
crypto pki enroll STEP-CA
Expected behaviour
The Cisco router requesst a certificate through a CSR via SCEP with step-ca and get a signed certificate which gets installed
Actual behaviour
Cisco performs a SCEP request with step-ca, which results in an error, according to the step-ca logfiles:
error="invalid scep get request: illegal base64 data at input byte 274"
Additional context
Diving into the issue, I can see the SCEP request from the Cisco (I am reluctant to include the whole so it is truncated) from the step-ca logs looks like this:
Apr 29 12:26:41 pi step-ca[24052]:
time="2022-04-29T12:26:41+02:00"
level=error
duration=1.095262ms
duration-ns=1095262
error="invalid scep get request: illegal base64 data at input byte 274"
fields.time="2022-04-29T12:26:41+02:00"
method=GET
name=ca
path="/scep/stepca/pkiclient.exe?operation=PKIOperation&message=MIIK1gYJKoZIhvcNAQcCoIIKxzCCCsMCAQExCzAJBgUrDgMCGgUAMIIF2wYJKoZI%0AhvcNAQcBoIIFzASCBcgwggXEBgkqhkiG9w0BBwOgggW1MIIFsQIBADGCAoQwggKA%0AAgEAMGgwUDELMAkGA1UEBhMCTkwxEjAQBgNVBAoTCUxpbmRlbmFhcjEtMCsGA1UE%0AAxMkTGluZGVuYWFyIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5AhQN4pYduaQM%0ApXqtsP3jCkQIsX%2F%2BJjANBgkqhkiG9w0BAQEFAASCAgBmD2uSKjx%2BZPNCnyhHxFNx%0A9Yy7W6L8mHY3tVODI1jLkS5%2BwRwEiQNxrCyYq0zkrkp%2FB8ssgNQaWMpW8zYZT0s3%0Ax28UxVJOfkiACN82O8XyI%2FyV%2B05uiPGwEkt202NNEKaZP7ze1IASxCJ2K4MBsJFC%0AvnfL9enAQl4dSwcXazeqf6SdlBFAPacYBcsHxetr4BRb%2BsF5XLzgCiGkaYeypvJ0%0Adif3qzovro09Url2KKbCzczw%2Fj3ONTlUFLgBNiHm8d80pLp%2FwEPRj34XmfKCwRBC%0AaTkLZDQWvBO%2B8AxcFoExO%2BGn%2BV7XdWxbWmG1Ey%2B6TC2BCX2Gd%2F1mIJJlk%2FuIRn0w%0ADeYQA%2FB3dyS95DFF1pTjAmPEeJ
[cut]
WtG94%0AjY0P7k9QVIxMFNGVrN4Shh8Y%2BegUC7lo%2BvbsJqhGMK5BQ9JP5ybr2oCTfv3wtoY1%0AtsZOXhvzgmPz3eEYvN9yrP7LKza9CtKkk89EfFVhkaKnqJISV8N%2BMeobCffT1He4%0Ayhb4JrhvU8988IowZ%2BeLza4kxsZnibD7rXlymTQDF8q04yqbtcamkrqj%0A"
protocol=HTTP/1.0
referer=
remote-address=192.168.0.1
request-id=c9lrqoccnn9psu3ug7rg
size=64
status=500
user-agent=
user-id=
the URLEncoded requests contains “%0A” (newline - this one seems to be ignored so problem) and also “%2F” and “%2B” (the ‘/’ and ‘+’ signs). The error turns out to be about these though they are perfectly valid in Base64 encoding but not in the currently used Base64 URL encoding variant.
Changing in function decodeRequest (scep/api/api.go line 154):
// TODO: verify this; it seems like it should be StdEncoding instead of URLEncoding
decodedMessage, err := base64.URLEncoding.DecodeString(message)
into
// TODO: verify this; it seems like it should be StdEncoding instead of URLEncoding
decodedMessage, err := base64. StdEncoding.DecodeString(message)
resolves this (though I am not sure whether other implementations may still need URLEncoding, potentially trying both would be better?).
This solves the problem with the invalid Base64 data but still does not make SCEP work from a Cisco.
Looking at tcpdump output for the requests it turns out that step-ca does not send any response back for the request from the Cisco. When performing the logged request from the command line step-ca simply closes the connection without a response. Looking in the code I see that in the Get handler in scep/api/api.go on line 88 step-ca does not do anything:
case opnPKIOperation:
// TODO: implement the GET for PKI operation? Default CACAPS doesn't specify this is in use, though
SCEP using HTTP GET is currently not supported at all, unfortunately this is not documented and the client is not informed and no error is visible about this anywhere. Fortunately, copying over the implementation from the Post handler below:
case opnPKIOperation:
res, err = h.PKIOperation(ctx, req)
seems to make it work (at least in my case) and allows a Cisco router to request a certificate using SCEP from step-ca
Could you please apply these changes to the next version as well? Thanks!
regards,
Frederik
About this issue
- Original URL
- State: open
- Created 2 years ago
- Comments: 22 (13 by maintainers)
@hslatman looking forward to this release, thanks!
I did some testing today with the
masterbranch today and can confirm the new fields indeed are included in the certificate with:I will try to play a bit more with the later today.
Hi @lindenaar,
I’ve just merged https://github.com/smallstep/certificates/pull/917, so in the next release the GET requests will be supported.
Do you happen to know what SCEP client your Cisco gear uses? I suspect it’s something closed source, but it may be based on some existing libraries and we may be able to use that instead to test more easily. Do you have some references to documentations where usage of FQDN, IP and the serial number are explained? I did find some mentions of the serial number here: https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/sec_conn_pki/configuration/15-mt/sec-pki-15-mt-book/sec-cert-enroll-pki.html.
@hslatman: Sorry for the delay in response, I will try to build a new version tomorrow and test it against an IOS-XE router.