FortiGate
FortiGate Next Generation Firewall utilizes purpose-built security processors and threat intelligence security services from FortiGuard labs to deliver top-rated protection and high performance, including encrypted traffic.
scollins
Staff
Staff
Article Id 262267
Description This article describes how to obtain a certificate on a FortiGate device using SCEP.
Scope FortiGate.
Solution

FortiGate supports the auto-enrollment of certificates using SCEP.

This can be done in 2 ways:

  1. Directly from the FortiGate device itself (via GUI or CLI).
  2. Using Certificate Templates on FortiManager.

 

This article will focus on the first option. A separate article exists for instructions on how to use FortiManager:

Technical Tip: Certificate Template with SCEP enrollment using FortiAuthenticator as external CA.

Note:

The beginning of the above article details how to enable SCEP on FortiAuthenticator, if using a FortiAuthenticator to serve SCEP requests this should be enabled otherwise requests will fail.

 

To create a certificate via the GUI and enroll with SCEP, go to System -> Certificates and select Generate CSR.

Fill in the necessary fields. On the enrollment method, select Online SCEP and fill in the fields correctly:

 

Untitled.png

 

Alternatively, the CLI can be used to do this:

 

execute vpn certificate local generate rsa IPSECVPNTest 2048 myvpn NL NH Amsterdam Fortinet "" ipsecvpntest@fortinet.com "" http://10.5.59.172/app/cert/scep/ <challenge_password>

 

Successful enrollment can be observed with the following debug:

 

diagnose debug application scep -1

diagnose debug enable

scep_parse_header: server returned status code 200
scep_parse_header: MIME header: application/x-x509-ca-cert
__process_ca_cert_reply: Reply type 1
__process_ca_cert_reply: loaded cacert
__read_ca_cert_cb: loaded signing cert
__read_ca_cert_cb: loaded CA
new_scep_transaction: transaction id: 2B9E443E5E0A9BA816785A1915AA2E99
pkcs7_wrap:1120 creating inner PKCS#7
pkcs7_wrap: data payload size: 775 bytes
pkcs7_wrap: successfully encrypted payload
pkcs7_wrap: envelope size: 1280 bytes
pkcs7_wrap: creating outer PKCS#7
pkcs7_wrap: signature added successfully
pkcs7_wrap: adding signed attributes
__add_attribute_string: adding string attribute transId
__add_attribute_string: adding string attribute messageType
__add_attribute_octet: adding octet attribute senderNonce
pkcs7_wrap: PKCS#7 data written successfully
pkcs7_wrap: applying base64 encoding
pkcs7_wrap: base64 encoded payload size: 3953 bytes
scep_parse_header: server returned status code 200
scep_parse_header: MIME header: x-pki-message
pkcs7_unwrap: reading outer PKCS#7
pkcs7_unwrap: PKCS#7 payload size: 756 bytes
pkcs7_unwrap: PKCS#7 contains 0 bytes of enveloped data
pkcs7_unwrap: verifying signature
pkcs7_unwrap: signature ok
pkcs7_unwrap: finding signed attributes
__get_attribute: finding attribute transId
__get_signed_attribute: allocating 32 bytes for attribute
pkcs7_unwrap: reply transaction id: 2B9E443E5E0A9BA816785A1915AA2E99
__get_attribute: finding attribute messageType
__get_signed_attribute: allocating 1 bytes for attribute
pkcs7_unwrap: reply message type is good
__get_attribute: finding attribute senderNonce
__get_signed_attribute: allocating 16 bytes for attribute
pkcs7_unwrap: senderNonce in reply: 65DCB45E9FCB8CBB4395C99D8B17BD92
__get_attribute: finding attribute recipientNonce
__get_signed_attribute: allocating 16 bytes for attribute
pkcs7_unwrap: recipientNonce in reply: 57E9E8B7D23E2912BCADE9BCACA90F08
__get_attribute: finding attribute pkiStatus
__get_signed_attribute: allocating 1 bytes for attribute
pkcs7_unwrap: pkistatus: PENDING
pkcs7_wrap:1138 creating issuer_and_subject PKCS#7
pkcs7_wrap: data payload size: 267 bytes
pkcs7_wrap: successfully encrypted payload
pkcs7_wrap: envelope size: 776 bytes
pkcs7_wrap: creating outer PKCS#7
pkcs7_wrap: signature added successfully
pkcs7_wrap: adding signed attributes
__add_attribute_string: adding string attribute transId
__add_attribute_string: adding string attribute messageType
__add_attribute_octet: adding octet attribute senderNonce
pkcs7_wrap: PKCS#7 data written successfully
pkcs7_wrap: applying base64 encoding
pkcs7_wrap: base64 encoded payload size: 3271 bytes
scep_parse_header: server returned status code 200
scep_parse_header: MIME header: x-pki-message
pkcs7_unwrap: reading outer PKCS#7
pkcs7_unwrap: PKCS#7 payload size: 5996 bytes
pkcs7_unwrap: PKCS#7 contains 2899 bytes of enveloped data
pkcs7_unwrap: verifying signature
pkcs7_unwrap: signature ok
pkcs7_unwrap: finding signed attributes
__get_attribute: finding attribute transId
__get_signed_attribute: allocating 32 bytes for attribute
pkcs7_unwrap: reply transaction id: 2B9E443E5E0A9BA816785A1915AA2E99
__get_attribute: finding attribute messageType
__get_signed_attribute: allocating 1 bytes for attribute
pkcs7_unwrap: reply message type is good
__get_attribute: finding attribute senderNonce
__get_signed_attribute: allocating 16 bytes for attribute
pkcs7_unwrap: senderNonce in reply: 976C51687F9263B79BF8CDF964136EF6
__get_attribute: finding attribute recipientNonce
__get_signed_attribute: allocating 16 bytes for attribute
pkcs7_unwrap: recipientNonce in reply: 40460901E83309A3022FF353C7EA1183
__get_attribute: finding attribute pkiStatus
__get_signed_attribute: allocating 1 bytes for attribute
pkcs7_unwrap: pkistatus: SUCCESS
pkcs7_unwrap: reading inner PKCS#7
pkcs7_unwrap: decrypting inner PKCS#7
pkcs7_unwrap: PKCS#7 payload size: 2384 bytes
scep_write_local_cert: found certificate with
subject: /ST=NH/L=Amsterdam/O=Fortinet/OU=AS/CN=myvpn/emailAddress=ipsecvpntest@fortinet.com
issuer: /C=NL/ST=NH/L=Amsterdam/O=Fortinet/OU=AS/CN=sceptest/emailAddress=sceptest@fortinet.com
scep_write_local_cert: writing cert
scep_write_local_cert: certificate written as /tmp/IPSECVPNTest

 

As of v7.0.4: if a certificate signing is made by an intermediate CA, the root certificate needs to be in the SCEP client certificate repository so that the intermediate CA's issuer can be checked. 

 

Once the certificate is successfully imported, the auto-regenerate option can be configured in the CLI if it is required. It will ensure that the certificate will automatically renew before expiry:
 

config vpn certificate local

    edit <name>

        set auto-regenerate-days {integer}

        set auto-regenerate-days-warning {integer}

    next

end

 

  • auto-regenerate-days: How many days before expiry does the unit request an updated local certificate. The default is 0, certificates are not renewed and expire.
  • auto-regenerate-days-warning: How many days before local certificate expiry the FortiGate generate a warning message. The default is 0, with no warning.

Once auto-regenerate-days is configured, FortiGate will send a renewal request for the expiring certificate configured amount of days before expiry.

 

If the CA does not respond or the request is rejected (e.g. due to the CA not accepting renewal requests too many days before expiry of the current certificate or not allowing renewals for expired certificates), FortiGate will try to continuously renew the certificate until a new certificate is issue with higher validity period than auto-regenerate days.

 

Note: If the certificate expires before successful renewal and the CA does not support renewing expired certificates, it is necessary to create a new CSR by following this KB and replace the relevant references in the FortiGate configuration.

 

Note: If auto-regenerate-days is misconfigured and does not comply with CA policies, FortiGate may send an excessive amount of renewal requests to the CA.

 

When a certificate is successfully renewed or generated using SCEP, a 'Certificate is loaded' log entry can be found on FortiGate VPN logs, which includes the certificate name.

 

Screenshot 2025-06-09 163638.png

 

Additionally, the General System Events log contains logs relevant to SCEP renewal.

'Successfully signed local certificate via SCEP' indicates renewal or enrollment has been completed.
'Failed to connect SCEP Server' indicates an issue with SCEP server connectivity
'Failed to sign local certificate via SCEP-(null)' indicates that FortiGate is able to contact the SCEP server, but the renewal or enrollment request is unsuccessful. A reason for the failure may be included. In case the reason stated is null, this can indicate the CA does not allow renewals this far in advance of expiry, it does not allow renewal of expired certificates or other reason specific to the CA. Logs on the SCEP server need to be examined to determine the exact reason.

 

The log action 'certificate-generate' displays all relevant FortiGate logs.

 

Screenshot 2025-06-09 164854.png