SCEP certificate enrollment - packet analysis


1. CA cert request:

Enrolling device requests and installs CA cert.

SCEP Opertion: GetCACert

HTTP Header:

GET /CertSrv/mscep/mscep.dll/pkiclient.exe?operation=GetCACert&message=SCEPLab HTTP/1.0
Host: 10.0.0.6



2. SCEP server returns the CA cert:

In the case of GET operation with a type of GetCACert, the MIME content type returned will 
depend on whether or not an RA is in use. If there is no RA, only the CA certificate is sent back in the response, and the response has the content type tagged as application/x-x509-ca-cert.
If there is an RA, as it is the case in this lab, the RA certificates are sent back together with the CA certificates. The content type is application/x-x509-ca-ra-cert.


HTTP Header:

HTTP/1.1 200 OK
Content-Length: 4170
Content-Type: application/x-x509-ca-ra-cert
Server: Microsoft-IIS/8.0
Date: Mon, 29 Apr 2013 09:15:51 GMT
Connection: close



3. Device requests an identity certificate:

SCEP Operation: PKIOperation

HTTP Header (message string has been truncated):

GET /CertSrv/mscep/mscep.dll/pkiclient.exe?operation=PKIOperation&message=MIITnyeD%0%3D%3D%0A HTTP/1.0
Host: 10.0.0.6



4. SCEP server returns identity cert:

For each GET operation, the CA/RA server will return a MIME object via HTTP. For a GET operation with PKIOperation as its type, the response is tagged as having a Content Type of application/x-pki-message. The body of this message is a BER encoded binary PKI message.

HTTP Header:

HTTP/1.1 200 OK
Content-Length: 2067
Content-Type: application/x-pki-message
Server: Microsoft-IIS/8.0
Date: Mon, 29 Apr 2013 10:46:51 GMT
Connection: close



SCEP Reference: http://www.cisco.com/warp/public/cc/pd/sqsw/tech/scep_wp.htm

Enrolling Cisco ASA for certificates via SCEP


1. Install CA cert

ciscoasa(config)# crypto ca trustpoint CA
ciscoasa(config-ca-trustpoint)# revocation-check crl
ciscoasa(config-ca-trustpoint)# enrollment url http://10.0.0.6/certsrv/mscep/mscep.dll
ciscoasa(config)# crypto ca authenticate CA 

Debug output:


CRYPTO_PKI: HTTP response header:
HTTP/1.1 200 OK
Content-Length: 4170
Content-Type: application/x-x509-ca-ra-cert
Server: Microsoft-IIS/8.0
Date: Mon, 29 Apr 2013 11:13:14 GMT
Connection: close

Content-Type indicates we have received CA and RA certificates.

CRYPTO_PKI:crypto_process_ca_ra_cert(trustpoint=CA)

INFO: Certificate has the following attributes:

Fingerprint:     537adc87 22cc6e2b 07fdf2e0 18d8ba8b
The PKCS #7 message contains 4 certificates.

CRYPTO_PKI:crypto_pkcs7_extract_ca_cert found cert
CRYPTO_PKI: transaction GetCACert completed
CRYPTO_PKI: CA certificate received.
CRYPTO_PKI: crypto_pki_authenticate_tp_cert()
CRYPTO_PKI: trustpoint CA authentication status = 0
Trustpoint 'CA' is a subordinate CA and holds a non self-signed certificate.
Trustpoint CA certificate accepted.
CRYPTO_PKI: Verifying certificate with serial number: 4D00000002924DEC093140270B000000000002, subject name: cn=IssuingCA-DC1,dc=kp,dc=local, issuer_name: cn=ORCA1-CA, signature alg: SHA1/RSA.


2. Request and install identity certificate:

Depending on SCEP server configuration, a challenge password may be required to obtain certificate  In Microsoft's SCEP implementation - NDES - we browse to 
http://scepserver /CertSrv/mscep_admin to obtain the password


ASA config:


ciscoasa(config)# crypto ca trustpoint CA
ciscoasa(config-ca-trustpoint)# keypair testKey
ciscoasa(config-ca-trustpoint)#password C972703054ED1301
ciscoasa(config)# crypto ca enroll CA


% Start certificate enrollment ..
% The fully-qualified domain name in the certificate will be: ciscoasa.kp.local
% Include the device serial number in the subject name? [yes/no]: yes
% The serial number in the certificate will be: 123456789AB
Request certificate from CA? [yes/no]: yes


Debug output:


CRYPTO_PKI: Found a subject match - inserting the following cert record into certList
CRYPTO_PKI: Found a subject match - inserting the following cert record into certList
CRYPTO_PKI: Found a subject match - inserting the following cert record into certListThe certificate has been granted by CA!


Linux certificate storage


As opposed to Windows, Linux doesn't have crypto APIs that would be usable by user-mode applications. Linux does have Kernel level CryptoAPI (crypto.h) which is accessible to kernel mode processes. As such applications store certificates in application specific locations. That way we end up with multiple copies of the same certificate. One way to workaroud is to designate a directory for certificate storage and create symbolic links in required directories. 

The Linux Kernel Cryptographic API overview: https://thesweeheng.files.wordpress.com/2007/11/6451.pdf


Generate CSR using a new key pair:

openssl req -nodes -newkey rsa:1024 -keyout serverName.key -out serverName.csr

Generate CSR using an existing key pair:

openssl req -new -key serverName.key -out serverName.csr


Once the request is signed, certs and keypair must be copied to relevant location. Most Linux applications require Base64 encoded certificate with .PEM extension. This however may vary. Apache for example requires Base64 encoded .CRT certificate. 

Sample storage locations:

Cisco AnyConnect:

User certs:

~/.cisco/certificates/ca                  Root CA
~/.cisco/certificates/client               User certificate 
~/.cisco/certificates/client/private       PrivateKeys


Computer certs:

/opt/.cisco/certificates/ca                    Root CA
/opt/.cisco/certificates/client                Client certificates 
/opt/.cisco/certificates/client/private    PrivateKeys


Nessus:

/opt/nessus/com/nessus/CA/servercert.pem 
/opt/nessus/var/nessus/CA/serverkey.pem


Apache:

Locations of cert and private key are specified in the config file (sample config below) per virtual host. Sample location:

/etc/httpd/conf/ssl.crt/serverName.crt
/etc/httpd/conf/ssl.key/serverName.key

Enabling SSL in Apache. 

Enable mod_ssl:

# e2enmod ssl

Configure Virtual Host:

This is configured in an httpd.conf or apache2.conf (which by default includes httpd.conf)


DocumentRoot /var/www/
ServerName 10.0.0.20
SSLEngine on
SSLCertificateFile /etc/apache2/conf/ssl.crt/10.0.0.20.crt
SSLCertificateKeyFile /etc/apache2/conf/ssl.key/10.0.0.20.key


Restart  service:

# service httpd restart

or

# apachectl -restart

OCSP certificate validation - packet analysis

Online Certificate Status Protocol (OCSP) is an IETF standard defined in RFC 2560 (http://www.ietf.org/rfc/rfc2560.txt). OCSP is used for real-time certificate status checking. OCSP uses HTTP as its transport mechanism. Transaction consists of an HTTP query using an HTTP POST verb and an HTTP 200 response. 

1. OCSP request (MIME type: ocsp-request):

HTTP header:

POST /ocsp HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: no-cache
Content-Type: application/ocsp-request
Accept: */*
User-Agent: Microsoft-CryptoAPI/6.2
Content-Length: 86
Host: srv3.kp.local

The request contains hash of the issuer's name and public key along with the serial number of the certificate to be validated:



2. OCSP response (MIME type: ocsp-response): 

HTTP header:

HTTP/1.1 200 OK

Cache-Control: max-age=580
Content-Length: 1256
Content-Type: application/ocsp-response
Expires: Mon, 22 Apr 2013 10:34:16 GMT
Last-Modified
: Mon, 22 Apr 2013 08:59:16 GMT

ETag: "407c5206fbf20cfa69f6110435a82fd4"
Server: Microsoft-IIS/8.0
Date: Mon, 22 Apr 2013 09:59:35 GMT


OCSP response contains the revocation status 


To prevent spoofing attacks, the response is signed by the responder. In order to validate the signature, certificate containing public key of the responder is returned. This could lead to a problem whereby OCSP signing certificate revocation would be checked leading to a "verification loop". According to the RFC's 2560 section 4.2.2.2.1 there are three ways of overcoming this issue. Microsoft CA implementation uses special extension "id-pkix-ocsp-nochek". This extention tells the requester not to validate status of the OCSP signing certificate. The risk of the certificate being misused is mitigated by using very short certificate validity periods. 


OCSP signing certificate:



Corresponding OCSP responder signing configuration:



CRL request over HTTP - packet analysis

One of the ways a CRL can be retrieved is HTTP. Whole transaction consists of an HTTP GET and an OK 200 response packets. The response is a PKIX-CRL MIME type encoded CRL. PKIX-CRL is an IETF standard defined in RFC 2585 http://www.ietf.org/rfc/rfc2585.txt

1. CRL requester generates an HTTP query using an HTTP GET verb

HTTP header:

GET /pki/IssuingCA-DC1.crl HTTP/1.1
Cache-Control: no-cache
Connection: Keep-Alive
Pragma: no-cache
Accept: */*
User-Agent: Microsoft-CryptoAPI/6.2
Host: dc1.kp.local



2. Server responds with CRL encoded in PKIX-CRL MIME type

HTTP header:

HTTP/1.1 200 OK
Content-Type: application/pkix-crl
Last-Modified: Mon, 22 Apr 2013 08:29:51 GMT
Accept-Ranges: bytes
ETag: "d06e258f333fce1:0"
Server: Microsoft-IIS/8.0
X-Powered-By: ASP.NET
Date: Sun, 21 Apr 2013 08:46:23 GMT
Content-Length: 820




WireShark decodes the PKIX-CRL. We can see all CRL extensions directly in the packet.

Cisco ASA Certificate Revocation Checking


ASA supports status verification using CRLs and OCSP. CRL can be retrieved using HTTP, LDAP or SCEP.

Revocation checking using CRL:

Over HTTP:

ciscoasa(config)# crypto ca trustpoint ASDM_TrustPoint2
ciscoasa(config-ca-trustpoint)# revocation-check crl
ciscoasa(config-ca-crl)# protocol http

By default ASA will use address listed in CDP extension of the certificate that is being validated. To override default behaviour we need to add the following in the CRL configuration context.

ciscoasa(config-ca-crl)# policy static
ciscoasa(config-ca-crl)# url 1 http://cdpurl.kp.local/crl.crl


Over LDAP:

Certificate I'm using for this lab, doesn't have LDAP address in its CDP extension. Therefore I'm using "policy static"  to specify LDAP URL where CRL can be retrieved. 

ciscoasa(config)# crypto ca trustpoint ASDM_TrustPoint2
ciscoasa(config-ca-trustpoint)# revocation-check crl
ciscoasa(config-ca-trustpoint)# crl configure
ciscoasa(config-ca-crl)# protocol ldap
ciscoasa(config-ca-crl)# policy static

ciscoasa(config-ca-crl)# url 1 ldap://dc1.kp.local/CN=IssuingCA-DC1,CN=dc1,CN=CDP,CN=Public%20Key%20Services,CN=Services,CN=Configuration,DC=kp,DC=local/

ciscoasa(config-ca-crl)# ldap-dn CN=asacrl,OU=UsersRoot,DC=kp,DC=local password

ciscoasa(config-ca-crl)# ldap-defaults 10.0.0.7


Revocation checking using OCSP:

ciscoasa(config)# crypto ca trustpoint ASDM_TrustPoint2
ciscoasa(config-ca-trustpoint)# revocation-check ocsp
ciscoasa(config-ca-trustpoint)# ocsp url http://srv3.kp.local/ocsp


View CRL cache:


ciscoasa# show crypto ca crl

CRL Issuer Name:
    cn=IssuingCA-DC1,dc=kp,dc=local
    LastUpdate: 15:23:47 UTC Apr 11 2013
    NextUpdate: 03:43:47 UTC Apr 19 2013
    Cached Until: 14:54:45 UTC Apr 15 2013
    Retrieved from CRL Distribution Point:
      http://dc1.kp.local/pki/IssuingCA-DC1.crl
    Size (bytes): 716
    Associated Trustpoints: ASDM_TrustPoint0


Enable crypto transaction debugging:

ciscoasa# debug crypto ca transactions 10


Retrieve CRL: 


ciscoasa(config)#crypto ca crl request ASDM_TrustPoint0

CRYPTO_PKI: CRL is being polled from CDP http://dc1.kp.local/pki/IssuingCA-DC1.crl.

CRYPTO_PKI: HTTP response header:
 HTTP/1.1 200 OK
Content-Type: application/pkix-crl
Last-Modified: Thu, 11 Apr 2013 15:33:47 GMT
Accept-Ranges: bytes
ETag: "edeaef5c936ce1:0"
Server: Microsoft-IIS/8.0
X-Powered-By: ASP.NET
Date: Mon, 15 Apr 2013 13:50:57 GMT
Connection: close
Content-Length: 716

CRYPTO_PKI: Found a subject match - inserting the following cert record into certList
CRYPTO_PKI: set CRL update timer with delay: 309171
CRYPTO_PKI: the current device time: 13:50:56 UTC Apr 15 2013

CRYPTO_PKI: the last CRL update time: 15:23:47 UTC Apr 11 2013
CRYPTO_PKI: the next CRL update time: 03:43:47 UTC Apr 19 2013
CRYPTO_PKI: CRL cache delay being set to: 3600000
CRYPTO_PKI: transaction HTTPGetCRL completed


Debug output of certificate validation using CRL:

CRYPTO_PKI: Verifying certificate with serial number: 4D00000002924DEC093140270B000000000002, subject name: cn=IssuingCA-DC1,dc=kp,dc=local, issuer_name: cn=ORCA1-CA, signature alg: SHA1/RSA.

CRYPTO_PKI(Cert Lookup) issuer="cn=ORCA1-CA" serial number=4d 00 00 00 02 92 4d ec 09 31 40 27 0b 00 00 00    
CRYPTO_PKI: Cerificate is resident.
CRYPTO_PKI: Verify chain of certs, Getting public key from signersCert.
CRYPTO_PKI: Sorted chain size is: 1
CRYPTO_PKI: Found ID cert. serial number: 6D000000075A2D9B4FE8E34DF7000000000007, subject name: ea=jd@kp.local,cn=Joe Doe
CRYPTO_PKI: Verifying certificate with serial number: 6D000000075A2D9B4FE8E34DF7000000000007, subject name: ea=jd@kp.local,cn=Joe Doe, issuer_name: cn=IssuingCA-DC1,dc=kp,dc=local, signature alg: SHA1/RSA.
CRYPTO_PKI(Cert Lookup) issuer="cn=IssuingCA-DC1,dc=kp,dc=local" serial number=6d 00 00 00 07 5a 2d 9b 4f e8 e3 4d f7 00 00 00                                   |  ...

CRYPTO_PKI: Starting CRL revocation check.
CRYPTO_PKI: Attempting to find cached CRL for CDP http://dc1.kp.local/pki/IssuingCA-DC1.crl
CRYPTO_PKI: Found CRL in cache for CDP: http://dc1.kp.local/pki/IssuingCA-DC1.crl, status 0.
CRYPTO_PKI: Certificate is revoked!


Debug output of certificate validation using OCSP:


CRYPTO_PKI: Sorted chain size is: 2
CRYPTO_PKI: Verifying certificate with serial number: 4D00000002924DEC093140270B000000000002, subject name: cn=IssuingCA-DC1,dc=kp,dc=local, issuer_name: cn=ORCA1-CA, signature alg: SHA1/RSA.
CRYPTO_PKI(Cert Lookup) issuer="cn=ORCA1-CA" serial number=4d 00 00 00 02 92 4d ec 09 31 40 27 0b 00 00 00   
CRYPTO_PKI: Cerificate is resident.

CRYPTO_PKI: Verify chain of certs, Getting public key from signersCert.

CRYPTO_PKI: Sorted chain size is: 1
CRYPTO_PKI: Found ID cert. serial number: 6D000000075A2D9B4FE8E34DF7000000000007, subject name: ea=jd@kp.local,cn=Joe Doe
CRYPTO_PKI: Verifying certificate with serial number: 6D000000075A2D9B4FE8E34DF7000000000007, subject name: ea=jd@kp.local,cn=Joe Doe, issuer_name: cn=IssuingCA-C1,dc=kp,dc=local, signature alg: SHA1/RSA.

CRYPTO_PKI(Cert Lookup) issuer="cn=IssuingCA-DC1,dc=kp,dc=local" serial number=6d00 00 00 07 5a 2d 9b 4f e8 e3 4d f7 00 00 00
CRYPTO_PKI: Verify cert is polling for revocation status.

CRYPTO_PKI: Starting OCSP revocation
CRYPTO_PKI: no responder matching this URL; create one!
CRYPTO_PKI: http connection opened
CRYPTO_PKI: OCSP response status - unauthorized.
CRYPTO_PKI: transaction GetOCSP completed

Managing Certificate Revocation Lists (CRLs) in Windows


Publish CRL to LDAP store:

C:\> certutil -dspublish .\IssuingCA-DC1.crl serverName

Validate certificate's Authority Information Access (AIA), Certificate Revocation List (CRL), Online Certificate Status Protocol (OCSP) status:

C:\>certutil -URL certname.cer

This command launches below UI that can be used to check the following:

Note: the certificate in question is revoked

Authority Information Access (AIA) - this extension specify location where CA certificates are located ( used for building certification path):




CRL accessibility based on CRL Distribution Point (CDP) extension:




Revocation status using OCSP:


OCSP URL is specified in AIA extension:


Download CRL (creates file "Blob0_1_0.crl" in working directory):

C:\> certutil-split  -URL http://dc1.kp.local/pki/IssuingCA-DC1.crl

View CRL publication related registry entries:

C:\> certutil -getreg ca\CRLPublicationURLs

Verify revocation and validity of a specific certificate:

C:\> certutil -f -urlfetch -verify .\compcert.cer


View CRL cached by CryptoAPI:

Windows CryptoAPI caches CRL for performance reasons.

C:\> certutil -urlcache CRL

Update local CRL cache / View CRL:

Command below forces update of CRL cache.



Digital Certificate Encoding types

Privacy Enhanced Mail (PEM) format

.cer / .pem     

- Base-64 encoded ASCII files 
- can be open  in a text editor
- Can contain certificates and private keys

Distinguished Encoding Rules (DER) format

.cer  / .crt / .der

- Binary encoded 
- Hash of the file matches certificate's thumbprint
- Susceptible to corruption due to binary format 
            (single bit change will invalidate cert as the hash won't match)


Public Key Cryptography Standards (PKCS)

Cryptographic Message Syntax Standard   - PKCS#7

.p7b / .p7c 

- Binary encoded format
- Can include whole certification path
- Cannot contain private keys


Personal Information Exchange - PKCS#12

.pfx / .p12
- Passphrase protected
- Can contain private keys
- Can include whole certification path



References:

https://www.sslshopper.com/ssl-converter.html

http://technet.microsoft.com/en-us/library/cc738545(v=ws.10).aspx

This is very low level Windows API stuff:




Enrolling Cisco ASA for certificates via terminal

This procedure is largely the same as in IOS.


Generate Keys:

ciscoasa(config)# crypto key generate rsa general-keys modulus 1024
INFO: The name for the keys will be:
Keypair generation process begin. Please wait...


Verify keys have been generated:

ciscoasa(config)# show crypto key mypubkey rsa
Key pair was generated at: 14:56:09 UTC Apr 5 2013
Key name:
 Usage: General Purpose Key
 Modulus Size (bits): 1024
 Key Data:

  30819f30 0d06092a 864886f7 0d010101 05000381 8d003081 89028181 00c0a355



Create trustpoint for root CA:

ciscoasa(config)# crypto ca trustpoint ORCA1-CA
ciscoasa(config-ca-trustpoint)# enrollment terminal

ciscoasa(config)# crypto ca authenticate ORCA1-CA
Enter the base 64 encoded CA certificate.
End with the word "quit" on a line by itself
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

quit

INFO: Certificate has the following attributes:
Fingerprint:     e9fd8a22 e82c13ef 5db781a7 616ad113
Do you accept this certificate? [yes/no]: yes

Trustpoint CA certificate accepted.

% Certificate successfully imported

While IOS shows both MD5 and SHA1 fingerprints, ASA shows only MD5. My certificate template is configured to use SHA1 as hashing algorithm. In order to compare the thumbprints, I had to use an external hashing utility. I used MD5Summer. We need to hash the certificate in .CRT  or binary .CER format (binary DER – Distinguished Encoding Rules - encoded).  




Create truspoint for subordinate CA:

ciscoasa(config)# crypto ca trustpoint IssuingCA-DC1
ciscoasa(config-ca-trustpoint)# enrollment terminal

ciscoasa(config)# crypto ca authenticate IssuingCA-DC1
Enter the base 64 encoded CA certificate.
End with the word "quit" on a line by itself
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
quit

INFO: Certificate has the following attributes:
Fingerprint:     537adc87 22cc6e2b 07fdf2e0 18d8ba8b
Do you accept this certificate? [yes/no]: yes

Certificate validated - Signed by existing trustpoint CA certificate.

Trustpoint CA certificate accepted.

% Certificate successfully imported

Verify the thumbprint:




Verify trustpoints:

ciscoasa# show crypto ca trustpoints

Trustpoint ORCA1-CA:
    Subject Name:
    cn=ORCA1-CA
          Serial Number: 37a15821a55dd2864b62a67b6efd5429
    Certificate configured.

Trustpoint IssuingCA-DC1:
    Subject Name:
    cn=IssuingCA-DC1
    dc=kp
    dc=local
          Serial Number: 4d00000002924dec093140270b000000000002
    Certificate configured.



Generate Certificate Signing Request (CSR):

ciscoasa(config)# crypto ca enroll IssuingCA-DC1

Would you like to continue with this enrollment? [yes/no]: yes
% Start certificate enrollment ..

% The fully-qualified domain name in the certificate will be: ciscoasa

% Include the device serial number in the subject name? [yes/no]: yes

% The serial number in the certificate will be: 123456789AB

Display Certificate Request to terminal? [yes/no]: yes
Certificate Request follows:
-----BEGIN CERTIFICATE REQUEST-----
-----END CERTIFICATE REQUEST-----

Redisplay enrollment request? [yes/no]: no


Sign the request:

C:\> certreq -submit -attrib CertificateTemplate:RouterCert .\asa1.csr asa1.pem

Import certificate:

ciscoasa(config)# crypto ca import IssuingCA-DC1 certificate


Verify certificates:

ciscoasa# show crypto ca certificates

Certificate
  Status: Available
  Certificate Serial Number: 6d00000040400187689d214e1e000000000040
  Certificate Usage: General Purpose
  Public Key Type: RSA (1024 bits)
  Signature Algorithm: SHA1 with RSA Encryption
  Issuer Name:
    cn=IssuingCA-DC1
    dc=kp
    dc=local
  Subject Name:
    hostname=ciscoasa
    serialNumber=123456789AB
  CRL Distribution Points:
    [1]  http://dc1.kp.local/pki/IssuingCA-DC1.crl
  Validity Date:
    start date: 15:35:33 UTC Apr 5 2013
    end   date: 12:54:58 UTC Mar 14 2014
  Associated Trustpoints: IssuingCA-DC1

CA Certificate
  Status: Available
  Certificate Serial Number: 4d00000002924dec093140270b000000000002
  Certificate Usage: Signature
  Public Key Type: RSA (2048 bits)
  Signature Algorithm: SHA1 with RSA Encryption
  Issuer Name:
    cn=ORCA1-CA
  Subject Name:
    cn=IssuingCA-DC1
    dc=kp
    dc=local
  CRL Distribution Points:
    [1]  http://dc1.kp.local/ORCA1-CA.crl
  Validity Date:
    start date: 12:44:58 UTC Mar 14 2013
    end   date: 12:54:58 UTC Mar 14 2014
  Associated Trustpoints: IssuingCA-DC1

CA Certificate
  Status: Available
  Certificate Serial Number: 37a15821a55dd2864b62a67b6efd5429
  Certificate Usage: Signature
  Public Key Type: RSA (2048 bits)
  Signature Algorithm: SHA1 with RSA Encryption
  Issuer Name:
    cn=ORCA1-CA
  Subject Name:
    cn=ORCA1-CA
  Validity Date:
    start date: 15:03:12 UTC Mar 13 2013
    end   date: 15:13:12 UTC Mar 13 2023
  Associated Trustpoints: ORCA1-CA



Cisco IOS certificate storage


The way IOS stores certificates depends on enrolment method. 

Certificates enrolled via command line or SCEP are stored in config:

R1#show run | begin crypto pki certificates
crypto pki certificate chain ORCA1-CA
 certificate ca 37A15821A55DD2864B62A67B6EFD5429
  3082038A 30820272 A0030201 02021037 A15821A5 5DD2864B 62A67B6E FD542930


Certificates installed via SDM are stored in NVRAM:

R2#dir nvram:
Directory of nvram:/

   45  -rw-      1629                       startup-config
   46  ----        7636                      private-config
    1  -rw-           4                        rf_cold_starts
    2  -rw-           0                        ifIndex-table
    3  -rw-         910                      ORCA1-CA#5429CA.cer
    4  -rw-         571                      IOS-CA-R2OUK#7401CA.cer

When the built-in IOS CA server is enabled, the CA cert is stored in NVRAM.

Enrolling Cisco IOS for certificates via terminal


In this post we'll go over enrolling Cisco IOS routers for certificates using terminal.  


Generate keys


Firstly we need to generate key pair that we'll then use to create Certificate Signing Request (CSR) that will include our public key. Here we need to decide on the key length. Security wise - the longer the better. It's never that simple though. To this day there are applications that simply do not support anything longer than 2048. This should be taken into consideration. Do we need anything longer than that? We'd have to consider the threat vector. Longer key makes factorization harder. To my knowledge as of writing 1024 bit keys have not been factored. It would take very long time and a lot of very advanced infrastructure to do. This is not a valid threat for most organizations. Key length should be considered in terms of certificate lifetime. The longer the validity the longer they. There also is the CPU overhead we need to take into account. Yes, nowadays CPUs are fast. However, if we consider a large scale deployment with 100s of certificates and for example DMVPNs, using 1024 bit keys vs 2048 can mean significantly more VPNs on single box. 

For the purpose of my lab I'm using 1024 bit keys.


r1(config)#crypto key generate rsa general-keys modulus 1024

To view generated keys:

r1#sh crypto key mypubkey rsa

% Key pair was generated at: 16:46:47 GMT Mar 29 2013
Key name: r1.securesenses.net
 Usage: General Purpose Key
 Key is not exportable.
 Key Data:
--- omitted--- 
% Key pair was generated at: 13:46:55 GMT Mar 30 2013
Key name: r1.securesenses.net.server
 Usage: Encryption Key
 Key is not exportable.
 Key Data:
--- omitted--- 

Import Root CA cert

In order to enrol a router for certificate we need to install the whole trust chain - certifcates of all CA's starting with root CA up to the CA that will issue our certificate. Since we are using terminal enrolment we need certificates in text format so that we can paste them in. For that we will use PEM - "Privacy Enhanced Mail" -  standard. We can recognize PEM format from using 
---BEGIN CERTFICATE--- and ---END CERTIFICATE---- headers and trailers. Between them the certificate is actually represented using Distinguished Encoding Rules - DER - encoding. 


Convert CRT to PEM

Windows Certificate MMC does not allow for saving certificates in PEM format. We will need to convert the .CRT to .PEM. OpenSSL library is what we will use. 

At command prompt:

openssl x509 -in ROOT-CA.crt -inform der -out ROOT-CA.pem -outform pem


Install ROOT CA certificate:

Create a trustpoint for the CA root certificate.

R1(config)#crypto ca trustpoint ORCA1-CA
R1(ca-trustpoint)#enrollment terminal PEM
R1(ca-trustpoint)#crl optional 
R1(ca-trustpoint)#exit

Import the CA root certificate with copy and paste.

r1(config)#crypto ca authenticate ORCA1-CA

Enter the base 64 encoded CA certificate.
End with a blank line or the word "quit" on a line by itself

-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----

Certificate has the following attributes:
       Fingerprint MD5: E9FD8A22 E82C13EF 5DB781A7 616AD113 
       Fingerprint SHA1: 6085A54F 1A6A67B1 7F8DC1A9 54F995AD
                         8DA49D21 

% Do you accept this certificate? [yes/no]: yes
Trustpoint CA certificate accepted.
% Certificate successfully imported

Confirm that hash matches the hash in the .CRT encoded cert we started with.



Install Sub-ordinate CA certificate:

We repeat above steps in order to install Subordinate CA certififcate. This is required so that we can validate full certificate chain. 
This time we should get the following message:

Certificate validated - Signed by existing trustpoint CA certificate.

Trustpoint CA certificate accepted.
% Certificate successfully imported


Verify certificates have been installed and associated to trustpoints:

r1#show crypto pki certificates
CA Certificate
  Status: Available
  Certificate Serial Number: 4D00000002924DEC093140270B000000000002
  Certificate Usage: Signature
  Issuer:
    cn=ORCA1-CA
  Subject:
    cn=IssuingCA-DC1
    dc=kp
    dc=local
  CRL Distribution Points:
    http://dc1.kp.local/ORCA1-CA.crl
  Validity Date:
    start date: 13:44:58 GMT Mar 14 2013
    end   date: 13:54:58 GMT Mar 14 2014
  Associated Trustpoints: SubCa

CA Certificate
  Status: Available
  Certificate Serial Number: 37A15821A55DD2864B62A67B6EFD5429
  Certificate Usage: Signature
  Issuer:
    cn=ORCA1-CA
  Subject:
    cn=ORCA1-CA
  Validity Date:
    start date: 16:03:12 GMT Mar 13 2013
    end   date: 16:13:12 GMT Mar 13 2023
  Associated Trustpoints: ORCA1-CA


Generate Certificate Signing Request (CSR)

r1(config)#crypto pki enroll SubCa
% Start certificate enrollment ..

% The subject name in the certificate will include: r1.securesenses.net
% Include the router serial number in the subject name? [yes/no]: yes
% The serial number in the certificate will be: FF1045C5
% Include an IP address in the subject name? [no]: no
Display Certificate Request to terminal? [yes/no]: yes
Certificate Request follows:

-----BEGIN CERTIFICATE REQUEST-----
-----END CERTIFICATE REQUEST-----

---End - This line is not part of the certificate request---

Redisplay enrolment request? [yes/no]: no

Copy everything between ---- BEGIN C..---- and ----END C..---- inclusive to a text file and save as .csr. Make sure you use a notepad so that no additional encoding is added.


Sign the request:

The request does not contain template information. Therefore we have supply in the request. For that we need to use certreq.exe utility.

C:\> certreq -submit -attrib CertificateTemplate:RouterCert .\r1.req r1.pem

Alternately we can omit the output file name and use GUI to save to CRT or CER format which we then convert to PEM using the following command:

openssl x509 -in r1.cer -out r1.pem -outform PEM



Import Router Certificate:

r1(config)#crypto pki import SubCa certificate

Enter the base 64 encoded certificate.
End with a blank line or the word "quit" on a line by itself

------BEGIN CERTIFICATE-----
------END CERTIFICATE-----


% Router Certificate successfully imported


Verify certificate import:

r1#show crypto pki certificates
Certificate
  Status: Available
  Certificate Serial Number: 6D00000017F99CF9DB55D020E5000000000017
  Certificate Usage: General Purpose
  Issuer:
    cn=IssuingCA-DC1
    dc=kp
    dc=local
  Subject:
    Name: r1.securesenses.net
    Serial Number: FF1045C5
    hostname=r1.securesenses.net
    serialNumber=FF1045C5
  CRL Distribution Points:
    http://dc1.kp.local/pki/IssuingCA-DC1.crl
  Validity Date:
    start date: 00:03:38 GMT Apr 1 2013
    end   date: 13:54:58 GMT Mar 14 2014
  Associated Trustpoints: SubCa


Cisco KB reference:

http://www.cisco.com/en/US/products/hw/modules/ps2706/products_configuration_example09186a008037d1c8.shtml