Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for certificate renewal via SCEP #3413

Open
wants to merge 10 commits into
base: master
Choose a base branch
from

Conversation

borama
Copy link
Contributor

@borama borama commented Dec 16, 2020

Hello,

this is the last PR that I'm bringing here for your kind consideration. I've implemented this for a client and successfully tested it using a Cisco client.

This PR adds support for renewing a certificate via the SCEP protocol (the scep servlet). The renewal process tries to follow the new SCEP draft and has the following assumptions:

  • a SCEP request is recognized as a certificate renewal request when at least one of the following conditions is met:
    • the SCEP messageType is equal to 17, i.e. it is a RenewalReq message type
    • or the SCEP messageType is the same as in initial cert enrollment (19 = PKCSReq) but the SCEP message is signed with a cert issued by this CA, not with a self-signed cerfiticate
    • this second option is here intentionally to support clients that don't use message type 17 (i.e. don't obey the newest draft spec); Cisco was among them
  • the client must generate a PKCS10 request (as in initial cert enrollment), generate a new private key and sign the PKCS10 request with this key
  • however, the SCEP message must be signed with the previously issued certificate, not a self-signed certificate (as in initial enrollment) - i.e. the previous cert must be present in the SignerInfo structure of the SCEP message
  • this signing certificate must still be valid, i.e. not expired and not revoked
  • the newly issued certificate will be exactly the same as the previous one, except for:
    • the public key - this is taken from the PKCS10 request
    • the validity from / to - left for the CA to decide and set this freshly
  • the CA then issues a new certificate using the RENEWAL_REQUEST (see the postRenewalRequest method) and typically returns it to the client immediately

The feature can be switched on in the CS.cfg configuration file using:

ca.scep.enableRenewal=false

(by default this is false, i.e. renewal support is switched off).

SCEP message integrity checking

During implementing this I noticed that the integrity of the SCEP messages coming from the clients is not verified in the verifyRequest method in the servlet. Thus, I added an implementation of this verification as it is an essential part of the renewal process (the client is not authenticated via external means, e.g. a password, but only via previous certificate - we must make sure that the client possesses the private key for this signing cert). The SCEP verification works as follows (see the verify method in CRSPKIMessage):

  • it considers the SCEP message as a PKCS7 message and uses the appropriate method in the pkcs7 package
  • for this it computes the message digest of the data (the inner PKCS7 message) using the algorithm taken from the SignerInfo structure
  • if this verification passes, we have a proof that the SCEP message was signed using the cert from the SignerInfo structure and that the client possesses the corresponding private key.

Thus, in case of cert renewal, we can consider such a message as verified.

Please don't hesitate to contact me if you have any questions or need further work on this. Thanks!

@edewata edewata requested a review from ladycfu December 16, 2020 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant