From 0b69819ed8951b2195a372a7d8f4fd76c1aa6ed4 Mon Sep 17 00:00:00 2001 From: Javex Date: Mon, 4 Jun 2012 10:32:44 +0100 Subject: [PATCH] Added changes for engine support. Working version, not intended for use! --- Makefile | 8 +- Makefile.w32 | 47 + README | 39 +- README.md | 4 - cmd.h | 233 +- conf.h | 58 +- draft-nourse-scep-06.txt | 4566 +++++++++--------- draft-nourse-scep-11.txt | 9468 +++++++++++++++++++------------------- fileutils.c | 161 +- getopt.c | 1058 +++++ getopt.h | 144 + ias.c | 120 +- ias.h | 46 +- init.c | 3 + net.c | 101 +- pkcs7.c | 1468 +++--- sceputils.c | 4 + sscep.c | 283 +- sscep.h | 30 +- 19 files changed, 9800 insertions(+), 8041 deletions(-) create mode 100644 Makefile.w32 delete mode 100644 README.md create mode 100644 getopt.c create mode 100644 getopt.h diff --git a/Makefile b/Makefile index 56518ca..59080ee 100644 --- a/Makefile +++ b/Makefile @@ -7,14 +7,18 @@ MANDIR = /usr/local/man/man8 CC = gcc #WITH_DEBUG = -g -CFLAGS = -Wall -O $(WITH_DEBUG) +OPENSSL = /c/Users/tob130/Downloads/openssl-mingw +CFLAGS = -Wall -O $(WITH_DEBUG) -I $(OPENSSL)/include + +LDFLAGS = -L$(OPENSSL)/lib +LDLIBS = -lcrypto -lws2_32 -lgdi32 MAN = sscep.8 PROG = sscep OBJS = sscep.o init.o net.o sceputils.o pkcs7.o ias.o fileutils.o $(PROG): $(OBJS) - $(CC) $(CFLAGS) -lcrypto -o $(PROG) $(OBJS) + $(CC) $(CFLAGS) -o $(PROG) $(OBJS) $(LDLIBS) $(LDFLAGS) clean: rm -f $(PROG) $(OBJS) $(MAN) core diff --git a/Makefile.w32 b/Makefile.w32 new file mode 100644 index 0000000..6b928f9 --- /dev/null +++ b/Makefile.w32 @@ -0,0 +1,47 @@ +# +# $Id: Makefile,v 1.0 2003/01/12 13:17:37 jt Exp $ +# + +CC = cl + +#for dynamically linking against binary OpenSSL distribution +#http://www.slproweb.com/download/Win32OpenSSL-v0.9.7i.exe +#works with VC 6.0 but not with VC 7.0 +#OPENSSL_PATH=C:\program files\OpenSSL +#OPENSSL_LIB=$(OPENSSL_PATH)\lib\VC +#OPENSSL_INC=$(OPENSSL_PATH)\include + + +#if you compile OpenSSL from source use the following definitions +OPENSSL_PATH=C:\Users\tob130\Programme\OpenSSL-Win32 +OPENSSL_LIB=$(OPENSSL_PATH)\lib +OPENSSL_INC=$(OPENSSL_PATH)\include + +#change to your scep URL +TEST_URL=http://scepserver.example.com/cgi-bin/scep/scep + +LINK=link +LFLAGS=/nologo /subsystem:console /opt:ref /debug +EX_LIBS=/libpath:"$(OPENSSL_LIB)" libeay32.lib wsock32.lib user32.lib gdi32.lib + +#DEBUG_OPT = /MDd /Od /GS /RTCcsu -D_DEBUG -DDEBUG +DEBUG_OPT = /MD /O2 + +CFLAGS = /W3 /Zi /Yd /nologo -DWIN32 $(DEBUG_OPT) -I. -I"$(OPENSSL_INC)" + +PROG = sscep.exe +OBJS = sscep.obj init.obj net.obj sceputils.obj pkcs7.obj ias.obj fileutils.obj getopt.obj +PDB = *.pdb + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK) $(LFLAGS) /out:$(PROG) $(OBJS) $(EX_LIBS) + +clean: + del $(PROG) $(OBJS) $(PDB) + +test: all + sscep.exe getca -v -u $(TEST_URL) -c cacert + + diff --git a/README b/README index 73ae170..d421dec 100644 --- a/README +++ b/README @@ -62,13 +62,46 @@ o OpenCA (getca, enroll, getcrl and automatic approval works)**** HOW TO COMPILE ============== -The program should compile on OpenBSD system without problems. Uncompress -the package and run command +The program should compile on the following systems: +OpenBSD +AIX +Darwin (PowerPC, no universal binaries yet) +Tandem NonStop (Guardian), OSS environment, MIPS processor +Linux x86 +z/OS (USS environment) +Solaris +Windows, compiled with VC6, statically linked with OpenSSL 0.9.7i + +Unix: + +To compile run: $ make -Copy binary file sscep and configuration file sscep.conf to somewhere. +Windows: + +The Win32 version of sscep has been tested with OpenSSL-v0.9.7i. +For Win32 environment you can choose two ways to compile the sscep program. + +1. Dynamically linked against the binary OpenSSL distribution: + http://www.slproweb.com/download/Win32OpenSSL-v0.9.7i.exe +For this you need the binaries from OpenSSL-v0.9.7i and change the paths +in the makefile Makefile.w32. +This works with VC6.0 but not with VC7.0. +2. Statically linked against OpenSSL-v0.9.7i. +You can download the source from the OpenSSL Homepage and you have to change the +paths in the makefile Makefile.w32. This OpenSSL Version needs to be compiled with the same +compiler as sscep, because otherwise you can get some trouble with diffrent LIBs. + +If you want to use a debug version of sscep, then you need to compile a debug version +of OpenSSL. + +To compile run: +C:\...> vcvars32.bat +C:\...> nmake -f Makefile.w32 + +Copy binary file sscep and configuration file sscep.conf to somewhere. HOW TO USE ========== diff --git a/README.md b/README.md deleted file mode 100644 index 9ba832f..0000000 --- a/README.md +++ /dev/null @@ -1,4 +0,0 @@ -sscep -===== - -Simple SCEP client with modifications for engine support & more \ No newline at end of file diff --git a/cmd.h b/cmd.h index 9a83d5d..1dd40cb 100644 --- a/cmd.h +++ b/cmd.h @@ -1,105 +1,128 @@ - -/* - * sscep -- Simple SCEP client implementation - * Copyright (c) Jarkko Turkulainen 2003. All rights reserved. - * See the file COPYRIGHT for licensing information. - */ - -/* - * Command line options - * These are defined globally for easy access from all functions. - * For each command line option 'x', there is int x_flag and - * char *x_char or int x_num if the option requires parameter. - */ - -/* CA certificate */ -int c_flag; -char *c_char; - -/* Debug? */ -int d_flag; - -/* CA encryption certificate */ -int e_flag; -char *e_char; - -/* Encryption algorithm */ -char *E_char; -int E_flag; - -/* Configuration file */ -int f_flag; -char *f_char; - -/* Fingerprint algorithm */ -char *F_char; -int F_flag; - -/* Local certificate */ -char *l_char; -int l_flag; - -/* Local selfsigned certificate (generated automaticatally) */ -char *L_char; -int L_flag; - -/* CA identifier */ -char *i_char; -int i_flag; - -/* Private key */ -char *k_char; -int k_flag; - -/* Private key of already existing certificate */ -char *K_char; -int K_flag; - -/* Request count */ -int n_flag; -int n_num; - -/* Already existing certificate (to be renewed) */ -char *O_char; -int O_flag; - -/* Proxy */ -char *p_char; -int p_flag; - -/* GetCrl CRL file */ -char *r_char; -int r_flag; - -/* Resume */ -int R_flag; - -/* Certificate serial number */ -char *s_char; -int s_flag; - -/* Signature algorithm */ -char *S_char; -int S_flag; - -/* Polling interval */ -int t_num; -int t_flag; - -/* Max polling time */ -int T_num; -int T_flag; - -/* URL */ -int u_flag; -char *url_char; - -/* Verbose? boolean */ -int v_flag; - -/* GetCert certificate */ -int w_flag; -char *w_char; - -/* End of command line options */ - + +/* + * sscep -- Simple SCEP client implementation + * Copyright (c) Jarkko Turkulainen 2003. All rights reserved. + * See the file COPYRIGHT for licensing information. + */ + +/* + * Command line options + * These are defined globally for easy access from all functions. + * For each command line option 'x', there is int x_flag and + * char *x_char or int x_num if the option requires parameter. + */ + +/* CA certificate */ +int c_flag; +char *c_char; + +/* Debug? */ +int d_flag; + +/* CA encryption certificate */ +int e_flag; +char *e_char; + +/* Encryption algorithm */ +char *E_char; +int E_flag; + +/* Configuration file */ +int f_flag; +char *f_char; + +/* Fingerprint algorithm */ +char *F_char; +int F_flag; + +/* enable EnGine support */ +char *g_char; +int g_flag; + +/* enable hwcrhk keys + * To set this means that the new key (for which you have the + * CSR and Private Key) should be taken from the engine + * while the old key (possibly, see captial letter options) + * is selected by the -H option +*/ +int h_flag; + +/* sets if engine should be used if the old key usage is set + * i.e., setting this uses the old key für signing and does + * not set anything for the lowercase options that correspond + * to the new keys +*/ +int H_flag; + +/* Local certificate */ +char *l_char; +int l_flag; + +/* Local selfsigned certificate (generated automaticatally) */ +char *L_char; +int L_flag; + +/* CA identifier */ +char *i_char; +int i_flag; + +/* Private key */ +char *k_char; +int k_flag; + +/* Private key of already existing certificate */ +char *K_char; +int K_flag; + +/* Test mode */ +int m_flag; +char *m_char; + +/* Request count */ +int n_flag; +int n_num; + +/* Already existing certificate (to be renewed) */ +char *O_char; +int O_flag; + +/* Proxy */ +char *p_char; +int p_flag; + +/* GetCrl CRL file */ +char *r_char; +int r_flag; + +/* Resume */ +int R_flag; + +/* Certificate serial number */ +char *s_char; +int s_flag; + +/* Signature algorithm */ +char *S_char; +int S_flag; + +/* Polling interval */ +int t_num; +int t_flag; + +/* Max polling time */ +int T_num; +int T_flag; + +/* URL */ +int u_flag; +char *url_char; + +/* Verbose? boolean */ +int v_flag; + +/* GetCert certificate */ +int w_flag; +char *w_char; + +/* End of command line options */ + diff --git a/conf.h b/conf.h index f4a5988..626eaad 100644 --- a/conf.h +++ b/conf.h @@ -1,29 +1,29 @@ - -/* - * sscep -- Simple SCEP client implementation - * Copyright (c) Jarkko Turkulainen 2003. All rights reserved. - * See the file COPYRIGHT for licensing information. - */ - - -/* Network timeout */ -#define TIMEOUT 120 - -/* Polling interval seconds */ -#define POLL_TIME 300 - -/* Max polling seconds */ -#define MAX_POLL_TIME 28800 - -/* Max polling count */ -#define MAX_POLL_COUNT 256 - -/* CA identifier */ -#define CA_IDENTIFIER "CAIdentifier" - -/* Self signed certificate expiration */ -#define SELFSIGNED_EXPIRE_DAYS 365 - -/* Transaction id for GetCert and GetCrl methods */ -#define TRANS_ID_GETCERT "SSCEP transactionId" - + +/* + * sscep -- Simple SCEP client implementation + * Copyright (c) Jarkko Turkulainen 2003. All rights reserved. + * See the file COPYRIGHT for licensing information. + */ + + +/* Network timeout */ +#define TIMEOUT 120 + +/* Polling interval seconds */ +#define POLL_TIME 300 + +/* Max polling seconds */ +#define MAX_POLL_TIME 28800 + +/* Max polling count */ +#define MAX_POLL_COUNT 256 + +/* CA identifier */ +#define CA_IDENTIFIER "CAIdentifier" + +/* Self signed certificate expiration */ +#define SELFSIGNED_EXPIRE_DAYS 365 + +/* Transaction id for GetCert and GetCrl methods */ +#define TRANS_ID_GETCERT "SSCEP transactionId" + diff --git a/draft-nourse-scep-06.txt b/draft-nourse-scep-06.txt index 0cb3e07..4470097 100644 --- a/draft-nourse-scep-06.txt +++ b/draft-nourse-scep-06.txt @@ -1,2283 +1,2283 @@ -INTERNET DRAFT Xiaoyi Liu -draft-nourse-scep-06.txt Cheryl Madson -expires 15-November 2002 David McGrew - Andrew Nourse - Cisco Systems - -Category: Informational 15 May 2002 - - -Cisco Systems' Simple Certificate Enrollment Protocol(SCEP): - -Status of this Memo - -This document is an Internet-Draft and is NOT offered in -accordance with Section 10 of RFC2026, and the author does not -provide the IETF with any rights other than to publish as an -Internet-Draft - -Internet-Drafts are working documents of the Internet Engineering -Task Force (IETF), its areas, and its working groups. Note that -other groups may also distribute working documents as -Internet-Drafts. - -Internet-Drafts are draft documents valid for a maximum of six -months and may be updated, replaced, or obsoleted by other -documents at any time. It is inappropriate to use Internet- -Drafts as reference material or to cite them other than as -"work in progress." - -The list of current Internet-Drafts can be accessed at -http://www.ietf.org/ietf/1id-abstracts.txt - -The list of Internet-Draft Shadow Directories can be accessed at -http://www.ietf.org/shadow.html. - -This memo provides information for the Internet community. This memo -does not specify an Internet standard of any kind. Distribution of -this memo is unlimited. - - -Abstract - -This document specifies the Cisco Simple Certificate Enrollment -Protocol, a PKI communication protocol which leverages existing -technology by using PKCS#7 and PKCS#10. SCEP is the evolution of the -enrollment protocol developed by Verisign, Inc. for Cisco Systems, Inc. -It now enjoys wide support in both client and CA implementations. - - -Table of Contents - - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 2 - 2. The Goal of SCEP . . . . . . . . . . . . . . . . . . . . . 3 - 2.1 SCEP Entity types . . . . . . . . . . . . . . . . . . . . 3 - 2.2 SCEP Operations Overview . . . . . . . . . . . . . . . . . 7 - - -Liu/Madson/McGrew/Nourse [Page 2] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - 2.3 PKI Operation Transactional Behavior . . . . . . . . . . . 10 - 2.4 Security . . . . . . . . . . . . . . . . . . . . . . . . . 12 - 3. Transport Protocol . . . . . . . . . . . . . . . . . . . . 13 - 4. Secure Transportation: PKCS #7 . . . . . . . . . . . . . . 14 - 4.1 SCEP Message Format . . . . . . . . . . . . . . . . . . . 14 - 4.2 Signed Transaction Attributes . . . . . . . . . . . . . . 15 - 5. SCEP Transaction Specification . . . . . . . . . . . . . . 16 - 6. Security Considerations . . . . . . . . . . . . . . . . . 33 - 7. Intellectual Propoerty . . . . . . . . . . . . . . . . . . 33 - 8. References . . . . . . . . . . . . . . . . . . . . . . . . 33 - Appendix A. Cisco End Entity Subject Name Definition . . . . . 34 - Appendix B. IPSEC Client Enrollment Certificate Request . . . . 35 - Appendix C. Private OID Definitions . . . . . . . . . . . . . 36 - Appendix D. Obtaining CRL by LDAP Query . . . . . . . . . . . . 36 - Appendix E. SCEP State Transitions . . . . . . . . . . . . . . 37 - Appendix F. Author Contact Information. . . . . . . . . . . . . 40 - Appendix G. Copyright Section . . . . . . . . . . . . . . . . . 40 - - -Section 1. Introduction - -Public key technology is becoming more widely deployed and is becoming -the basis for standards based security, such as the Internet Engineering -Task Force's IPSEC and IKE protocols. With the use of public key -certificates in network security protocols comes the need for a -certificate management protocol that Public Key Infrastructure (PKI) -clients and Certificate Authority servers can use to support certificate -life cycle operations such as certificate enrollment and revocation, and -certificate and CRL access. - -In the following, Section 2 gives an overview of the PKI operations, and -Section 2.4 describes the security goals of the protocol and the -mechanisms used to achieve them. The transport protocol and the -security protocol PKCS#7 are described at Section 3 and Section 4, -respectively. The last section, Section 5, specifies each PKI operation -in terms of the message formats and the data structures of each -operation. - -The appendices provide detailed specifications and examples. End entity -subject names are specified in Appendix A, attribute OIDs are specified -in Appendix C , and the SCEP state transitions are described in Appendix -E. An example of a certificate enrollment request is provided in -Appendix B, and an example LDAP query URL encoding is provided in -Appendix D. - -The authors would like to thank Peter William of ValiCert, Inc. -(formerly of Verisign, Inc) and Alex Deacon of Verisign, Inc. and -Christopher Welles of IRE, Inc. for their contributions to this protocol -and to this document. - - - - -Liu/Madson/McGrew/Nourse [Page 3] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -2.0 The Goal of SCEP -The goal of SCEP is to support the secure issuance of certificates to -network devices in a scalable manner, using existing technology whenever -possible. The protocol supports the following operations: - - CA and RA public key distribution - Certificate enrollment - Certificate revocation - Certificate query - CRL query - -Certificate and CRL access can be achieved by using the LDAP protocol -(as specified in Appendix D), or by using the query messages defined in -SCEP. The use of HTTP certificate and CRL access, and the support of -CDP as specified in RFC2459, will be specified in a future version of -this document. In Section 2.1, we first define PKI entity types as well -as the properties of each entity type. In Section 2.2, the PKI -operations are described at functional level. Section 2.3 describes the -transaction behavior of each PKI operations. The complete PKI messages -are covered in Section 5. - -2.1 SCEP Entity types - -The entity types defined in SCEP are the end entity type (i.e., IPSEC -clients), the Certificate Authority (CA) entity type, and the -Registration Authority entity type (RA). An end entity is sometimes -called a "SCEP client" in the following. - -2.1.1 End Entities - -An end entity is an entity whose name is defined in a certificate -subject name field and optionally, in SubjectAltName, a X.509 -certificate V3 extension. As an end entity, a SCEP client is identified -by a subject name consisting of the following naming attributes: - - Fully qualified domain name, for example, router.cisco.com - IP address, or - Serial number. - -In the paragraph above , the fully qualified domain name is required for -each SCEP client, the IP address and the serial number are optional name -attributes. In the certificate enrollment request, the PKCS#10 subject -field contains the required and optional name attributes. Based on the -PKCS#10 subject name information, the certificate issued to the SCEP -client must have the same name attributes set both in the subjectName -field and in the SubjectAltName extension. - -It is important to note that a client named as Alice.cisco.com is -different than a client named as Alice.cisco.com plus the IP address -name attribute 171.69.1.129. From CA point of view, the Distinguished -names assigned in these two cases are distinct names. - - -Liu/Madson/McGrew/Nourse [Page 4] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -Entity names which are specified as in the IPSEC profile (i.e., FQDN, IP -address and User FQDN) must be presented in certificate's SubjectAltName -extension. Multiple IPSEC entity names, (if any) are encoded as multiple -values of a single SubjectAltName extension. The CA has the authority -to assign a distinguished name to an end entity. The assigned DN should -contain the SCEP client names as the relative DN. - -The attribute identifiers and an example of SCEP client subject name are -specified in Appendix A. Appendix B has an example from Cisco VPN Client -enrollment request. - -2.1.1.1 Local Key/Certificate/CRL Storage and Certificate-name uniqueness - -An end entity is required to generate asymmetric key pairs and to -provide storage to store its private keys. If the end entity does not -have enough permanent memory to save its certificate, the end entity -should be able to query its own certificate from the CA, once the -certificate has been issued. The public key pairs can be generated with -a specific key usage. The key usage are conveyed to the CA through the -certificate enrollment request. All current SCEP client implementations -expect that there will be only one pair of keys for a given subject name -and key usage combination and CA, at any time. This property is called -the certificate-name uniqueness property, and it implies that a CA that -implements SCEP will enforce the unique mapping between a SCEP client -subject name and its key pairs with a given key usage. At any time, if -the subject name is changed, or if the key is updated, the existing -certificate would have to be revoked before a new one could be issued. - -It is desirable that the CA enforce certificate-name uniqueness, but -it is not mandatory. However a CA that does not enforce uniqueness -must provide some other mechanism to prevent the re-transmission of an -enrollment request by a SCEP client from creating a second certificate -or certificate request, nor can the second request merely be rejected. -If a client times out from polling for a pending request it can -resynchronize by reissuing the original request with the original -subject name and transaction ID. This must return the status of the -original transaction, including the certificate if it was granted. -It must not create a new transaction unless the original cert has been -revoked, or the transaction arrives more than halfway through the -validity time of the original certificate. - -An enrollment request that occurs more than halfway through the validity -time of an existing certificate for the same subject name and key usage -MAY be interpreted as a renewal request and accepted regardless of the -duplication of subject name. Certificate renewal can be done this way. - - -2.1.1.2 End entity authentication - -As with every protocol that uses public-key cryptography, the -association between the public keys used in the protocol and the -identities with which they are associated must be authenticated in a - - -Liu/Madson/McGrew/Nourse [Page 5] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -cryptographically secure manner. This requirement is needed to -prevent a "man in the middle" attack, in which an adversary that can -manipulate the data as it travels between the protocol participants -can subvert the security of the protocol. To satisfy this -requirement, SCEP provides two authentication methods: manual -authentication, and authentication based on pre-shared secret. In the -manual mode, the end entity submitting the request is required to wait -until its identity can be verified by the CA operator using any -reliable out-of-band method. To prevent a "man-in-the-middle" attack, -an MD5 `fingerprint' generated on the PKCS#10 (before PKCS #7 -enveloping and signing) must be compared out-of-band between the server -and the end entity. SCEP clients and CAs (or RAs, if appropriate) -must display this fingerprint to a user to enable this verification, -if manual mode is used. Failing to provide this information leaves -the protocol vulnerable to attack by sophisticated adversaries. When -utilizing a pre-shared secret scheme, the server should distribute a -shared secret to the end entity which can uniquely associate the -enrollment request with the given end entity. The distribution of the -secret must be private: only the end entity should know this -secret. The actual binding mechanism between the end entity and the -secret is subject to the server policy and implementation. When -creating enrollment request, the end entity is asked to provide a -challenge password. When using the pre-shared secret scheme, the end -entity must type in the re-distributed secret as the password. In the -manual authentication case, the challenge password is also required -since the server may challenge an end entity with the password before -any certificate can be revoked. Later on, this challenge password -will be included as a PKCS#10 attribute, and is sent to the server as -encrypted data. The PKCS#7 envelope protects the privacy of the -challenge password with DES encryption. - -2.1.1.3 Self-Signed Certificates - -In this protocol, the communication between the end entity and the -certificate authority is secured by using PKCS#7 as the messaging -protocol. PKCS#7, however, is a protocol which assumes the communicating -entities already possess the peer's certificates and requires both -parties use the issuer names and issuer assigned certificate serial -numbers to identify the certificate in order to verify the signature and -decrypt the message. When using PKCS#7 as a secure protocol for SCEP -transactions this assumption may not be valid. To solve this problem, -an end entity generates a self-signed certificate for its own public -key. In this self-signed certificate, the issuer name is the end entity -subject name (the same name later used in the PKCS#10). During the -certificate enrollment, the end entity will first post itself as the -signing authority by attaching the self-signed certificate to the signed -certificate request. When the Certificate Authority makes the envelope -on the issued certificate using the public key included in the -self-signed certificate, it should use the same issuer name and serial -number as conveyed in the self-signed certificate to inform the end -entity on which private key should be used to open the envelope. - -Note that when a client enrolls for Mayarate encryption and signature - -Liu/Madson/McGrew/Nourse [Page 6] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -certificates, it may use the signature certificate to sign both -requests, and then expect its signature key to be used to encrypt -both responses. In any case, the recipientinfo on the envelope should -reflect the key used to encrypt the request. - -2.1.2 Certificate Authority - -A Certificate Authority(CA) is an entity whose name is defined in the -certificate issuer name field. Before any PKI operations can begin, -the CA generates its own public key pair and creates a self-signed CA -certificate, or causes another CA to issue a certificate to it. -Associated with the CA certificate is a fingerprint which will be used -by the end entity to authenticate the received CA certificate if it -is self-signed. The fingerprint is created by calculating a MD5 hash -on the whole CA certificate. Before any end entity can start its -enrollment, this root certificate has to be configured at the entity -side securely. For IPSEC clients, the client certificates must have -SubjectAltName extension. To utilize LDAP as a CRL query protocol, -the certificates must have CRL Distribution Point. Key usage is -optional. Without key usage, the public key is assumed as a general -purpose public key and it can be used for all the purposes. - -A Certificate Authority may enforce certain name policy. When using -X.500 directory name as the subject name, all the name attributes -specified in the PKCS#10 request should be included as Relative DN. All -the name attributes as defined in RFC2459 should be specified in the -SubjectAltName. An example is provided in Appendix A. - - If there is no LDAP query protocol support, the Certificate Authority -should answer certificate and CRL queries, and to this end it should be -online all the time. - -The updating of the CA's public key is not addressed within the SCEP -protocol. An SCEP client can remove its copy of a CA's public key and -re-enroll under the CA's new public key. - -2.1.3 Registration Authorities - -In the environment where a RA is present, an end entity performs -enrollment through the RA. In order to setup a secure channel with RA -using PKCS#7, the RA certificate(s) have to be obtained by the client -in addition to the CA certificate(s). - -In the following, the CA and RA are specified as one entity in the -context of PKI operation definitions. - -2.1.4 Trusted Root Store - -To support interoperability between IPSEC peers whose certificates are -issued by different CA, SCEP allows the users to configure multiple -trusted roots. A root is a trusted root when its certificate has been - - -Liu/Madson/McGrew/Nourse [Page 7] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -configured as such in the client. An SCEP client that supports multiple -roots must associate with each root the information needed to query a -CRL from each root. - -Once a trusted root is configured in the client, the client can verify -the signatures of the certificates issued by the given root. - -2.2 SCEP Operations Overview - -In this section, we give a high level overview of the PKI operations as -defined in SCEP. - -2.2.1 End Entity Initialization - -The end entity initialization includes the key pair generation and the -configuring of the required information to communicate with the -certificate authority. - -2.2.1.1 Key Pair Generation - -Before an end entity can start PKI transaction, it first generates -asymmetric key pairs, using the selected algorithm (the RSA algorithm is -required in SCEP, and is the only algorithm in current implementations). - -An end entity can create one or more asymmetric key pairs, for different -key usage. The key pairs can be created for encryption only, signing -only, or for all purposes. For the same key usage, there can be only -one key pair at any time. - -The key pairs are saved by the client in NVRAM or other non-volatile -media. The identification of a key pair is based on the FQDN assigned to -the client and the selected key usage. Every time a new key pair is -generated to replace the old key pair, the existing certificates have to -be revoked from the CA and a new enrollment has to be completed. - -2.2.1.2 Required Information - -An end entity is required to have the following information configured -before starting any PKI operations: - - 1. the certificate authority IP address or fully qualified domain name, - 2. the certificate authority HTTP CGI script path, and - the HTTP proxy information in case there is no direct Internet - connection to the server, - 3. the CRL query URL, if the CRL is to be obtained by from a directory - server by means of LDAP. - - -2.2.2 CA/RA Certificate Distribution - -Before any PKI operation can be started, the end entity needs to get -the CA/RA certificates. At this time, since no public key has been - - -Liu/Madson/McGrew/Nourse [Page 8] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -exchanged between the end entity and the CA/RA, the message to get the -CA/RA certificate can not be secured using PKCS#7 protocol. Instead, the -CA/RA certificate distribution is implemented as a clear HTTP Get -operation. After the end entity gets the CA certificate, it has to -authenticate the CA certificate by comparing the finger print with the -CA/RA operator. Since the RA certificates are signed by the CA, there is -no need to authenticate the RA certificates. - -This operation is defined as a transaction consisting of one HTTP Get -message and one HTTP Response message: - - END ENTITY CA SERVER - Get CA/RA Cert: HTTP Get message - -----------------------------> - CA/RA Cert download: HTTP Response message - <--------------------------------------- - Compute finger print and - call CA operator. - Receive call and check finger print - -If an RA is in use, a degenerated PKCS#7 with a certificate chain -consisting of both RA and CA certificates is sent back to the end -entity. Otherwise the CA certificate is directly sent back as the -HTTP response payload. - - -2.2.3 Certificate Enrollment - -An end entity starts an enrollment transaction by creating a -certificate request using PKCS#10 and send it to the CA/RA enveloped -using the PKCS#7. After the CA/RA receives the request, it will either -automatically approve the request and send the certificate back, or it -will require the end entity to wait until the operator can manually -authenticate the identity of the requesting end entity. Two -attributes are included in the PKCS#10 certificate request - a -Challenge Password attribute and an optional ExtensionReq attribute -which will be a sequence of extensions the end entity would like to be -included in its V3 certificate extensions. The Challenge Password is -used for revocation and may be used (at the option of the CA/RA) -additionally as a one-time password for automatic enrollment. - -In the automatic mode, the transaction consists of one PKCSReq PKI -Message, and one CertRep PKI message. In the manual mode, the end entity -enters into polling mode by periodically sending GetCertInitial PKI -message to the server, until the server operator completes the manual -authentication, after which the CA will respond to GetCertInitial by -returning the issued certificate. - -The transaction in automatic mode: - - END ENTITY CA SERVER - - -Liu/Madson/McGrew/Nourse [Page 9] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 -PKCSReq: PKI cert. enrollment msg - --------------------------------> CertRep: pkiStatus = SUCCESS - certificate -attached - <------------------------------ - Receive issued certificate. - -The transaction in manual mode: - - END ENTITY CA SERVER - PKCSReq: PKI cert. enrollment msg - --------------------------------> CertRep: pkiStatus = PENDING - <------------------------------ - GetCertInitial: polling msg - --------------------------------> CertRep: pkiStatus = PENDING - <------------------------------ - ................. CertRep: pkiStatus = SUCCESS - certificate -attached - <------------------------------ - Receive issued certificate. - - -2.2.4 End Entity Certificate Revocation - -An end entity should be able to revoke its own certificate. Currently -the revocation is implemented as a manual process. In order to revoke a -certificate, the end entity make a phone call to the CA server -operator. The operator will come back asking the ChallangePassword -(which has been send to the server as an attribute of the PKCS#10 -certificate request). If the ChallangePassword matches, the certificate -is revoked. The reason of the revocation is documented by CA/RA. - - -2.2.5 Certificate Access - -There are two methods to query certificates. The first method is to use -LDAP as a query protocol. Using LDAP to query assumes the client -understand the LDAP scheme supported by the CA. The SCEP client assumes -that the subject DN name in the certificate is used as URL to query the -certificate. The standard attributes (userCertificate and caCertificate) -are used as filter. - -For the environment where LDAP is not available, a certificate query -message is defined to retrieve the certificates from CA. - -To query a certificate from the certificate authority, an end entity -sends a request consisting of the certificate's issuer name and the -serial number. This assumes that the end entity has saved the issuer - - -Liu/Madson/McGrew/Nourse [Page 10] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -name and the serial number of the issued certificate from the previous -enrollment transaction. The transaction to query a certificate consists -of one GetCert PKI message and one CertRep PKI message: - - END ENTITY CA SERVER - GetCert: PKI cert query msg - -------------------------------> CertRep: pkiStatus = SUCCESS - certificate -attached - <----------------------------- - Receive the certificate. - -2.2.6 CRL Distribution - -The CA/RA will not "push" the CRL to the end entities. The query of the -CRL can only be initialized by the end entity. - -There are three methods to query CRL. - -The CRL may be retrieved by a simple HTTP GET. If the CA supports this -method, it should encode the URL into a CRL Distribution Point extension -in the certificates it issues. Support for this method should be -incorporated in new and updated clients, but may not be in older -versions. - -The second method is to query CRL using LDAP. This assumes the CA server -supports CRL LDAP publishing and issues the CRL Distribution Point in -the certificate. The CRL Distribution Point is encoded as a DN. Please -refer to Appendix D for the examples of CRL Distribution Point. - -The third method is implemented for the CA which does not support LDAP -CRL publishing or does not implement the CRL Distribution Point. In this -case, a CRL query is composed by creating a message consists of the CA -issuer name and the CA's certificate serial number. This method is -deprecated because it does not scale well and requires the CA to be a -high-availability service. - -The message is send to the CA in the same way as the other SCEP -requests: The transaction to query CRL consists of one GetCRL PKI -message and one CertRep PKI message which have no certificates but CRL. - - END ENTITY CA SERVER - GetCRL: PKI CRL query msg - ----------------------------------> CertRep: CRL attached - <-------------------------------- - -2.3 PKI Operation Transactional Behavior - -As described before, a PKI operation is a transaction consisting of the -messages exchanged between an end entity and the CA/RA. This section -will specify the transaction behavior on both the end entity and the - - -Liu/Madson/McGrew/Nourse [Page 11] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -certificate authority server. Because the protocol is basically a two -way communication protocol without a confirmation message from the -initiating side, state and state resynchronization rules have to be -defined, in case any error happens at either side. Before the state -transition can be defined, the notion of transaction identifier has to -be defined first. - -2.3.1 Transaction Identifier - -A transaction identifier is a string generated by the entity when -starting a transaction. Since all the PKI operations defined in this -protocol are initiated by the end entity, it is the responsibility of -the end entity to generate a unique string as the transaction -identifier. All the PKI messages exchanged for a given PKI operations -must carry the same transaction identifier. The transaction identifier -is generated as a MD5 hash on the public key value for which the -enrollment request is made. This allows the SCEP client to reuse the -same transaction identifier if it is reissuing a request for the same -certificate (i.e. a certificate with the same subject, issuer, and key). -The SCEP protocol requires that transaction identifiers be unique, so -that queries can be matched up with transactions. For this reason, in -those cases in which Mayarate signing and encryption certificates are -issued to the same end entity, the keys must be different. - -2.3.2 State Transitions in Certificate Enrollment - -The end entity state transitions during enrollment operation is -indicated in the diagram below: - +-<------+ - | | - GetCertInitial triggered by timeout or - | | manual authentication - | | - [CERT-NONEXISTANT] ------> [CERT-REQ-PENDING] ---> [CERT-ISSUED] - | PKCSReq | CertRep with SUCCESS - | | - | | - +--------<-------------------+ - request rejected, timeout, or error - -As described in the section 2.2.3, certificate enrollment starts at the -state CERT-NONEXISTANT. Sending PKCSReq changes the state to -CERT-REQ-PENDING. Receiving CertRep with SUCCESS status changes the -state to CERT-ISSUED. In the case the server sending back the response -with pending status, the end entity will keep polling certificate -response by sending GetCertInitial to the server, until either a CertRep -with SUCCESS status is received, or the maximum polling number has been -exceeded. - -If an error or timeout occurs in the CERT-REQ-PENDING state, the end -entity will transition to the CERT-NONEXISTANT state. - - -Liu/Madson/McGrew/Nourse [Page 12] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - -The client administrator will, eventually, start up another enrollment -request. It is important to note that, as long as the end entity does -not change its subject name or keys, the same transaction id will be -used in the "new" transaction. This is important because based on this -transaction id, the certificate authority server can recognize this as -an existing transaction instead of a new one. - - -2.3.3 Transaction Behavior of Certificate/CRL Access - -There is no state maintained during certificate access and CRL access -transaction. When using the certificate query and CRL query messages -defined in this protocol, the transaction identifier is still required -so that the end entity can match the response message with the -upstanding request message. When using LDAP to query the certificate and -the CRL, the behavior is specified by the LDAP protocol. - -2.4 Security - -The security goals of SCEP are that no adversary can: - -o subvert the public key/identity binding from that intended, -o discover the identity information in the enrollment requests and - issued certificates, -o cause the revocation of certificates with any non-negligible - probability. - -Here an adversary is any entity other than the end entity and the CA -(and optionally the RA) participating in the protocol that is -computationally limited, but that can manipulate data during -transmission (that is, a man-in-the-middle). The precise meaning of -'computationally limited' depends on the implementer's choice of -cryptographic hash functions and ciphers. The required algorithms are -RSA, DES, and MD5. - -The first and second goals are met through the use of PKCS#7 and PKCS#10 -encryption and digital signatures using authenticated public keys. The -CA's public key is authenticated via the checking of the CA fingerprint, -as specified in Section 2.1.2, and the SCEP client's public key is -authenticated through the manual authentication or pre-shared secret -authentication, as specified in Section 2.1.1.2. The third goal is met -through the use of a Challenge Password for revocation, that is chosen -by the SCEP client and communicated to the CA protected by the PKCS#7 -encryption, as specified in Section 2.2.4. - -The motivation of the first security goal is straightforward. The -motivation for the second security goal is to protect the identity -information in the enrollment requests and certificates. For example, -two IPSEC hosts behind a firewall may need to exchange certificates, and -may need to enroll certificates with a CA that is outside of a firewall. -Most networks with firewalls seek to prevent IP addresses and DNS - - -Liu/Madson/McGrew/Nourse [Page 13] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -information from the trusted network leaving that network. The second -goal enables the hosts in this example to enroll with a CA outside the -firewall without revealing this information. The motivation for the -third security goal is to protect the SCEP clients from denial of -service attacks. - - -Section 3 Transport Protocol - -In the SCEP protocol, HTTP is used as the transport protocol for the PKI -messages. - -3.1 HTTP "GET" Message Format - -In the PKI protocol, CA/RA certificates are send to the end entity in -clear, whereas the end entity certificates are send out using the PKCS#7 -secure protocol. This results in two types of GET operations. The type -of GET operation is specified by augmenting the GET message with -OPERATION and MESSAGE parameters in the Request-URL. OPERATION -identifies the type of GET operation, and MESSAGE is actually the PKI -message encoded as a text string. - -The following is the syntax definition of a HTTP GET message send from -an end entity to a certificate authority server: - -Request = "GET " CGI-PATH CGI-PROG "?operation=" OPERATION "&message=" -MESSAGE -where: - CGI-PATH defines the actual CGI path to invoke the CGI program which - parses the request. -| CGI-PROG is set to be the string "pkiclient.exe". This is intended -| to be the program that the CA will use to handle the SCEP transactions, -| though the CA may ignore CGI-PROG and use only the CGI-PATH. - OPERATION is set to be the string "PKIOperation" when the GET message - carries a PKI message to request certificates or CRL; OPERATION is set -| to be the string "GetCACert" or "GetCACertChain" when the GET operation -| is used to get CA/RA certificate or the CA Cert chain (respectively). - When OPERATION is "PKIOperation", MESSAGE is a base64-encoded PKI - message -| when OPERATION is "GetCACert" or "GetCACertChain", MESSAGE is a string -| which represents the certificate authority issuer identifier. - -For example. An end entity may submit a message via HTTP to the server -as follows: - -GET /cgi-bin/pkiclient.exe?operation=PKIOperation&message=MIAGCSqGSIb3D -QEHA6CAMIACAQAxgDCBzAIBADB2MGIxETAPBgNVBAcTCE ......AAAAAA== - -3.2 Response Message Format - -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. The following is an -example of the response: - - - -Liu/Madson/McGrew/Nourse [Page 14] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -"Content-Type:application/x-pki-message\n\n" - -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 send back in the response, and the -response has the content type tagged as application/x-x509-ca-cert. the -body of the response is a DER encoded binary X.509 certificate. For -example: - - "Content-Type:application/x-x509-ca-cert\n\n" - -If there is an RA, the RA certificates are send back together with the -CA certificates, a certificate-only PKCS#7 SignedData is send back in -the response where the SignerInfo is empty. Section 5 has the detailed -definition of the message format in this case. The content type is -application/x-x509-ca-ra-cert. - -Section 4 Secure Transportation: PKCS#7 - -PKCS#7 is a general enveloping mechanism that enables both signed and -encrypted transmission of arbitrary data. It is widely implemented and -included in the RSA tool kit. - -In this section, the general PKCS#7 enveloped PKI message format is -specified. The complete PKCS#7 message format for each PKI transaction -will be covered in Section 5. - -4.1 SCEP Message Format - -As a transaction message, a SCEP message has a set of transaction -specific attributes and an information portion. Employing PKCS#7 -protocol, the transaction specific attributes are encoded as a set of -authenticated attributes of the SignedData. The information portion will -first be encrypted to become Enveloped Data, and then the digest of the -enveloped information portion is included as one of the message digest -attributes and being signed together with the other transaction specific -attributes. - -By applying both enveloping and signing transformations, a SCEP message -is protected both for the integrity of its end-end-transition -information and the confidentiality of its information portion. The -advantage of this technique over the conventional transaction message -format is that, the signed transaction type information and the status -of the transaction can be determined prior to invoke security handling -procedures specific to the information portion being processed. - -The following is an example of a SCEP message with its enveloped and -signed data portion represented by pkcsPKISigned and -pkcsPKIEnveloped. The out-most of any PKI message is a blob of -ContentInfo, with its content type set to SignedData and the actual -signed data as the content. - - -Liu/Madson/McGrew/Nourse [Page 15] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - pkiMessage ContentInfo ::= { - contentType {pkcs-7 signedData(2)} - content pkcsPKISigned - } - pkcsPKISigned SignedData ::= { - version 1 - digestAlgorithm { iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} -- data content identifier - content pkcsPKIEnvelope -- enveloped information portion - } - certificates -- signer certificate chain - signerInfo -- including signed transaction info and the digest - -- of the enveloped information portion as the - -- authenticated attributes - } - pkcsPKIEnveloped EnvelopedData ::= { - version 0 - recipientInfos -- information required to open the envelop - encryptedContentInfo { - contentType {pkcs-7 1} -- data content identifier - contentEncryptionAlgorithm - encryptedContent -- encrypted information portion - } - } - -4.2 Signed Transaction Attributes - -The following transaction attributes are encoded as authenticated -attributes. Please refer to Appendix B for the OID definitions. - -transactionID PrintableString -- Decimal value as a string - messageType PrintableString -- Decimal value as a string - pkiStatus PrintableString -- Decimal value as a string - failinfo PrintableString -- Decimal value as a string - senderNonce Octet String - recipientNonce Octet String - -where: - - The transactionID is an attribute which uniquely identify a - transaction. This attribute is required in all PKI messages. - - The messageType attribute specify the type of operation performed by the - transaction. This attribute is required in all PKI - messages. Currently, the following message types are defined: - - PKCSReq (19) -- Permits use of PKCS#10 certificate request - CertRep (3) -- Response to certificate or CRL request - GetCertInitial (20) -- Certificate polling in manual enrollment - GetCert (21) -- Retrieve a certificate - - -Liu/Madson/McGrew/Nourse [Page 16] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - GetCRL (22) -- Retrieve a CRL - - All response message will include transaction status information which - is defined as pkiStatus attribute: - - SUCCESS (0) -- request granted - FAILURE (2) -- request rejected - PENDING (3) -- request pending for manual approval. - - If the status in the response is FAILURE, the failinfo attribute will - contain one of the following failure reasons: - - badAlg (0) -- Unrecognized or unsupported algorithm ident - badMessageCheck (1) -- integrity check failed - badRequest (2) -- transaction not permitted or supported - badTime (3) -- Message time field was not sufficiently close - to the system time - badCertId (4) -- No certificate could be identified matching - the provided criteria - - The attributes of senderNonce and recipientNonce are the 16 byte - random numbers generated for each transaction to prevent the replay - attack. - -When an end entity sends a PKI message to the server, a senderNonce is -included in the message. After the server processes the request, it will -send back the end entity senderNonce as the recipientNonce and generates -another nonce as the senderNonce in the response message. Because the -proposed pki protocol is a two-way communication protocol, it is clear -that the nonce can only be used by the end entity to prevent the -replay. The server has to employ extra state related information to -prevent a replay attack. - -Section 5. SCEP Transaction Specification - -In this section each SCEP transaction is specified in terms of the -complete messages exchanged during the transaction. - -5.1 Certificate Enrollment - -The certificate enrollment transaction consists of one PKCSReq message -send to the certificate authority from an end entity, and one CertRep -message send back from the server. The pkiStatus returned in the -response message is either SUCCESS, or FAILURE, or PENDING. The -information portion of a PKCSReq message is a PKCS#10 certificate -request, which contains the subject Distinguished Name, the subject -public key, and two attributes, a ChallangePassword attribute to be used -for revocation, and an optional ExtensionReq attribute which will be a -sequence of extensions the end entity expects to be included in its V3 -certificate extensions. One of the extension attribute specifies the key -usage. The pkiStatus is set to SUCCESS when the certificate is send -back in CertRep; the pkiStatus is set to FAILURE when the certificate - - -Liu/Madson/McGrew/Nourse [Page 17] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -request is rejected; the pkiStatus is set to PENDING when the server has -decided to manually authenticate the end entity. The messages exchanged -in the manual authentication mode is further specified in Section 5.2. - -Precondition: - Both the end entity and the certificate authority have completed their - initialization process. The end entity has already been configured - with the CA/RA certificate. - -Postcondition: - Either the certificate is received by the end entity, or the end - entity is notified to do the manual authentication, or the request - is rejected. - -5.1.1 PKCSReq Message Format - -A PKCSReq message is created by following the steps defined below: - -1. Create a PKCS#10 certificate request which is signed by the end - entity's private key, corresponding to the public key included in - the PKCS#10 certificate request. This constitutes the information - portion of PKCSReq. - -2. Encrypt the PKCS#10 certificate request using a randomly generated - content-encryption key. This content-encryption key is then - encrypted by the CA's* public key and included in the recipientInfo. - This step completes the "envelope" for the PKCS#10 certificate - request. - -3. Generate a unique string as the transaction id. - -4. Generate a 16 byte random number as senderNonce. - -5. Generate message digest on the enveloped PKCS#10 certificate request - using the selected digest algorithm. - -6. Create SignedData by adding the end entity's self-signed certificate - as the signer's public key certificate. Include the message type, - transaction id, the senderNonce and the message digest as the - authenticated attributes and sign the attributes using the end - entity's private key. This completes the SignedData. - -7. The SignedData is prepended with the ContenInfo blob which indicates - a SignedData object. This final step completes the create of a - complete PKCSReq PKI message. - -In the following, the PKCSReq message is defined following the ASN.1 -notation. - -For readability, the values of a field is either represented by a quoted -string which specifies the intended value, or a constant when the value -is known. - - -Liu/Madson/McGrew/Nourse [Page 18] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - -- PKCSReq information portion - pkcsCertReq CertificationRequest ::= { -- PKCS#10 - version 0 - subject "the end entity's subject name" - subjectPublicKeyInfo { - algorithm {pkcs-1 1} -- rsa encryption - subjectPublicKey "DER encoding of the end entity's public key" - } - attributes { - challengePassword {{pkcs-9 7} "password string" } - extensions - } - signatureAlgorithm {pkcs-1 4} -- MD5WithRSAEncryption - signature "bit string which is created by signing inner content - of the defined pkcsCertReq using end entity's private - key, corresponding to the public key included in - subjectPublicKeyInfo." - } - -- Enveloped information portion - pkcsCertReqEnvelope EnvelopeData ::= { -- PKCS#7 - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the CA issuer name" - serialNumber "the CA certificate serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} -- rsa encryption - encryptedKey "content-encryption key - encrypted by CA public key" - } - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "object identifier - for DES encryption" - encryptedContent "encrypted pkcsCertReq using the content- - encryption key" - } - } - -- Signed PKCSReq - pkcsCertReqSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} -- data content identifier - content pkcsCertReqEnvelope - } - certificate { -- the end entity's self-signed certificate - version 3 - serialNumber "the transaction id associated with enrollment" - signature {pkcs-1 4} -- md5WithRSAEncryption - - -Liu/Madson/McGrew/Nourse [Page 19] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - issuer " the end entity's subject name" - validity { - notBefore "a UTC time" - notAfter "a UTC time" - } - subject "the end entity's subject name" - subjectPublicKeyInfo { - algorithm {pkcs-1 1} - subjectPublicKey "DER encoding of end entity's public key" - } - signatureAlgorithm {pkcs-1 4} - signature "the signature generated by using the end entity's - private key corresponding to the public key in - this certificate." - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the end entity's subject name" - serialNumber "the transaction id associated - with the enrollment" - } - digestAlgorithm {iso(0) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "an octet string"} - transaction-id {{id-attributes transId(7)} "printable - string"} - -- this transaction id will be used - -- together with the subject name as - -- the identifier of the end entity's key - -- pair during enrollment - messageType {{id-attributes messageType(2)} "PKCSReq"} - senderNonce {{id-attributes senderNonce(5)} - "a random number encoded as a string"} - } - digestEncryptionAlgorithm {pkcs-1 1} -- rsa encryption - encryptedDigest "encrypted digest of the authenticated - attributes using end entity's private key" - } - } - pkcsReq PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsCertRepSigned - } - - - - - - - - -Liu/Madson/McGrew/Nourse [Page 20] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -5.1.2 CertRep Message Format - -The response to an SCEP enrollment request is a CertRep message. - -5.1.2.1 PENDING Response - -When the CA is configured to manually authenticate the end entity, -the CertRep is returned with the attribute pkiStatus set to PENDING. -The data portion for this message is null. Only the transaction -required attributes are sent back. - -CertRepSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo {contentType {pkcs-7 1} -- empty content - } - signerInfo { - version 1 - issuerAndSerialNumber { -| issuer "name of CA that issued the CA [RA] cert" -| serialNumber "the serial number of the CA [RA] cert" - } - digestAlgorithm (iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} NULL} - messageType {{id-attribute messageType(0)} "CertRep"} - transaction-id {{id-attributes transid(7)} "printablestring"} - --- same transaction id used in PKCSReq - pkiStatus {{id-attributes pkiStatus(3)} "PENDING"} - recipientNonce {{id-attributes recipientNonce(6)}<16 bytes>} - senderNonce {{id-attributes senderNonce(5)} <16 bytes>} - } - digestEncrytionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted message digest of the authenticated -| attributes using the CA's [RA's] private key" - } -} -CertRep PKIMessage ::= { - contentType {pkcs-7 2} - content CertRepSigned -} - -5.1.2.2 Failure Response - -In this case, the CertRep sent back to the end entity is same as in -the PENDING case, except that the pkiStatus attribute is set to FAILURE, -and the failInfo attribute should be included: - - pkistatus {{id-attributes pkiStatus(3)} "FAILURE"} - failInfo {{id-attributes failInfo(4)} "the reason to reject"} - -Liu/Madson/McGrew/Nourse [Page 21] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -5.1.2.3 SUCCESS response - -In this case, the information portion of CertRep will be a degenerated -PKCS#7 which contains the end entity's certificate. It is then enveloped -and signed as below: - -pkcsCertRep SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { -- empty content since this is degenerated PKCS#7 - contentType {pkcs-7 1} - } - certificates { - certificate { -- issued end entity's certificate - version 3 - serialNumber "issued end entity's certificate serial number" - signature {pkcs-1 4} -- md5WithRSAEncryption - issuer "the certificate authority issuer name" - validity { - notBefore "UTC time" - notAfter "UTC time" - } - subject "the end entity subject name as given in PKCS#10" - subjectPublicKeyInfo { - algorithm {pkcs-1 1} - subjectPublicKey "a DER encoding of end entity public - key as given in PKCS#10" - } - extensions " the extensions as given in PKCS#10" - signatureAlgorithm {pkcs-1 4} - signature " the certificate authority signature" - } - certificate "the certificate authority certificate" -| certificate "the registration authority certificate (if -applicable)" - } -} -pkcsCertRepEnvelope EnvelopedData ::= { -- PKCS#7 - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { -- use issuer name and serial number as - -- conveyed in end entity's self-signed - -- certificate, included in the PKCSReq - issuer "the end entity's subject name" - serialNumber "the serial number defined by the end entity in - its self-signed certificate" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted by the end entity's - public key which is same key as authenticated in - the end entity's certificate" - } - -Liu/Madson/McGrew/Nourse [Page 22] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - encryptedContentInfo { - contentType {pkcs-7 1} -- data content identifier - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted pkcsCertRep using content encryption - key" - } -} -pkcsCertRepSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - content pkcsCertRepEnvelope - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the certificate authority issuer name" - serialNumber "the CA certificate's serial number" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "a octet string"} - messageType {{id-attribute messageType(2)} "CertRep"} - transaction-id {{id-attributes transId(7)} "printable - string"} - -- same transaction id as given in PKCSReq - pkiStatus {{id-attributes pkiStatus(3) "SUCCESS"} - recipientNonce {{id-attribute recipientNonce(6)}<16 bytes>} - senderNonce {{ id-attributes senderNonce(5) <16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticate attributes - using CA's private key " - } -} -CertRep PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsCertRepSigned -} - -5.2 Poll for End Entity Initial Certificate - -Either triggered by the PENDING status received from the CertRep, or by -the non-response timeout for the previous PKCSReq, an end entity will -enter the polling state by periodically sending GetCertInitial to the -server, until either the request is granted and the certificate is sent -back, or the request is rejected, or the the configured time limit for -polling is exceeded. - - -Liu/Madson/McGrew/Nourse [Page 23] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - -Since GetCertInitial is part of the enrollment, the messages exchanged -during the polling period should carries the same transaction identifier -as the previous PKCSReq. - -PreCondition - Either the end entity has received a CertRep with pkiStatus set to be - PENDING, or the previous PKCSReq has timed out. - -PostContition - The end entity has either received the certificate, or be rejected of - its request, or the polling period ended as a failure. - -5.2.1 GetCertInitial Message Format - -|Since at this time the certificate has not been issued, the end entity -|can only use the end entity's subject name, combined with the -|transaction identifier, to identify the polled certificate request. - -|The certificate authority server must be able to uniquely identify the -|polled certificate request. A subject name can have more than one -|outstanding certificate request (with different key usage attributes). - --- Information portion - -pkcsGetCertInitial issuerAndSubject ::= { - issuer "the certificate authority issuer name" - subject "the end entity subject name as given in PKCS#10" -} -pkcsGetCertInitialEnvelope EnvelopedData ::= { - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the CA issuer name" - serialNumber "the CA certificate serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted by CA's public key" - } - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted getCertInital" - } -} -pkcsGetCertInitialSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - - -Liu/Madson/McGrew/Nourse [Page 24] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - content pkcsGetCertIntialEnvelope - } - certificate { -- the end entity's self-signed certificate - version 3 - serialNumber "the transaction id associated with enrollment" - signature {pkcs-1 4} -- md5WithRSAEncryption - issuer " the end entity's subject name" - validity { - notBefore "a UTC time" - notAfter "a UTC time" - } - subject "the end entity's subject name" - subjectPublicKeyInfo { - algorithm {pkcs-1 1} - subjectPublicKey "DER encoding of end entity's public key" - } - signatureAlgorithm {pkcs-1 4} - signature "the signature generated by using the end entity's - private key corresponding to the public key in - this certificate." - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "end entity's subject name" - serialNumber "the transaction id used in previous PKCSReq" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "an octet string"} - -- digest of getCertInitial - messageType {{id-attribute messageType(2)} "GetCertInitial"} - transaction-id {{id-attributes transId(7)} "printable - string"} - -- same transaction idused in previous PKCSReq - senderNonce {{id-attribute senderNonce(3)} 0x<16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticateAttributes" - } -} -GetCertInitial PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsGetCertInitialSigned -} - - - -5.2.2 GetCertInitial Response Message Format - -The response messages for GetCertInitial are the same as for PKCSReq. - -Liu/Madson/McGrew/Nourse [Page 25] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -5.3 Certificate Access - -The certificate query message defined in this section is an option when -the LDAP server is not available to provide the certificate query. An -end entity should be able to query an issued certificate from the -certificate authority, as long as the issuer name and the issuer -assigned certificate serial number is known to the requesting end -entity. This transaction is not intended to provide the service as a -certificate directory service. A more complicated query mechanism would -have to be defined in order to allow an end entity to query a certificate -using various different fields. - -This transaction consists of one GetCert message send to the server by -an end entity, and one CertRep message send back from the server. - -PreCondition - The queried certificate have been issued by the certificate authority - and the issuer assigned serial number is known. - -PostContition - Either the certificate is send back or the request is rejected. - - -5.3.1 GetCert Message Format - -The queried certificate is identified by its issuer name and the issuer -assigned serial number. If this is a query for an arbitrary end entity's -certificate, the requesting end entity should includes its own CA issued -certificate in the signed envelope. If this is a query for its own -certificate (assume the end entity lost the issued certificate, or does -not have enough non-volatile memory to save the certificate), then the -self-signed certificate has to be included in the signed envelope. - - pkcsGetCert issuerAndSerialNumber ::= { - issuer "the certificate issuer name" - serialNumber "the certificate serial number" - } - pkcsGetCertEnvelope EnvelopedData ::= { - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the CA [RA] issuer name" - serialNumber "the CA [RA] certificate serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted - by CA [RA] public key" - } - - - - - -Liu/Madson/McGrew/Nourse [Page 26] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted pkcsGetCert using the content - encryption key" - } - } - pkcsGetCertSigned SignedData ::= { - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - content pkcsGetCertEnvelope - } - certificates { - certificate "CA issued certificate" - or "self-signed certificate" - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the end entity's subject name" - serialNumber "end entity's certificate serial number" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "an octet string"} - -- digest of pkcsGetCertEnvelope - messageType {{id-attribute messageType(2)} "GetCert"} - transaction-id {{id-attributes transId(7)} "printable - string"} - senderNonce {{id-attribute senderNonce(3)} <16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticateAttributes" - } - } - GetCert PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsGetCertSigned - } - - - - - - - - - -Liu/Madson/McGrew/Nourse [Page 27] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - -5.3.2 CertRep Message Format - -In this case, the CertRep from the server is same as the CertRep for the -PKCSReq, except that the server will only either grant the request or -reject the request. Also, the recipientInfo should use the CA issuer -name and CA assigned serial number to identify the end entity's key pair -since at this time, the end entity has received its own certificate. - -5.4 CRL Access - -The CRL query message defined in this section is an option when the LDAP -server is not available to provide the CRL query. In the PKI protocol -proposed here, only the end entity can initiate the transaction to -download CRL. An end entity send GetCRL request to the server and the -server send back CertRep whose information portion is a degenerated -PKCS#7 which contains only the most recent CRL. The size of CRL included -in the CertRep should be determined by the implementation. - -PreCondition - The certificate authority certificate has been downloaded to the end - entity. - -PostCondition - CRL send back to the end entity. - -5.4.1 GetCRL Message format - -The CRL is identified by using both CA's issuer name and the CA -certificate's serial number: - - pkcsGetCRL issuerAndSerialNumber { - issuer "the certificate authority issuer name" - serialNumber "certificate authority certificate's serial number" - } - -When the CRLDistributionPoint is supported, the pkcsGetCRL is defined as -the following: - - pkcsGetCRL SEQUENCE { - crlIssuer issuerAndSerialNumber - distributionPoint CE-CRLDistPoints - } - -where CE-CRLDisPoints is defined in X.509, but must contain only one -CRL distribution point. - - - - - - - - - - -Liu/Madson/McGrew/Nourse [Page 28] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - pkcsGetCRLEnvelope EnvelopedData ::= { - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the certificate authority (or RA) issuer name" - serialNumber "the CA (RA) certificate's serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted by CA (RA) public key" - } - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted pkcsGetCRL" - } - } - pkcsGetCRLSigned SignedData ::= { - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - content pkcsGetCRLEnvelope - } - certificates { - certificate "CA-issued or self-signed end entity's certificate" - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the end entity's issuer name" - serialNumber "the end entity's certificate serial number" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} 0x<16/20 bytes>} - -- digest of pkcsGetCRLEnvelope - messageType {{id-attribute messageType(2)} "CertCRL"} - transaction-id {{id-attributes transId(7)} "printable - string"} - senderNonce {{id-attribute senderNonce(3)} <16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticateAttributes" - } - } - GetCRL PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsGetCRLSigned - } - -Liu/Madson/McGrew/Nourse [Page 29] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - -5.4.2 CertRep Message Format - -The CRL is send back to the end entity through CertRep message. The -information portion of this message is a degenerated PKCS#7 SignedData -which contains only a CRL. - - pkcsCertRep SignedData ::= { - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - } - crl { - signature {pkcs-1 4} - issuer "the certificate authority issuer name" - lastUpdate "UTC time" - nextUpdate "UTC time" - revokedCertificate { - -- the first entry - userCertificate "certificate serial number" - revocationData "UTC time" - .... - -- last entry - userCertificate "certificate serial number" - revocationData "UTC time" - } - } - pkcsCertRepEnvelope EnvelopedData ::= { - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the end entity's issuer name" - serialNumber "the end entity certificate serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted by end entity's - public key " - } - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted pkcsCertRep using end entity's - public key" - } - } - - - - - - -Liu/Madson/McGrew/Nourse [Page 30] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - - pkcsCertRepSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - content pkcsCertRepEnvelope - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the certificate authority issuer name" - serialNumber "the CA certificate's serial number" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "an octet string"} - -- digest of pkcsCertRepEnvelope - messageType {{id-attribute messageType(2)} "CertRep"} - transaction-id {{id-attributes transId(7)} "printable - string"} - -- same transaction id as given in PKCSReq - pkiStatus {{id-attributes pkiStatus(3) "SUCCESS"} - recipientNonce{{id-attribute recipientNonce(6)}<16 bytes>} - senderNonce {{id-attribute senderNonce (5) 0x<16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticatedAttributes - using CA private key" - } - } - - -NOTE:The PKCS#7 EncryptedContent is specified as an octet string, but -SCEP entities must also accept a sequence of octet strings as a valid -alternate encoding. - -This alternate encoding must be accepted wherever PKCS #7 Enveloped -Data is specified in this document. - - - - - - - - - - - -Liu/Madson/McGrew/Nourse [Page 31] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -5.5 Get Certificate Authority Certificate - -Before any transaction begins, end entities have to get the CA (and -possibly RA) certificate(s) first. Since no public keys have been -exchanged, the message can not be encrypted and the response must be -authenticated by out-of-band means. These certs are obtained by means -of an HTTP GET message. To get the CA certificate, the end entity does a -"HTTP GET" and receives a plain X.509 certificate in response. In the -request, the URL identifies a CGI script on the server and passes the CA -issuer identifier as the parameter to the CGI script. Once the CA -certificate is received by the end entity, a fingerprint is generated -using MD5 hash algorithm on the whole CA certificate. This fingerprint -is verified by some positive out-of-band means, such as a phone call. - - -5.5.1 GetCACert HTTP Message Format - "GET" CGI-PATH CGI-PROG "?operation=GetCACert" "&message=" CA-IDENT - where: - CGI-PATH defines the actual CGI path to invoke the CGI program - which parses the request. - CGI-PROG is set to be the string "pkiclient.exe" and this is - expected to be the program that the CA will use to handle the - SCEP transactions. - CA-IDENT is any string which is understood by the CA. - For example, it could be a domain name like ietf.org. - If a certificate authority has multiple root certificates - this field can be used to distinguish which is required. - Otherwise it may be ignored. - -5.5.2 Response - -The response for GetCACert is different between the case where the CA -directly communicated with the end entity during the enrollment, and the -case where a RA exists and the end entity communicates with the RA -during the enrollment. - -5.5.2.1 CA Certificate Only Response - -A binary X.509 CA certificate is send back as a MIME object with a -Content-Type of application/x-x509-ca-cert. - -5.5.2.2 CA and RA Certificates Response - -When an RA exists, both CA and RA certificates must be sent back in -the response to the GetCACert request. The RA certificate(s) must be -signed by the CA. A certificates-only PKCS#7 SignedData is used to -carry the certificates to the end entity, with a Content-Type of -application/x-x509-ca-ra-cert. - - - - - - - - -Liu/Madson/McGrew/Nourse [Page 32] - -|5.6 Get Certificate Authority Certificate Chain -| -|In order to support Certificate Authority hierarchies, it is necessary -|to have a way to get the entire certificate chain. The following message -|has been added to SCEP for this purpose. -| -|5.6.1 GetCACertChain HTTP Message Format -| -| "GET" CGI-SCRIPT "?" "operation=GetCACertChain" "&" "message" CA-IDENT -| where CGI-SCRIPT and CA-IDENT are as described for GetCACert. -| -|5.6.2 Response -| -|The response for GetCACertChain is a certificates-only PKCS#7 SignedData -|to carry the certificates to the end entity, with a Content-Type of -|application/x-x509-ca-ra-cert-chain. -| -|5.6.3 Backwards Compatability -| -|Versions of SCEP prior to revision 3 do not support GetCACertChain. -|Certificate Authorities written to these prior versions will not be -|able to process the message and may return an HTML error. -| -|To avoid this, clients should send the GetCACert message first. If the -|returned certificate is self-signed or is signed by a Certificate -|Authority that is trusted by the client, then it is not necessary to -|send the GetCACertChain message and it should not be sent. -| -|If a Certificate Authority is configured with a certificate that is -|not either self-signed or has a self-signed issuer, then it should -|support this message. In other words, it should be supported if the -|CA hierarchy is more than two-deep. -| -|An old CA in a two-deep hierarchy might still get this message from -|a client if the client did not trust either that CA or its issuer. -|In that event, the certificate cannot be trusted anyway. In any case -|the CA must not crash or hang upon the receipt of the message and the -|client must be able to handle whatever error is returned by the CA, -|including an HTML error or an ungraceful disconnect. - - - - - - - - - - - - - - - - - -Liu/Madson/McGrew/Nourse [Page 33] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -The following is the ASN.1 definition of Cert-Only PKCS#7: - - certOnly SignedData ::= { - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - -contentInfo { - contentType {pkcs-7 1} -- data content identifier - content -- NULL - } - certificates -- the RA and CA certificates. - } - - CARACerts PKIMessage ::= { -- special pki message sent in the clear - contentType {pkcs-7 2} - content certOnly - } - - -6.0 Security Considerations - -This entire document is about security. Common security considerations -such as keeping private keys truly private and using adequate lengths -for symmetric and asymmetric keys must be followed in order to maintain -the security of this protocol. - - -7.0 Intellectual Property - -This protcol includes the optional use of Certificate Revocation List -Distribution Point (CRLDP) technology, which is a patented technology -of Entrust Technologies, Inc. (Method for Efficient Management of -Certificate Revocation Lists and Update Information (U.S. Patent -5,699,431)). Please contact Entrust Technologies, Inc. -(www.entrust.com) for more information on licensing CRLDP technology. - - -8.0 References - -[PKCS7] Kaliski, B., "PKCS #7: Cryptographic Message Syntax Version -1.5", RFC 2315, March 1998. - -[PKCS10] Kaliski, B., "PKCS #10: Certification Request Syntax Version -1.5", RFC 2314, March 1998. - -[RFC2459] Housley, R., ec. al., "Internet X.509 Public Key -Infrastructure Certificate and CRL Profile", RFC 2459, January 1999. - - - - - - -Liu/Madson/McGrew/Nourse [Page 34] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -Appendix A: Cisco End Entity Subject Name Definition - -The ip address and the FQDN of a SCEP client should be included in the -V3 extension subjectAltName. When the subjectAltName extension attribute -is present, both the subjectAltName fields and the subjectName field could -have the IP address and the FQDN information. - -When the X.500 directory is used by the CA to define the name space, the -subject name defined above become a RDN which is part of DN binded to -the end entity's public key in the certificate. - - -A sample of DN assigned by Entrust CA is given below (assume the same -ciscoRouterAlice is used as the end entity defined subject name): - - OU = InteropTesting, O = Entrust Technologies, C = CA - RDN = {"alice.cisco.com", "172.21.114.67", "22334455"} - - -Liu/Madson/McGrew/Nourse [Page 35] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -Appendix B: IPSEC Client Enrollment Certificate Request - -The following is the certificate enrollment request (PKCS#10) as created -by Cisco VPN Client: - ------END NEW CERTIFICATE REQUEST----- - 0 30 439: SEQUENCE { - 4 30 288: SEQUENCE { - 8 02 1: INTEGER 0 - 11 30 57: SEQUENCE { - 13 31 55: SET { - 15 30 53: SEQUENCE { - 17 06 3: OBJECT IDENTIFIER commonName (2 5 4 3) - 22 13 46: PrintableString - : 'For Xiaoyi, IPSEC attrs in alternate name - extn' - : } - : } - : } - 70 30 158: SEQUENCE { - 73 30 13: SEQUENCE { - 75 06 9: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 - 1 1) - 86 05 0: NULL - : } - 88 03 140: BIT STRING 0 unused bits - : 30 81 88 02 81 80 73 DB 1D D5 65 AA EF C7 D4 8E - : AA 6E EB 46 AC 91 2A 0F 50 51 17 AD 50 A2 2A F2 - : CE BE F1 E4 22 8C D7 61 A1 6C 87 61 62 92 CB A6 - : 80 EA B4 0F 09 9D 18 5F 39 A3 02 0E DB 38 4C E4 - : 8A 63 2E 72 8B DC BE 9E ED 6C 1A 47 DE 13 1B 0F - : 83 29 4D 3E 08 86 FF 08 2B 43 09 EF 67 A7 6B EA - : 77 62 30 35 4D A9 0F 0F DF CC 44 F5 4D 2C 2E 19 - : E8 63 94 AC 84 A4 D0 01 E1 E3 97 16 CD 86 64 18 - : [ Another 11 bytes skipped ] - : } - 231 A0 63: [0] { - 233 30 61: SEQUENCE { - 235 06 9: OBJECT IDENTIFIER extensionReq (1 2 840 113549 1 9 - 14) - 246 31 48: SET { - 248 30 46: SEQUENCE { - 250 30 44: SEQUENCE { - 252 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17) - 257 04 37: OCTET STRING - 30 23 87 04 01 02 03 04 81 0D 65 6D 61 69 - - -Liu/Madson/McGrew/Nourse [Page 36] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - 6C 40 69 72 65 2E 63 6F 6D 82 0C 66 71 64 - 6E 2E 69 72 65 2E 63 6F 6D - : } - : } - : } - : } - : } - : } - - 296 30 13: SEQUENCE { - 298 06 9: OBJECT IDENTIFIER md5withRSAEncryption (1 2 840 113549 - 1 1 4) - 309 05 0: NULL - : } - 311 03 129: BIT STRING 0 unused bits - : 19 60 55 45 7F 72 FD 4E E5 3F D2 66 B0 77 13 9A - : 87 86 75 6A E1 36 C6 B6 21 71 68 BD 96 F0 B4 60 - : 95 8F 12 F1 65 33 16 FD 46 8A 63 19 90 40 B4 B7 - : 2C B5 AC 63 17 50 28 F0 CD A4 F0 00 4E D2 DE 6D - : C3 4F F5 CB 03 4D C8 D8 31 5A 7C 01 47 D2 2B 91 - : B5 48 55 C8 A7 0B DD 45 D3 4A 8D 94 04 3A 6C B0 - : A7 1D 64 74 AB 8A F7 FF 82 C7 22 0A 2A 95 FB 24 - : 88 AA B6 27 83 C1 EC 5E A0 BA 0C BA 2E 6D 50 C7 - : } - - -Appendix C: Private OID Definitions - -The OIDs used in defining pkiStatus are VeriSign self-maintained -OIDs. Please note, work is in progress to replace the VeriSign owned -object identifiers with the standard object identifiers. Once the -standarlization is completed, this documentation will be updated. - -id-VeriSign OBJECT_IDENTIFIER ::= {2 16 US(840) 1 VeriSign(113733)} -id-pki OBJECT_IDENTIFIER ::= {id-VeriSign pki(1)} -id-attributes OBJECT_IDENTIFIER ::= {id-pki attributes(9)} -id-messageType OBJECT_IDENTIFIER ::= {id-attributes messageType(2)} -id-pkiStatus OBJECT_IDENTIFIER ::= {id-attributes pkiStatus(3)} -id-failInfo OBJECT_IDENTIFIER ::= {id-attributes failInfo(4)} -id-senderNonce OBJECT_IDENTIFIER ::= {id-attributes senderNonce(5)} -id-recipientNonce OBJECT_IDENTIFIER ::= {id-attributes recipientNonce(6)} -id-transId OBJECT_IDENTIFIER ::= {id-attributes transId(7)} -id-extensionReq OBJECT_IDENTIFIER ::= {id-attributes extensionReq(8)} - - -Liu/Madson/McGrew/Nourse [Page 37] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - Appendix D: CRL Query by means of LDAP - - In order to retrieve the CRL by means of LDAP, the client needs to know - where in the directory it is stored. The certificate must contain a - CRL Distribution Point extension encoded as a DN or as an LDAP URI. - -For example, the certificate issued by Entrust VPN contains -the following DN as the CRL distribution point: - - - -CN = CRL1, O = cisco, C = US. - - The asn.1 encoding of this distribution point is: - - 30 2C 31 0B 30 09 06 03 55 04 06 13 02 55 53 31 0E 30 0C 06 - 03 55 04 0A 13 05 63 69 73 63 6F 31 0D 30 0B 06 03 55 04 03 - 13 04 43 52 4C 31 - - -The ldap form would be: - -ldap://servername/CN=CRL1,O=cisco,C=US - - - -Appendix E: SCEP State Transitions - -SCEP state transitions are based on transaction identifier. The design -goal is to ensure the synchronization between the CA and the end entity -under various error situations. - - -An identity is defined by the combination of FQDN, the IP address and -the client serial number. FQDN is the required name attribute. It is -important to notice that, a client named as Alice.cisco.com is different -from the client named as Alice.cisco.com plus IPAddress 171.69.1.129. - -Each enrollment transaction is uniquely associated with a transaction -identifier. Because the enrollment transaction could be interrupted by -various errors, including network connection errors or client reboot, -the SCEP client generates a transaction identifier by calculating MD5 -hash on the public key value for which the enrollment is requested. This -retains the same transaction identifier throughout the enrollment -transaction, even if the client has rebooted or timed out, and issues a -new enrollment request for the same key pair. It also provides the way -for the CA to uniquely identify a transaction in its database. At the -end entity side, it generates a transaction identifier which is included -in PKCSReq. If the CA returns a response of PENDING, the end entity -will poll by periodically sending out GetCertInitial with the same -transaction identifier until either a response other than PENDING is -obtained, or the configured maximum time has elapsed. - -If the client times out or the client reboots, the client administrator -will start another enrollment transaction with the same key pair. The -second enrollment will have the transaction idenifier. At the server -side, instead of accepting the PKCSReq as a new enrollment request, it -should respond as if another GetCertInitial message had been sent with -that transaction ID. In another word, the second PKCSReq should be -taken as a resynchronization message to allow the enrollment resume as -the same transaction. - -It is important to keep the transaction id unique since CEP requires the -same policy and same identity be applied to the same subject name and - - -Liu/Madson/McGrew/Nourse [Page 38] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -key pair binding. In the current implementation, an SCEP client can -only assume one identity. At any time, only one key pair, with a given -key usage, can be associated with the same identity. - -The following gives several example of client to CA transactions. - -Client actions are indicated in the left column, CA actions are -indicated in the right column. A blank action signifies that no message -was received. Note that these examples assume that the CA enforces the -certificate-name uniqueness property defined in Section 2.1.1.1. - -The first transaction, for example, would read like this: - "Client Sends PKCSReq message with transaction ID 1 to the - CA. The CA signs the certificate and constructs a CertRep Message - containing the signed certificate with a transaction ID 1. The client - receives the message and installs the cert locally." - -Successful Enrollment Case: no manual authentication -PKCSReq (1) ----------> CA Signs Cert -Client Installs Cert <---------- CertRep (1) SIGNED CERT - - - -Successful Enrollment Case: manual authentication required -PKCSReq (10) ----------> Cert Request goes into Queue -Client Polls <---------- CertRep (10) PENDING -GetCertInitial (10) ----------> Still pending -Client Polls <---------- CertRep (10) PENDING -GetCertInitial (10) ----------> Still pending -Client Polls <---------- CertRep (10) PENDING -GetCertInitial (10) ----------> Still pending -Client Polls <---------- CertRep (10) PENDING -GetCertInitial (10) ----------> Cert has been signed -Client Installs Cert <---------- CertRep (10) SIGNED CERT - - - -Resync Case - CA Receive and Signs PKCSReq, Client Did not receive -CertRep: - -PKCSReq (3) ----------> Cert Request goes into queue - <---------- CertRep (3) PENDING -GetCertInitial (3) ----------> - <---------- CertRep (3) PENDING -GetCertInitial (3) -----------> - <----------- CA signed Cert and send back - CertRep(3) -(Time Out) -PKCSReq (3) ----------> Cert already signed, send back to - client -Client Installs Cert <---------- CertRep (3) SIGNED CERT - - - -Liu/Madson/McGrew/Nourse [Page 39] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - - -Case when NVRAM is lost and client has to generate a new key pair, there -is no change of name information: - -PKCSReq (4) ----------> CA Signs Cert -Client Installs Cert <---------- CertRep (4) SIGNED CERT -(Client looses Cert) -PKCSReq (5) ----------> There is already a valid cert with - this DN. -Client Admin Revokes <---------- CertRep (5) OVERLAPPING CERT ERROR -PKCSReq (5) ----------> CA Signs Cert -Client Installs Cert <---------- CertRep (5) SIGNED CERT - - -Case when client admin resync the enrollment using a different PKCS#10: -PKCSReq (6) ----------> CA Signs Cert - <---------- CertRep (6) SIGNED CERT -(Client timeout and admin starts another enrollment with a different - PKCS#10, but the same transaction id) -PKCSReq (6) with different PKCS#10 - ----------> There is already a valid cert with - this entity (by checking FQDN). - <---------- CertRep (6) INVALID PKCS#10 CERT - ERROR -Client admin either revokes the existing cert -or corrects the error by enrolling with -the same PKCS#10 as the first PKCSReq(6) -PKCSReq (6) ----------> CA find the existing Cert -Client Installs Cert <---------- CertRep (6) SIGNED CERT - - -Resync case when server is slow in response: -PKCSReq (13) ----------> Cert Request goes into Queue - <---------- CertRep (13) PENDING -GetCertInitial ----------> Still pending - <---------- CertRep (13) PENDING -GetCertInitial ----------> Still pending - <---------- CertRep (13) PENDING -GetCertInitial ----------> Still pending - <---------- CertRep (13) PENDING -GetCertInitial ----------> Still pending -(TimeOut) <---------- CertRep (13) PENDING -* Case 1 -PKCSReq (13) ----------> Still pending -Client polls <---------- CertRep (13) PENDING -CertCertInitial ----------> Cert has been signed -Client Installs Cert <---------- CertRep (13) SIGNED CERT -* Case 2 -PKCSReq (13) ----------> Cert has been signed -Client Installs Cert <---------- CertRep (13) SIGNED CERT - - - - -Liu/Madson/McGrew/Nourse [Page 40] - -Cisco Systems' Simple Certificate Enrollment Protocol May 2002 - -Appendix F. Author Contact Information - -Xiaoyi Liu Cheryl Madson -Cisco Cisco -170 West Tasman Drive 170 West Tasman Drive -San Jose, CA 94134 San Jose, CA 94134 -xliu@cisco.com cmadson@cisco.com - - -David McGrew Andrew Nourse -Cisco Cisco -170 West Tasman Drive 101 Cooper Street -San Jose, CA 94134 Santa Cruz, CA 95060 -mcgrew@cisco.com nourse@cisco.com - - - - -Appendix G. Copyright Section - -Copyright (C) The Internet Society (2000). All Rights Reserved. - -This document and translations of it may be copied and furnished -to others, and derivative works that comment on or otherwise -explain it or assist in its implmentation may be prepared, copied, -published and distributed, in whole or in part, without -restriction of any kind, provided that the above copyright notice -and this paragraph are included on all such copies and derivative -works. However, this document itself may not be modified in any -way, such as by removing the copyright notice or references to the -Internet Society or other Internet organizations, except as needed -for the purpose of developing Internet standards in which case the -procedures for copyrights defined in the Internet Standards -process must be followed, or as required to translate it into -languages other than English. - -The limited permissions granted above are perpetual and will not -be revoked by the Internet Society or its successors or assigns. - -This document and the information contained herein is provided on -an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET -ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF -THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED -WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - -This draft expires 15-November 2002 - -[End of draft-nourse-scep-07.txt] - - +INTERNET DRAFT Xiaoyi Liu +draft-nourse-scep-06.txt Cheryl Madson +expires 15-November 2002 David McGrew + Andrew Nourse + Cisco Systems + +Category: Informational 15 May 2002 + + +Cisco Systems' Simple Certificate Enrollment Protocol(SCEP): + +Status of this Memo + +This document is an Internet-Draft and is NOT offered in +accordance with Section 10 of RFC2026, and the author does not +provide the IETF with any rights other than to publish as an +Internet-Draft + +Internet-Drafts are working documents of the Internet Engineering +Task Force (IETF), its areas, and its working groups. Note that +other groups may also distribute working documents as +Internet-Drafts. + +Internet-Drafts are draft documents valid for a maximum of six +months and may be updated, replaced, or obsoleted by other +documents at any time. It is inappropriate to use Internet- +Drafts as reference material or to cite them other than as +"work in progress." + +The list of current Internet-Drafts can be accessed at +http://www.ietf.org/ietf/1id-abstracts.txt + +The list of Internet-Draft Shadow Directories can be accessed at +http://www.ietf.org/shadow.html. + +This memo provides information for the Internet community. This memo +does not specify an Internet standard of any kind. Distribution of +this memo is unlimited. + + +Abstract + +This document specifies the Cisco Simple Certificate Enrollment +Protocol, a PKI communication protocol which leverages existing +technology by using PKCS#7 and PKCS#10. SCEP is the evolution of the +enrollment protocol developed by Verisign, Inc. for Cisco Systems, Inc. +It now enjoys wide support in both client and CA implementations. + + +Table of Contents + + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. The Goal of SCEP . . . . . . . . . . . . . . . . . . . . . 3 + 2.1 SCEP Entity types . . . . . . . . . . . . . . . . . . . . 3 + 2.2 SCEP Operations Overview . . . . . . . . . . . . . . . . . 7 + + +Liu/Madson/McGrew/Nourse [Page 2] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + 2.3 PKI Operation Transactional Behavior . . . . . . . . . . . 10 + 2.4 Security . . . . . . . . . . . . . . . . . . . . . . . . . 12 + 3. Transport Protocol . . . . . . . . . . . . . . . . . . . . 13 + 4. Secure Transportation: PKCS #7 . . . . . . . . . . . . . . 14 + 4.1 SCEP Message Format . . . . . . . . . . . . . . . . . . . 14 + 4.2 Signed Transaction Attributes . . . . . . . . . . . . . . 15 + 5. SCEP Transaction Specification . . . . . . . . . . . . . . 16 + 6. Security Considerations . . . . . . . . . . . . . . . . . 33 + 7. Intellectual Propoerty . . . . . . . . . . . . . . . . . . 33 + 8. References . . . . . . . . . . . . . . . . . . . . . . . . 33 + Appendix A. Cisco End Entity Subject Name Definition . . . . . 34 + Appendix B. IPSEC Client Enrollment Certificate Request . . . . 35 + Appendix C. Private OID Definitions . . . . . . . . . . . . . 36 + Appendix D. Obtaining CRL by LDAP Query . . . . . . . . . . . . 36 + Appendix E. SCEP State Transitions . . . . . . . . . . . . . . 37 + Appendix F. Author Contact Information. . . . . . . . . . . . . 40 + Appendix G. Copyright Section . . . . . . . . . . . . . . . . . 40 + + +Section 1. Introduction + +Public key technology is becoming more widely deployed and is becoming +the basis for standards based security, such as the Internet Engineering +Task Force's IPSEC and IKE protocols. With the use of public key +certificates in network security protocols comes the need for a +certificate management protocol that Public Key Infrastructure (PKI) +clients and Certificate Authority servers can use to support certificate +life cycle operations such as certificate enrollment and revocation, and +certificate and CRL access. + +In the following, Section 2 gives an overview of the PKI operations, and +Section 2.4 describes the security goals of the protocol and the +mechanisms used to achieve them. The transport protocol and the +security protocol PKCS#7 are described at Section 3 and Section 4, +respectively. The last section, Section 5, specifies each PKI operation +in terms of the message formats and the data structures of each +operation. + +The appendices provide detailed specifications and examples. End entity +subject names are specified in Appendix A, attribute OIDs are specified +in Appendix C , and the SCEP state transitions are described in Appendix +E. An example of a certificate enrollment request is provided in +Appendix B, and an example LDAP query URL encoding is provided in +Appendix D. + +The authors would like to thank Peter William of ValiCert, Inc. +(formerly of Verisign, Inc) and Alex Deacon of Verisign, Inc. and +Christopher Welles of IRE, Inc. for their contributions to this protocol +and to this document. + + + + +Liu/Madson/McGrew/Nourse [Page 3] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +2.0 The Goal of SCEP +The goal of SCEP is to support the secure issuance of certificates to +network devices in a scalable manner, using existing technology whenever +possible. The protocol supports the following operations: + + CA and RA public key distribution + Certificate enrollment + Certificate revocation + Certificate query + CRL query + +Certificate and CRL access can be achieved by using the LDAP protocol +(as specified in Appendix D), or by using the query messages defined in +SCEP. The use of HTTP certificate and CRL access, and the support of +CDP as specified in RFC2459, will be specified in a future version of +this document. In Section 2.1, we first define PKI entity types as well +as the properties of each entity type. In Section 2.2, the PKI +operations are described at functional level. Section 2.3 describes the +transaction behavior of each PKI operations. The complete PKI messages +are covered in Section 5. + +2.1 SCEP Entity types + +The entity types defined in SCEP are the end entity type (i.e., IPSEC +clients), the Certificate Authority (CA) entity type, and the +Registration Authority entity type (RA). An end entity is sometimes +called a "SCEP client" in the following. + +2.1.1 End Entities + +An end entity is an entity whose name is defined in a certificate +subject name field and optionally, in SubjectAltName, a X.509 +certificate V3 extension. As an end entity, a SCEP client is identified +by a subject name consisting of the following naming attributes: + + Fully qualified domain name, for example, router.cisco.com + IP address, or + Serial number. + +In the paragraph above , the fully qualified domain name is required for +each SCEP client, the IP address and the serial number are optional name +attributes. In the certificate enrollment request, the PKCS#10 subject +field contains the required and optional name attributes. Based on the +PKCS#10 subject name information, the certificate issued to the SCEP +client must have the same name attributes set both in the subjectName +field and in the SubjectAltName extension. + +It is important to note that a client named as Alice.cisco.com is +different than a client named as Alice.cisco.com plus the IP address +name attribute 171.69.1.129. From CA point of view, the Distinguished +names assigned in these two cases are distinct names. + + +Liu/Madson/McGrew/Nourse [Page 4] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +Entity names which are specified as in the IPSEC profile (i.e., FQDN, IP +address and User FQDN) must be presented in certificate's SubjectAltName +extension. Multiple IPSEC entity names, (if any) are encoded as multiple +values of a single SubjectAltName extension. The CA has the authority +to assign a distinguished name to an end entity. The assigned DN should +contain the SCEP client names as the relative DN. + +The attribute identifiers and an example of SCEP client subject name are +specified in Appendix A. Appendix B has an example from Cisco VPN Client +enrollment request. + +2.1.1.1 Local Key/Certificate/CRL Storage and Certificate-name uniqueness + +An end entity is required to generate asymmetric key pairs and to +provide storage to store its private keys. If the end entity does not +have enough permanent memory to save its certificate, the end entity +should be able to query its own certificate from the CA, once the +certificate has been issued. The public key pairs can be generated with +a specific key usage. The key usage are conveyed to the CA through the +certificate enrollment request. All current SCEP client implementations +expect that there will be only one pair of keys for a given subject name +and key usage combination and CA, at any time. This property is called +the certificate-name uniqueness property, and it implies that a CA that +implements SCEP will enforce the unique mapping between a SCEP client +subject name and its key pairs with a given key usage. At any time, if +the subject name is changed, or if the key is updated, the existing +certificate would have to be revoked before a new one could be issued. + +It is desirable that the CA enforce certificate-name uniqueness, but +it is not mandatory. However a CA that does not enforce uniqueness +must provide some other mechanism to prevent the re-transmission of an +enrollment request by a SCEP client from creating a second certificate +or certificate request, nor can the second request merely be rejected. +If a client times out from polling for a pending request it can +resynchronize by reissuing the original request with the original +subject name and transaction ID. This must return the status of the +original transaction, including the certificate if it was granted. +It must not create a new transaction unless the original cert has been +revoked, or the transaction arrives more than halfway through the +validity time of the original certificate. + +An enrollment request that occurs more than halfway through the validity +time of an existing certificate for the same subject name and key usage +MAY be interpreted as a renewal request and accepted regardless of the +duplication of subject name. Certificate renewal can be done this way. + + +2.1.1.2 End entity authentication + +As with every protocol that uses public-key cryptography, the +association between the public keys used in the protocol and the +identities with which they are associated must be authenticated in a + + +Liu/Madson/McGrew/Nourse [Page 5] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +cryptographically secure manner. This requirement is needed to +prevent a "man in the middle" attack, in which an adversary that can +manipulate the data as it travels between the protocol participants +can subvert the security of the protocol. To satisfy this +requirement, SCEP provides two authentication methods: manual +authentication, and authentication based on pre-shared secret. In the +manual mode, the end entity submitting the request is required to wait +until its identity can be verified by the CA operator using any +reliable out-of-band method. To prevent a "man-in-the-middle" attack, +an MD5 `fingerprint' generated on the PKCS#10 (before PKCS #7 +enveloping and signing) must be compared out-of-band between the server +and the end entity. SCEP clients and CAs (or RAs, if appropriate) +must display this fingerprint to a user to enable this verification, +if manual mode is used. Failing to provide this information leaves +the protocol vulnerable to attack by sophisticated adversaries. When +utilizing a pre-shared secret scheme, the server should distribute a +shared secret to the end entity which can uniquely associate the +enrollment request with the given end entity. The distribution of the +secret must be private: only the end entity should know this +secret. The actual binding mechanism between the end entity and the +secret is subject to the server policy and implementation. When +creating enrollment request, the end entity is asked to provide a +challenge password. When using the pre-shared secret scheme, the end +entity must type in the re-distributed secret as the password. In the +manual authentication case, the challenge password is also required +since the server may challenge an end entity with the password before +any certificate can be revoked. Later on, this challenge password +will be included as a PKCS#10 attribute, and is sent to the server as +encrypted data. The PKCS#7 envelope protects the privacy of the +challenge password with DES encryption. + +2.1.1.3 Self-Signed Certificates + +In this protocol, the communication between the end entity and the +certificate authority is secured by using PKCS#7 as the messaging +protocol. PKCS#7, however, is a protocol which assumes the communicating +entities already possess the peer's certificates and requires both +parties use the issuer names and issuer assigned certificate serial +numbers to identify the certificate in order to verify the signature and +decrypt the message. When using PKCS#7 as a secure protocol for SCEP +transactions this assumption may not be valid. To solve this problem, +an end entity generates a self-signed certificate for its own public +key. In this self-signed certificate, the issuer name is the end entity +subject name (the same name later used in the PKCS#10). During the +certificate enrollment, the end entity will first post itself as the +signing authority by attaching the self-signed certificate to the signed +certificate request. When the Certificate Authority makes the envelope +on the issued certificate using the public key included in the +self-signed certificate, it should use the same issuer name and serial +number as conveyed in the self-signed certificate to inform the end +entity on which private key should be used to open the envelope. + +Note that when a client enrolls for Mayarate encryption and signature + +Liu/Madson/McGrew/Nourse [Page 6] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +certificates, it may use the signature certificate to sign both +requests, and then expect its signature key to be used to encrypt +both responses. In any case, the recipientinfo on the envelope should +reflect the key used to encrypt the request. + +2.1.2 Certificate Authority + +A Certificate Authority(CA) is an entity whose name is defined in the +certificate issuer name field. Before any PKI operations can begin, +the CA generates its own public key pair and creates a self-signed CA +certificate, or causes another CA to issue a certificate to it. +Associated with the CA certificate is a fingerprint which will be used +by the end entity to authenticate the received CA certificate if it +is self-signed. The fingerprint is created by calculating a MD5 hash +on the whole CA certificate. Before any end entity can start its +enrollment, this root certificate has to be configured at the entity +side securely. For IPSEC clients, the client certificates must have +SubjectAltName extension. To utilize LDAP as a CRL query protocol, +the certificates must have CRL Distribution Point. Key usage is +optional. Without key usage, the public key is assumed as a general +purpose public key and it can be used for all the purposes. + +A Certificate Authority may enforce certain name policy. When using +X.500 directory name as the subject name, all the name attributes +specified in the PKCS#10 request should be included as Relative DN. All +the name attributes as defined in RFC2459 should be specified in the +SubjectAltName. An example is provided in Appendix A. + + If there is no LDAP query protocol support, the Certificate Authority +should answer certificate and CRL queries, and to this end it should be +online all the time. + +The updating of the CA's public key is not addressed within the SCEP +protocol. An SCEP client can remove its copy of a CA's public key and +re-enroll under the CA's new public key. + +2.1.3 Registration Authorities + +In the environment where a RA is present, an end entity performs +enrollment through the RA. In order to setup a secure channel with RA +using PKCS#7, the RA certificate(s) have to be obtained by the client +in addition to the CA certificate(s). + +In the following, the CA and RA are specified as one entity in the +context of PKI operation definitions. + +2.1.4 Trusted Root Store + +To support interoperability between IPSEC peers whose certificates are +issued by different CA, SCEP allows the users to configure multiple +trusted roots. A root is a trusted root when its certificate has been + + +Liu/Madson/McGrew/Nourse [Page 7] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +configured as such in the client. An SCEP client that supports multiple +roots must associate with each root the information needed to query a +CRL from each root. + +Once a trusted root is configured in the client, the client can verify +the signatures of the certificates issued by the given root. + +2.2 SCEP Operations Overview + +In this section, we give a high level overview of the PKI operations as +defined in SCEP. + +2.2.1 End Entity Initialization + +The end entity initialization includes the key pair generation and the +configuring of the required information to communicate with the +certificate authority. + +2.2.1.1 Key Pair Generation + +Before an end entity can start PKI transaction, it first generates +asymmetric key pairs, using the selected algorithm (the RSA algorithm is +required in SCEP, and is the only algorithm in current implementations). + +An end entity can create one or more asymmetric key pairs, for different +key usage. The key pairs can be created for encryption only, signing +only, or for all purposes. For the same key usage, there can be only +one key pair at any time. + +The key pairs are saved by the client in NVRAM or other non-volatile +media. The identification of a key pair is based on the FQDN assigned to +the client and the selected key usage. Every time a new key pair is +generated to replace the old key pair, the existing certificates have to +be revoked from the CA and a new enrollment has to be completed. + +2.2.1.2 Required Information + +An end entity is required to have the following information configured +before starting any PKI operations: + + 1. the certificate authority IP address or fully qualified domain name, + 2. the certificate authority HTTP CGI script path, and + the HTTP proxy information in case there is no direct Internet + connection to the server, + 3. the CRL query URL, if the CRL is to be obtained by from a directory + server by means of LDAP. + + +2.2.2 CA/RA Certificate Distribution + +Before any PKI operation can be started, the end entity needs to get +the CA/RA certificates. At this time, since no public key has been + + +Liu/Madson/McGrew/Nourse [Page 8] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +exchanged between the end entity and the CA/RA, the message to get the +CA/RA certificate can not be secured using PKCS#7 protocol. Instead, the +CA/RA certificate distribution is implemented as a clear HTTP Get +operation. After the end entity gets the CA certificate, it has to +authenticate the CA certificate by comparing the finger print with the +CA/RA operator. Since the RA certificates are signed by the CA, there is +no need to authenticate the RA certificates. + +This operation is defined as a transaction consisting of one HTTP Get +message and one HTTP Response message: + + END ENTITY CA SERVER + Get CA/RA Cert: HTTP Get message + -----------------------------> + CA/RA Cert download: HTTP Response message + <--------------------------------------- + Compute finger print and + call CA operator. + Receive call and check finger print + +If an RA is in use, a degenerated PKCS#7 with a certificate chain +consisting of both RA and CA certificates is sent back to the end +entity. Otherwise the CA certificate is directly sent back as the +HTTP response payload. + + +2.2.3 Certificate Enrollment + +An end entity starts an enrollment transaction by creating a +certificate request using PKCS#10 and send it to the CA/RA enveloped +using the PKCS#7. After the CA/RA receives the request, it will either +automatically approve the request and send the certificate back, or it +will require the end entity to wait until the operator can manually +authenticate the identity of the requesting end entity. Two +attributes are included in the PKCS#10 certificate request - a +Challenge Password attribute and an optional ExtensionReq attribute +which will be a sequence of extensions the end entity would like to be +included in its V3 certificate extensions. The Challenge Password is +used for revocation and may be used (at the option of the CA/RA) +additionally as a one-time password for automatic enrollment. + +In the automatic mode, the transaction consists of one PKCSReq PKI +Message, and one CertRep PKI message. In the manual mode, the end entity +enters into polling mode by periodically sending GetCertInitial PKI +message to the server, until the server operator completes the manual +authentication, after which the CA will respond to GetCertInitial by +returning the issued certificate. + +The transaction in automatic mode: + + END ENTITY CA SERVER + + +Liu/Madson/McGrew/Nourse [Page 9] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 +PKCSReq: PKI cert. enrollment msg + --------------------------------> CertRep: pkiStatus = SUCCESS + certificate +attached + <------------------------------ + Receive issued certificate. + +The transaction in manual mode: + + END ENTITY CA SERVER + PKCSReq: PKI cert. enrollment msg + --------------------------------> CertRep: pkiStatus = PENDING + <------------------------------ + GetCertInitial: polling msg + --------------------------------> CertRep: pkiStatus = PENDING + <------------------------------ + ................. CertRep: pkiStatus = SUCCESS + certificate +attached + <------------------------------ + Receive issued certificate. + + +2.2.4 End Entity Certificate Revocation + +An end entity should be able to revoke its own certificate. Currently +the revocation is implemented as a manual process. In order to revoke a +certificate, the end entity make a phone call to the CA server +operator. The operator will come back asking the ChallangePassword +(which has been send to the server as an attribute of the PKCS#10 +certificate request). If the ChallangePassword matches, the certificate +is revoked. The reason of the revocation is documented by CA/RA. + + +2.2.5 Certificate Access + +There are two methods to query certificates. The first method is to use +LDAP as a query protocol. Using LDAP to query assumes the client +understand the LDAP scheme supported by the CA. The SCEP client assumes +that the subject DN name in the certificate is used as URL to query the +certificate. The standard attributes (userCertificate and caCertificate) +are used as filter. + +For the environment where LDAP is not available, a certificate query +message is defined to retrieve the certificates from CA. + +To query a certificate from the certificate authority, an end entity +sends a request consisting of the certificate's issuer name and the +serial number. This assumes that the end entity has saved the issuer + + +Liu/Madson/McGrew/Nourse [Page 10] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +name and the serial number of the issued certificate from the previous +enrollment transaction. The transaction to query a certificate consists +of one GetCert PKI message and one CertRep PKI message: + + END ENTITY CA SERVER + GetCert: PKI cert query msg + -------------------------------> CertRep: pkiStatus = SUCCESS + certificate +attached + <----------------------------- + Receive the certificate. + +2.2.6 CRL Distribution + +The CA/RA will not "push" the CRL to the end entities. The query of the +CRL can only be initialized by the end entity. + +There are three methods to query CRL. + +The CRL may be retrieved by a simple HTTP GET. If the CA supports this +method, it should encode the URL into a CRL Distribution Point extension +in the certificates it issues. Support for this method should be +incorporated in new and updated clients, but may not be in older +versions. + +The second method is to query CRL using LDAP. This assumes the CA server +supports CRL LDAP publishing and issues the CRL Distribution Point in +the certificate. The CRL Distribution Point is encoded as a DN. Please +refer to Appendix D for the examples of CRL Distribution Point. + +The third method is implemented for the CA which does not support LDAP +CRL publishing or does not implement the CRL Distribution Point. In this +case, a CRL query is composed by creating a message consists of the CA +issuer name and the CA's certificate serial number. This method is +deprecated because it does not scale well and requires the CA to be a +high-availability service. + +The message is send to the CA in the same way as the other SCEP +requests: The transaction to query CRL consists of one GetCRL PKI +message and one CertRep PKI message which have no certificates but CRL. + + END ENTITY CA SERVER + GetCRL: PKI CRL query msg + ----------------------------------> CertRep: CRL attached + <-------------------------------- + +2.3 PKI Operation Transactional Behavior + +As described before, a PKI operation is a transaction consisting of the +messages exchanged between an end entity and the CA/RA. This section +will specify the transaction behavior on both the end entity and the + + +Liu/Madson/McGrew/Nourse [Page 11] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +certificate authority server. Because the protocol is basically a two +way communication protocol without a confirmation message from the +initiating side, state and state resynchronization rules have to be +defined, in case any error happens at either side. Before the state +transition can be defined, the notion of transaction identifier has to +be defined first. + +2.3.1 Transaction Identifier + +A transaction identifier is a string generated by the entity when +starting a transaction. Since all the PKI operations defined in this +protocol are initiated by the end entity, it is the responsibility of +the end entity to generate a unique string as the transaction +identifier. All the PKI messages exchanged for a given PKI operations +must carry the same transaction identifier. The transaction identifier +is generated as a MD5 hash on the public key value for which the +enrollment request is made. This allows the SCEP client to reuse the +same transaction identifier if it is reissuing a request for the same +certificate (i.e. a certificate with the same subject, issuer, and key). +The SCEP protocol requires that transaction identifiers be unique, so +that queries can be matched up with transactions. For this reason, in +those cases in which Mayarate signing and encryption certificates are +issued to the same end entity, the keys must be different. + +2.3.2 State Transitions in Certificate Enrollment + +The end entity state transitions during enrollment operation is +indicated in the diagram below: + +-<------+ + | | + GetCertInitial triggered by timeout or + | | manual authentication + | | + [CERT-NONEXISTANT] ------> [CERT-REQ-PENDING] ---> [CERT-ISSUED] + | PKCSReq | CertRep with SUCCESS + | | + | | + +--------<-------------------+ + request rejected, timeout, or error + +As described in the section 2.2.3, certificate enrollment starts at the +state CERT-NONEXISTANT. Sending PKCSReq changes the state to +CERT-REQ-PENDING. Receiving CertRep with SUCCESS status changes the +state to CERT-ISSUED. In the case the server sending back the response +with pending status, the end entity will keep polling certificate +response by sending GetCertInitial to the server, until either a CertRep +with SUCCESS status is received, or the maximum polling number has been +exceeded. + +If an error or timeout occurs in the CERT-REQ-PENDING state, the end +entity will transition to the CERT-NONEXISTANT state. + + +Liu/Madson/McGrew/Nourse [Page 12] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + +The client administrator will, eventually, start up another enrollment +request. It is important to note that, as long as the end entity does +not change its subject name or keys, the same transaction id will be +used in the "new" transaction. This is important because based on this +transaction id, the certificate authority server can recognize this as +an existing transaction instead of a new one. + + +2.3.3 Transaction Behavior of Certificate/CRL Access + +There is no state maintained during certificate access and CRL access +transaction. When using the certificate query and CRL query messages +defined in this protocol, the transaction identifier is still required +so that the end entity can match the response message with the +upstanding request message. When using LDAP to query the certificate and +the CRL, the behavior is specified by the LDAP protocol. + +2.4 Security + +The security goals of SCEP are that no adversary can: + +o subvert the public key/identity binding from that intended, +o discover the identity information in the enrollment requests and + issued certificates, +o cause the revocation of certificates with any non-negligible + probability. + +Here an adversary is any entity other than the end entity and the CA +(and optionally the RA) participating in the protocol that is +computationally limited, but that can manipulate data during +transmission (that is, a man-in-the-middle). The precise meaning of +'computationally limited' depends on the implementer's choice of +cryptographic hash functions and ciphers. The required algorithms are +RSA, DES, and MD5. + +The first and second goals are met through the use of PKCS#7 and PKCS#10 +encryption and digital signatures using authenticated public keys. The +CA's public key is authenticated via the checking of the CA fingerprint, +as specified in Section 2.1.2, and the SCEP client's public key is +authenticated through the manual authentication or pre-shared secret +authentication, as specified in Section 2.1.1.2. The third goal is met +through the use of a Challenge Password for revocation, that is chosen +by the SCEP client and communicated to the CA protected by the PKCS#7 +encryption, as specified in Section 2.2.4. + +The motivation of the first security goal is straightforward. The +motivation for the second security goal is to protect the identity +information in the enrollment requests and certificates. For example, +two IPSEC hosts behind a firewall may need to exchange certificates, and +may need to enroll certificates with a CA that is outside of a firewall. +Most networks with firewalls seek to prevent IP addresses and DNS + + +Liu/Madson/McGrew/Nourse [Page 13] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +information from the trusted network leaving that network. The second +goal enables the hosts in this example to enroll with a CA outside the +firewall without revealing this information. The motivation for the +third security goal is to protect the SCEP clients from denial of +service attacks. + + +Section 3 Transport Protocol + +In the SCEP protocol, HTTP is used as the transport protocol for the PKI +messages. + +3.1 HTTP "GET" Message Format + +In the PKI protocol, CA/RA certificates are send to the end entity in +clear, whereas the end entity certificates are send out using the PKCS#7 +secure protocol. This results in two types of GET operations. The type +of GET operation is specified by augmenting the GET message with +OPERATION and MESSAGE parameters in the Request-URL. OPERATION +identifies the type of GET operation, and MESSAGE is actually the PKI +message encoded as a text string. + +The following is the syntax definition of a HTTP GET message send from +an end entity to a certificate authority server: + +Request = "GET " CGI-PATH CGI-PROG "?operation=" OPERATION "&message=" +MESSAGE +where: + CGI-PATH defines the actual CGI path to invoke the CGI program which + parses the request. +| CGI-PROG is set to be the string "pkiclient.exe". This is intended +| to be the program that the CA will use to handle the SCEP transactions, +| though the CA may ignore CGI-PROG and use only the CGI-PATH. + OPERATION is set to be the string "PKIOperation" when the GET message + carries a PKI message to request certificates or CRL; OPERATION is set +| to be the string "GetCACert" or "GetCACertChain" when the GET operation +| is used to get CA/RA certificate or the CA Cert chain (respectively). + When OPERATION is "PKIOperation", MESSAGE is a base64-encoded PKI + message +| when OPERATION is "GetCACert" or "GetCACertChain", MESSAGE is a string +| which represents the certificate authority issuer identifier. + +For example. An end entity may submit a message via HTTP to the server +as follows: + +GET /cgi-bin/pkiclient.exe?operation=PKIOperation&message=MIAGCSqGSIb3D +QEHA6CAMIACAQAxgDCBzAIBADB2MGIxETAPBgNVBAcTCE ......AAAAAA== + +3.2 Response Message Format + +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. The following is an +example of the response: + + + +Liu/Madson/McGrew/Nourse [Page 14] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +"Content-Type:application/x-pki-message\n\n" + +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 send back in the response, and the +response has the content type tagged as application/x-x509-ca-cert. the +body of the response is a DER encoded binary X.509 certificate. For +example: + + "Content-Type:application/x-x509-ca-cert\n\n" + +If there is an RA, the RA certificates are send back together with the +CA certificates, a certificate-only PKCS#7 SignedData is send back in +the response where the SignerInfo is empty. Section 5 has the detailed +definition of the message format in this case. The content type is +application/x-x509-ca-ra-cert. + +Section 4 Secure Transportation: PKCS#7 + +PKCS#7 is a general enveloping mechanism that enables both signed and +encrypted transmission of arbitrary data. It is widely implemented and +included in the RSA tool kit. + +In this section, the general PKCS#7 enveloped PKI message format is +specified. The complete PKCS#7 message format for each PKI transaction +will be covered in Section 5. + +4.1 SCEP Message Format + +As a transaction message, a SCEP message has a set of transaction +specific attributes and an information portion. Employing PKCS#7 +protocol, the transaction specific attributes are encoded as a set of +authenticated attributes of the SignedData. The information portion will +first be encrypted to become Enveloped Data, and then the digest of the +enveloped information portion is included as one of the message digest +attributes and being signed together with the other transaction specific +attributes. + +By applying both enveloping and signing transformations, a SCEP message +is protected both for the integrity of its end-end-transition +information and the confidentiality of its information portion. The +advantage of this technique over the conventional transaction message +format is that, the signed transaction type information and the status +of the transaction can be determined prior to invoke security handling +procedures specific to the information portion being processed. + +The following is an example of a SCEP message with its enveloped and +signed data portion represented by pkcsPKISigned and +pkcsPKIEnveloped. The out-most of any PKI message is a blob of +ContentInfo, with its content type set to SignedData and the actual +signed data as the content. + + +Liu/Madson/McGrew/Nourse [Page 15] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + pkiMessage ContentInfo ::= { + contentType {pkcs-7 signedData(2)} + content pkcsPKISigned + } + pkcsPKISigned SignedData ::= { + version 1 + digestAlgorithm { iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} -- data content identifier + content pkcsPKIEnvelope -- enveloped information portion + } + certificates -- signer certificate chain + signerInfo -- including signed transaction info and the digest + -- of the enveloped information portion as the + -- authenticated attributes + } + pkcsPKIEnveloped EnvelopedData ::= { + version 0 + recipientInfos -- information required to open the envelop + encryptedContentInfo { + contentType {pkcs-7 1} -- data content identifier + contentEncryptionAlgorithm + encryptedContent -- encrypted information portion + } + } + +4.2 Signed Transaction Attributes + +The following transaction attributes are encoded as authenticated +attributes. Please refer to Appendix B for the OID definitions. + +transactionID PrintableString -- Decimal value as a string + messageType PrintableString -- Decimal value as a string + pkiStatus PrintableString -- Decimal value as a string + failinfo PrintableString -- Decimal value as a string + senderNonce Octet String + recipientNonce Octet String + +where: + + The transactionID is an attribute which uniquely identify a + transaction. This attribute is required in all PKI messages. + + The messageType attribute specify the type of operation performed by the + transaction. This attribute is required in all PKI + messages. Currently, the following message types are defined: + + PKCSReq (19) -- Permits use of PKCS#10 certificate request + CertRep (3) -- Response to certificate or CRL request + GetCertInitial (20) -- Certificate polling in manual enrollment + GetCert (21) -- Retrieve a certificate + + +Liu/Madson/McGrew/Nourse [Page 16] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + GetCRL (22) -- Retrieve a CRL + + All response message will include transaction status information which + is defined as pkiStatus attribute: + + SUCCESS (0) -- request granted + FAILURE (2) -- request rejected + PENDING (3) -- request pending for manual approval. + + If the status in the response is FAILURE, the failinfo attribute will + contain one of the following failure reasons: + + badAlg (0) -- Unrecognized or unsupported algorithm ident + badMessageCheck (1) -- integrity check failed + badRequest (2) -- transaction not permitted or supported + badTime (3) -- Message time field was not sufficiently close + to the system time + badCertId (4) -- No certificate could be identified matching + the provided criteria + + The attributes of senderNonce and recipientNonce are the 16 byte + random numbers generated for each transaction to prevent the replay + attack. + +When an end entity sends a PKI message to the server, a senderNonce is +included in the message. After the server processes the request, it will +send back the end entity senderNonce as the recipientNonce and generates +another nonce as the senderNonce in the response message. Because the +proposed pki protocol is a two-way communication protocol, it is clear +that the nonce can only be used by the end entity to prevent the +replay. The server has to employ extra state related information to +prevent a replay attack. + +Section 5. SCEP Transaction Specification + +In this section each SCEP transaction is specified in terms of the +complete messages exchanged during the transaction. + +5.1 Certificate Enrollment + +The certificate enrollment transaction consists of one PKCSReq message +send to the certificate authority from an end entity, and one CertRep +message send back from the server. The pkiStatus returned in the +response message is either SUCCESS, or FAILURE, or PENDING. The +information portion of a PKCSReq message is a PKCS#10 certificate +request, which contains the subject Distinguished Name, the subject +public key, and two attributes, a ChallangePassword attribute to be used +for revocation, and an optional ExtensionReq attribute which will be a +sequence of extensions the end entity expects to be included in its V3 +certificate extensions. One of the extension attribute specifies the key +usage. The pkiStatus is set to SUCCESS when the certificate is send +back in CertRep; the pkiStatus is set to FAILURE when the certificate + + +Liu/Madson/McGrew/Nourse [Page 17] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +request is rejected; the pkiStatus is set to PENDING when the server has +decided to manually authenticate the end entity. The messages exchanged +in the manual authentication mode is further specified in Section 5.2. + +Precondition: + Both the end entity and the certificate authority have completed their + initialization process. The end entity has already been configured + with the CA/RA certificate. + +Postcondition: + Either the certificate is received by the end entity, or the end + entity is notified to do the manual authentication, or the request + is rejected. + +5.1.1 PKCSReq Message Format + +A PKCSReq message is created by following the steps defined below: + +1. Create a PKCS#10 certificate request which is signed by the end + entity's private key, corresponding to the public key included in + the PKCS#10 certificate request. This constitutes the information + portion of PKCSReq. + +2. Encrypt the PKCS#10 certificate request using a randomly generated + content-encryption key. This content-encryption key is then + encrypted by the CA's* public key and included in the recipientInfo. + This step completes the "envelope" for the PKCS#10 certificate + request. + +3. Generate a unique string as the transaction id. + +4. Generate a 16 byte random number as senderNonce. + +5. Generate message digest on the enveloped PKCS#10 certificate request + using the selected digest algorithm. + +6. Create SignedData by adding the end entity's self-signed certificate + as the signer's public key certificate. Include the message type, + transaction id, the senderNonce and the message digest as the + authenticated attributes and sign the attributes using the end + entity's private key. This completes the SignedData. + +7. The SignedData is prepended with the ContenInfo blob which indicates + a SignedData object. This final step completes the create of a + complete PKCSReq PKI message. + +In the following, the PKCSReq message is defined following the ASN.1 +notation. + +For readability, the values of a field is either represented by a quoted +string which specifies the intended value, or a constant when the value +is known. + + +Liu/Madson/McGrew/Nourse [Page 18] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + -- PKCSReq information portion + pkcsCertReq CertificationRequest ::= { -- PKCS#10 + version 0 + subject "the end entity's subject name" + subjectPublicKeyInfo { + algorithm {pkcs-1 1} -- rsa encryption + subjectPublicKey "DER encoding of the end entity's public key" + } + attributes { + challengePassword {{pkcs-9 7} "password string" } + extensions + } + signatureAlgorithm {pkcs-1 4} -- MD5WithRSAEncryption + signature "bit string which is created by signing inner content + of the defined pkcsCertReq using end entity's private + key, corresponding to the public key included in + subjectPublicKeyInfo." + } + -- Enveloped information portion + pkcsCertReqEnvelope EnvelopeData ::= { -- PKCS#7 + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the CA issuer name" + serialNumber "the CA certificate serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} -- rsa encryption + encryptedKey "content-encryption key + encrypted by CA public key" + } + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "object identifier + for DES encryption" + encryptedContent "encrypted pkcsCertReq using the content- + encryption key" + } + } + -- Signed PKCSReq + pkcsCertReqSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} -- data content identifier + content pkcsCertReqEnvelope + } + certificate { -- the end entity's self-signed certificate + version 3 + serialNumber "the transaction id associated with enrollment" + signature {pkcs-1 4} -- md5WithRSAEncryption + + +Liu/Madson/McGrew/Nourse [Page 19] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + issuer " the end entity's subject name" + validity { + notBefore "a UTC time" + notAfter "a UTC time" + } + subject "the end entity's subject name" + subjectPublicKeyInfo { + algorithm {pkcs-1 1} + subjectPublicKey "DER encoding of end entity's public key" + } + signatureAlgorithm {pkcs-1 4} + signature "the signature generated by using the end entity's + private key corresponding to the public key in + this certificate." + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the end entity's subject name" + serialNumber "the transaction id associated + with the enrollment" + } + digestAlgorithm {iso(0) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "an octet string"} + transaction-id {{id-attributes transId(7)} "printable + string"} + -- this transaction id will be used + -- together with the subject name as + -- the identifier of the end entity's key + -- pair during enrollment + messageType {{id-attributes messageType(2)} "PKCSReq"} + senderNonce {{id-attributes senderNonce(5)} + "a random number encoded as a string"} + } + digestEncryptionAlgorithm {pkcs-1 1} -- rsa encryption + encryptedDigest "encrypted digest of the authenticated + attributes using end entity's private key" + } + } + pkcsReq PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsCertRepSigned + } + + + + + + + + +Liu/Madson/McGrew/Nourse [Page 20] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +5.1.2 CertRep Message Format + +The response to an SCEP enrollment request is a CertRep message. + +5.1.2.1 PENDING Response + +When the CA is configured to manually authenticate the end entity, +the CertRep is returned with the attribute pkiStatus set to PENDING. +The data portion for this message is null. Only the transaction +required attributes are sent back. + +CertRepSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo {contentType {pkcs-7 1} -- empty content + } + signerInfo { + version 1 + issuerAndSerialNumber { +| issuer "name of CA that issued the CA [RA] cert" +| serialNumber "the serial number of the CA [RA] cert" + } + digestAlgorithm (iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} NULL} + messageType {{id-attribute messageType(0)} "CertRep"} + transaction-id {{id-attributes transid(7)} "printablestring"} + --- same transaction id used in PKCSReq + pkiStatus {{id-attributes pkiStatus(3)} "PENDING"} + recipientNonce {{id-attributes recipientNonce(6)}<16 bytes>} + senderNonce {{id-attributes senderNonce(5)} <16 bytes>} + } + digestEncrytionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted message digest of the authenticated +| attributes using the CA's [RA's] private key" + } +} +CertRep PKIMessage ::= { + contentType {pkcs-7 2} + content CertRepSigned +} + +5.1.2.2 Failure Response + +In this case, the CertRep sent back to the end entity is same as in +the PENDING case, except that the pkiStatus attribute is set to FAILURE, +and the failInfo attribute should be included: + + pkistatus {{id-attributes pkiStatus(3)} "FAILURE"} + failInfo {{id-attributes failInfo(4)} "the reason to reject"} + +Liu/Madson/McGrew/Nourse [Page 21] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +5.1.2.3 SUCCESS response + +In this case, the information portion of CertRep will be a degenerated +PKCS#7 which contains the end entity's certificate. It is then enveloped +and signed as below: + +pkcsCertRep SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { -- empty content since this is degenerated PKCS#7 + contentType {pkcs-7 1} + } + certificates { + certificate { -- issued end entity's certificate + version 3 + serialNumber "issued end entity's certificate serial number" + signature {pkcs-1 4} -- md5WithRSAEncryption + issuer "the certificate authority issuer name" + validity { + notBefore "UTC time" + notAfter "UTC time" + } + subject "the end entity subject name as given in PKCS#10" + subjectPublicKeyInfo { + algorithm {pkcs-1 1} + subjectPublicKey "a DER encoding of end entity public + key as given in PKCS#10" + } + extensions " the extensions as given in PKCS#10" + signatureAlgorithm {pkcs-1 4} + signature " the certificate authority signature" + } + certificate "the certificate authority certificate" +| certificate "the registration authority certificate (if +applicable)" + } +} +pkcsCertRepEnvelope EnvelopedData ::= { -- PKCS#7 + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { -- use issuer name and serial number as + -- conveyed in end entity's self-signed + -- certificate, included in the PKCSReq + issuer "the end entity's subject name" + serialNumber "the serial number defined by the end entity in + its self-signed certificate" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted by the end entity's + public key which is same key as authenticated in + the end entity's certificate" + } + +Liu/Madson/McGrew/Nourse [Page 22] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + encryptedContentInfo { + contentType {pkcs-7 1} -- data content identifier + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted pkcsCertRep using content encryption + key" + } +} +pkcsCertRepSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + content pkcsCertRepEnvelope + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the certificate authority issuer name" + serialNumber "the CA certificate's serial number" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "a octet string"} + messageType {{id-attribute messageType(2)} "CertRep"} + transaction-id {{id-attributes transId(7)} "printable + string"} + -- same transaction id as given in PKCSReq + pkiStatus {{id-attributes pkiStatus(3) "SUCCESS"} + recipientNonce {{id-attribute recipientNonce(6)}<16 bytes>} + senderNonce {{ id-attributes senderNonce(5) <16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticate attributes + using CA's private key " + } +} +CertRep PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsCertRepSigned +} + +5.2 Poll for End Entity Initial Certificate + +Either triggered by the PENDING status received from the CertRep, or by +the non-response timeout for the previous PKCSReq, an end entity will +enter the polling state by periodically sending GetCertInitial to the +server, until either the request is granted and the certificate is sent +back, or the request is rejected, or the the configured time limit for +polling is exceeded. + + +Liu/Madson/McGrew/Nourse [Page 23] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + +Since GetCertInitial is part of the enrollment, the messages exchanged +during the polling period should carries the same transaction identifier +as the previous PKCSReq. + +PreCondition + Either the end entity has received a CertRep with pkiStatus set to be + PENDING, or the previous PKCSReq has timed out. + +PostContition + The end entity has either received the certificate, or be rejected of + its request, or the polling period ended as a failure. + +5.2.1 GetCertInitial Message Format + +|Since at this time the certificate has not been issued, the end entity +|can only use the end entity's subject name, combined with the +|transaction identifier, to identify the polled certificate request. + +|The certificate authority server must be able to uniquely identify the +|polled certificate request. A subject name can have more than one +|outstanding certificate request (with different key usage attributes). + +-- Information portion + +pkcsGetCertInitial issuerAndSubject ::= { + issuer "the certificate authority issuer name" + subject "the end entity subject name as given in PKCS#10" +} +pkcsGetCertInitialEnvelope EnvelopedData ::= { + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the CA issuer name" + serialNumber "the CA certificate serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted by CA's public key" + } + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted getCertInital" + } +} +pkcsGetCertInitialSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + + +Liu/Madson/McGrew/Nourse [Page 24] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + content pkcsGetCertIntialEnvelope + } + certificate { -- the end entity's self-signed certificate + version 3 + serialNumber "the transaction id associated with enrollment" + signature {pkcs-1 4} -- md5WithRSAEncryption + issuer " the end entity's subject name" + validity { + notBefore "a UTC time" + notAfter "a UTC time" + } + subject "the end entity's subject name" + subjectPublicKeyInfo { + algorithm {pkcs-1 1} + subjectPublicKey "DER encoding of end entity's public key" + } + signatureAlgorithm {pkcs-1 4} + signature "the signature generated by using the end entity's + private key corresponding to the public key in + this certificate." + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "end entity's subject name" + serialNumber "the transaction id used in previous PKCSReq" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "an octet string"} + -- digest of getCertInitial + messageType {{id-attribute messageType(2)} "GetCertInitial"} + transaction-id {{id-attributes transId(7)} "printable + string"} + -- same transaction idused in previous PKCSReq + senderNonce {{id-attribute senderNonce(3)} 0x<16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticateAttributes" + } +} +GetCertInitial PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsGetCertInitialSigned +} + + + +5.2.2 GetCertInitial Response Message Format + +The response messages for GetCertInitial are the same as for PKCSReq. + +Liu/Madson/McGrew/Nourse [Page 25] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +5.3 Certificate Access + +The certificate query message defined in this section is an option when +the LDAP server is not available to provide the certificate query. An +end entity should be able to query an issued certificate from the +certificate authority, as long as the issuer name and the issuer +assigned certificate serial number is known to the requesting end +entity. This transaction is not intended to provide the service as a +certificate directory service. A more complicated query mechanism would +have to be defined in order to allow an end entity to query a certificate +using various different fields. + +This transaction consists of one GetCert message send to the server by +an end entity, and one CertRep message send back from the server. + +PreCondition + The queried certificate have been issued by the certificate authority + and the issuer assigned serial number is known. + +PostContition + Either the certificate is send back or the request is rejected. + + +5.3.1 GetCert Message Format + +The queried certificate is identified by its issuer name and the issuer +assigned serial number. If this is a query for an arbitrary end entity's +certificate, the requesting end entity should includes its own CA issued +certificate in the signed envelope. If this is a query for its own +certificate (assume the end entity lost the issued certificate, or does +not have enough non-volatile memory to save the certificate), then the +self-signed certificate has to be included in the signed envelope. + + pkcsGetCert issuerAndSerialNumber ::= { + issuer "the certificate issuer name" + serialNumber "the certificate serial number" + } + pkcsGetCertEnvelope EnvelopedData ::= { + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the CA [RA] issuer name" + serialNumber "the CA [RA] certificate serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted + by CA [RA] public key" + } + + + + + +Liu/Madson/McGrew/Nourse [Page 26] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted pkcsGetCert using the content + encryption key" + } + } + pkcsGetCertSigned SignedData ::= { + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + content pkcsGetCertEnvelope + } + certificates { + certificate "CA issued certificate" + or "self-signed certificate" + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the end entity's subject name" + serialNumber "end entity's certificate serial number" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "an octet string"} + -- digest of pkcsGetCertEnvelope + messageType {{id-attribute messageType(2)} "GetCert"} + transaction-id {{id-attributes transId(7)} "printable + string"} + senderNonce {{id-attribute senderNonce(3)} <16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticateAttributes" + } + } + GetCert PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsGetCertSigned + } + + + + + + + + + +Liu/Madson/McGrew/Nourse [Page 27] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + +5.3.2 CertRep Message Format + +In this case, the CertRep from the server is same as the CertRep for the +PKCSReq, except that the server will only either grant the request or +reject the request. Also, the recipientInfo should use the CA issuer +name and CA assigned serial number to identify the end entity's key pair +since at this time, the end entity has received its own certificate. + +5.4 CRL Access + +The CRL query message defined in this section is an option when the LDAP +server is not available to provide the CRL query. In the PKI protocol +proposed here, only the end entity can initiate the transaction to +download CRL. An end entity send GetCRL request to the server and the +server send back CertRep whose information portion is a degenerated +PKCS#7 which contains only the most recent CRL. The size of CRL included +in the CertRep should be determined by the implementation. + +PreCondition + The certificate authority certificate has been downloaded to the end + entity. + +PostCondition + CRL send back to the end entity. + +5.4.1 GetCRL Message format + +The CRL is identified by using both CA's issuer name and the CA +certificate's serial number: + + pkcsGetCRL issuerAndSerialNumber { + issuer "the certificate authority issuer name" + serialNumber "certificate authority certificate's serial number" + } + +When the CRLDistributionPoint is supported, the pkcsGetCRL is defined as +the following: + + pkcsGetCRL SEQUENCE { + crlIssuer issuerAndSerialNumber + distributionPoint CE-CRLDistPoints + } + +where CE-CRLDisPoints is defined in X.509, but must contain only one +CRL distribution point. + + + + + + + + + + +Liu/Madson/McGrew/Nourse [Page 28] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + pkcsGetCRLEnvelope EnvelopedData ::= { + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the certificate authority (or RA) issuer name" + serialNumber "the CA (RA) certificate's serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted by CA (RA) public key" + } + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted pkcsGetCRL" + } + } + pkcsGetCRLSigned SignedData ::= { + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + content pkcsGetCRLEnvelope + } + certificates { + certificate "CA-issued or self-signed end entity's certificate" + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the end entity's issuer name" + serialNumber "the end entity's certificate serial number" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} 0x<16/20 bytes>} + -- digest of pkcsGetCRLEnvelope + messageType {{id-attribute messageType(2)} "CertCRL"} + transaction-id {{id-attributes transId(7)} "printable + string"} + senderNonce {{id-attribute senderNonce(3)} <16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticateAttributes" + } + } + GetCRL PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsGetCRLSigned + } + +Liu/Madson/McGrew/Nourse [Page 29] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + +5.4.2 CertRep Message Format + +The CRL is send back to the end entity through CertRep message. The +information portion of this message is a degenerated PKCS#7 SignedData +which contains only a CRL. + + pkcsCertRep SignedData ::= { + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + } + crl { + signature {pkcs-1 4} + issuer "the certificate authority issuer name" + lastUpdate "UTC time" + nextUpdate "UTC time" + revokedCertificate { + -- the first entry + userCertificate "certificate serial number" + revocationData "UTC time" + .... + -- last entry + userCertificate "certificate serial number" + revocationData "UTC time" + } + } + pkcsCertRepEnvelope EnvelopedData ::= { + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the end entity's issuer name" + serialNumber "the end entity certificate serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted by end entity's + public key " + } + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted pkcsCertRep using end entity's + public key" + } + } + + + + + + +Liu/Madson/McGrew/Nourse [Page 30] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + + pkcsCertRepSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + content pkcsCertRepEnvelope + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the certificate authority issuer name" + serialNumber "the CA certificate's serial number" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "an octet string"} + -- digest of pkcsCertRepEnvelope + messageType {{id-attribute messageType(2)} "CertRep"} + transaction-id {{id-attributes transId(7)} "printable + string"} + -- same transaction id as given in PKCSReq + pkiStatus {{id-attributes pkiStatus(3) "SUCCESS"} + recipientNonce{{id-attribute recipientNonce(6)}<16 bytes>} + senderNonce {{id-attribute senderNonce (5) 0x<16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticatedAttributes + using CA private key" + } + } + + +NOTE:The PKCS#7 EncryptedContent is specified as an octet string, but +SCEP entities must also accept a sequence of octet strings as a valid +alternate encoding. + +This alternate encoding must be accepted wherever PKCS #7 Enveloped +Data is specified in this document. + + + + + + + + + + + +Liu/Madson/McGrew/Nourse [Page 31] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +5.5 Get Certificate Authority Certificate + +Before any transaction begins, end entities have to get the CA (and +possibly RA) certificate(s) first. Since no public keys have been +exchanged, the message can not be encrypted and the response must be +authenticated by out-of-band means. These certs are obtained by means +of an HTTP GET message. To get the CA certificate, the end entity does a +"HTTP GET" and receives a plain X.509 certificate in response. In the +request, the URL identifies a CGI script on the server and passes the CA +issuer identifier as the parameter to the CGI script. Once the CA +certificate is received by the end entity, a fingerprint is generated +using MD5 hash algorithm on the whole CA certificate. This fingerprint +is verified by some positive out-of-band means, such as a phone call. + + +5.5.1 GetCACert HTTP Message Format + "GET" CGI-PATH CGI-PROG "?operation=GetCACert" "&message=" CA-IDENT + where: + CGI-PATH defines the actual CGI path to invoke the CGI program + which parses the request. + CGI-PROG is set to be the string "pkiclient.exe" and this is + expected to be the program that the CA will use to handle the + SCEP transactions. + CA-IDENT is any string which is understood by the CA. + For example, it could be a domain name like ietf.org. + If a certificate authority has multiple root certificates + this field can be used to distinguish which is required. + Otherwise it may be ignored. + +5.5.2 Response + +The response for GetCACert is different between the case where the CA +directly communicated with the end entity during the enrollment, and the +case where a RA exists and the end entity communicates with the RA +during the enrollment. + +5.5.2.1 CA Certificate Only Response + +A binary X.509 CA certificate is send back as a MIME object with a +Content-Type of application/x-x509-ca-cert. + +5.5.2.2 CA and RA Certificates Response + +When an RA exists, both CA and RA certificates must be sent back in +the response to the GetCACert request. The RA certificate(s) must be +signed by the CA. A certificates-only PKCS#7 SignedData is used to +carry the certificates to the end entity, with a Content-Type of +application/x-x509-ca-ra-cert. + + + + + + + + +Liu/Madson/McGrew/Nourse [Page 32] + +|5.6 Get Certificate Authority Certificate Chain +| +|In order to support Certificate Authority hierarchies, it is necessary +|to have a way to get the entire certificate chain. The following message +|has been added to SCEP for this purpose. +| +|5.6.1 GetCACertChain HTTP Message Format +| +| "GET" CGI-SCRIPT "?" "operation=GetCACertChain" "&" "message" CA-IDENT +| where CGI-SCRIPT and CA-IDENT are as described for GetCACert. +| +|5.6.2 Response +| +|The response for GetCACertChain is a certificates-only PKCS#7 SignedData +|to carry the certificates to the end entity, with a Content-Type of +|application/x-x509-ca-ra-cert-chain. +| +|5.6.3 Backwards Compatability +| +|Versions of SCEP prior to revision 3 do not support GetCACertChain. +|Certificate Authorities written to these prior versions will not be +|able to process the message and may return an HTML error. +| +|To avoid this, clients should send the GetCACert message first. If the +|returned certificate is self-signed or is signed by a Certificate +|Authority that is trusted by the client, then it is not necessary to +|send the GetCACertChain message and it should not be sent. +| +|If a Certificate Authority is configured with a certificate that is +|not either self-signed or has a self-signed issuer, then it should +|support this message. In other words, it should be supported if the +|CA hierarchy is more than two-deep. +| +|An old CA in a two-deep hierarchy might still get this message from +|a client if the client did not trust either that CA or its issuer. +|In that event, the certificate cannot be trusted anyway. In any case +|the CA must not crash or hang upon the receipt of the message and the +|client must be able to handle whatever error is returned by the CA, +|including an HTML error or an ungraceful disconnect. + + + + + + + + + + + + + + + + + +Liu/Madson/McGrew/Nourse [Page 33] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +The following is the ASN.1 definition of Cert-Only PKCS#7: + + certOnly SignedData ::= { + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + +contentInfo { + contentType {pkcs-7 1} -- data content identifier + content -- NULL + } + certificates -- the RA and CA certificates. + } + + CARACerts PKIMessage ::= { -- special pki message sent in the clear + contentType {pkcs-7 2} + content certOnly + } + + +6.0 Security Considerations + +This entire document is about security. Common security considerations +such as keeping private keys truly private and using adequate lengths +for symmetric and asymmetric keys must be followed in order to maintain +the security of this protocol. + + +7.0 Intellectual Property + +This protcol includes the optional use of Certificate Revocation List +Distribution Point (CRLDP) technology, which is a patented technology +of Entrust Technologies, Inc. (Method for Efficient Management of +Certificate Revocation Lists and Update Information (U.S. Patent +5,699,431)). Please contact Entrust Technologies, Inc. +(www.entrust.com) for more information on licensing CRLDP technology. + + +8.0 References + +[PKCS7] Kaliski, B., "PKCS #7: Cryptographic Message Syntax Version +1.5", RFC 2315, March 1998. + +[PKCS10] Kaliski, B., "PKCS #10: Certification Request Syntax Version +1.5", RFC 2314, March 1998. + +[RFC2459] Housley, R., ec. al., "Internet X.509 Public Key +Infrastructure Certificate and CRL Profile", RFC 2459, January 1999. + + + + + + +Liu/Madson/McGrew/Nourse [Page 34] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +Appendix A: Cisco End Entity Subject Name Definition + +The ip address and the FQDN of a SCEP client should be included in the +V3 extension subjectAltName. When the subjectAltName extension attribute +is present, both the subjectAltName fields and the subjectName field could +have the IP address and the FQDN information. + +When the X.500 directory is used by the CA to define the name space, the +subject name defined above become a RDN which is part of DN binded to +the end entity's public key in the certificate. + + +A sample of DN assigned by Entrust CA is given below (assume the same +ciscoRouterAlice is used as the end entity defined subject name): + + OU = InteropTesting, O = Entrust Technologies, C = CA + RDN = {"alice.cisco.com", "172.21.114.67", "22334455"} + + +Liu/Madson/McGrew/Nourse [Page 35] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +Appendix B: IPSEC Client Enrollment Certificate Request + +The following is the certificate enrollment request (PKCS#10) as created +by Cisco VPN Client: + +-----END NEW CERTIFICATE REQUEST----- + 0 30 439: SEQUENCE { + 4 30 288: SEQUENCE { + 8 02 1: INTEGER 0 + 11 30 57: SEQUENCE { + 13 31 55: SET { + 15 30 53: SEQUENCE { + 17 06 3: OBJECT IDENTIFIER commonName (2 5 4 3) + 22 13 46: PrintableString + : 'For Xiaoyi, IPSEC attrs in alternate name + extn' + : } + : } + : } + 70 30 158: SEQUENCE { + 73 30 13: SEQUENCE { + 75 06 9: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 + 1 1) + 86 05 0: NULL + : } + 88 03 140: BIT STRING 0 unused bits + : 30 81 88 02 81 80 73 DB 1D D5 65 AA EF C7 D4 8E + : AA 6E EB 46 AC 91 2A 0F 50 51 17 AD 50 A2 2A F2 + : CE BE F1 E4 22 8C D7 61 A1 6C 87 61 62 92 CB A6 + : 80 EA B4 0F 09 9D 18 5F 39 A3 02 0E DB 38 4C E4 + : 8A 63 2E 72 8B DC BE 9E ED 6C 1A 47 DE 13 1B 0F + : 83 29 4D 3E 08 86 FF 08 2B 43 09 EF 67 A7 6B EA + : 77 62 30 35 4D A9 0F 0F DF CC 44 F5 4D 2C 2E 19 + : E8 63 94 AC 84 A4 D0 01 E1 E3 97 16 CD 86 64 18 + : [ Another 11 bytes skipped ] + : } + 231 A0 63: [0] { + 233 30 61: SEQUENCE { + 235 06 9: OBJECT IDENTIFIER extensionReq (1 2 840 113549 1 9 + 14) + 246 31 48: SET { + 248 30 46: SEQUENCE { + 250 30 44: SEQUENCE { + 252 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17) + 257 04 37: OCTET STRING + 30 23 87 04 01 02 03 04 81 0D 65 6D 61 69 + + +Liu/Madson/McGrew/Nourse [Page 36] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + 6C 40 69 72 65 2E 63 6F 6D 82 0C 66 71 64 + 6E 2E 69 72 65 2E 63 6F 6D + : } + : } + : } + : } + : } + : } + + 296 30 13: SEQUENCE { + 298 06 9: OBJECT IDENTIFIER md5withRSAEncryption (1 2 840 113549 + 1 1 4) + 309 05 0: NULL + : } + 311 03 129: BIT STRING 0 unused bits + : 19 60 55 45 7F 72 FD 4E E5 3F D2 66 B0 77 13 9A + : 87 86 75 6A E1 36 C6 B6 21 71 68 BD 96 F0 B4 60 + : 95 8F 12 F1 65 33 16 FD 46 8A 63 19 90 40 B4 B7 + : 2C B5 AC 63 17 50 28 F0 CD A4 F0 00 4E D2 DE 6D + : C3 4F F5 CB 03 4D C8 D8 31 5A 7C 01 47 D2 2B 91 + : B5 48 55 C8 A7 0B DD 45 D3 4A 8D 94 04 3A 6C B0 + : A7 1D 64 74 AB 8A F7 FF 82 C7 22 0A 2A 95 FB 24 + : 88 AA B6 27 83 C1 EC 5E A0 BA 0C BA 2E 6D 50 C7 + : } + + +Appendix C: Private OID Definitions + +The OIDs used in defining pkiStatus are VeriSign self-maintained +OIDs. Please note, work is in progress to replace the VeriSign owned +object identifiers with the standard object identifiers. Once the +standarlization is completed, this documentation will be updated. + +id-VeriSign OBJECT_IDENTIFIER ::= {2 16 US(840) 1 VeriSign(113733)} +id-pki OBJECT_IDENTIFIER ::= {id-VeriSign pki(1)} +id-attributes OBJECT_IDENTIFIER ::= {id-pki attributes(9)} +id-messageType OBJECT_IDENTIFIER ::= {id-attributes messageType(2)} +id-pkiStatus OBJECT_IDENTIFIER ::= {id-attributes pkiStatus(3)} +id-failInfo OBJECT_IDENTIFIER ::= {id-attributes failInfo(4)} +id-senderNonce OBJECT_IDENTIFIER ::= {id-attributes senderNonce(5)} +id-recipientNonce OBJECT_IDENTIFIER ::= {id-attributes recipientNonce(6)} +id-transId OBJECT_IDENTIFIER ::= {id-attributes transId(7)} +id-extensionReq OBJECT_IDENTIFIER ::= {id-attributes extensionReq(8)} + + +Liu/Madson/McGrew/Nourse [Page 37] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + Appendix D: CRL Query by means of LDAP + + In order to retrieve the CRL by means of LDAP, the client needs to know + where in the directory it is stored. The certificate must contain a + CRL Distribution Point extension encoded as a DN or as an LDAP URI. + +For example, the certificate issued by Entrust VPN contains +the following DN as the CRL distribution point: + + + +CN = CRL1, O = cisco, C = US. + + The asn.1 encoding of this distribution point is: + + 30 2C 31 0B 30 09 06 03 55 04 06 13 02 55 53 31 0E 30 0C 06 + 03 55 04 0A 13 05 63 69 73 63 6F 31 0D 30 0B 06 03 55 04 03 + 13 04 43 52 4C 31 + + +The ldap form would be: + +ldap://servername/CN=CRL1,O=cisco,C=US + + + +Appendix E: SCEP State Transitions + +SCEP state transitions are based on transaction identifier. The design +goal is to ensure the synchronization between the CA and the end entity +under various error situations. + + +An identity is defined by the combination of FQDN, the IP address and +the client serial number. FQDN is the required name attribute. It is +important to notice that, a client named as Alice.cisco.com is different +from the client named as Alice.cisco.com plus IPAddress 171.69.1.129. + +Each enrollment transaction is uniquely associated with a transaction +identifier. Because the enrollment transaction could be interrupted by +various errors, including network connection errors or client reboot, +the SCEP client generates a transaction identifier by calculating MD5 +hash on the public key value for which the enrollment is requested. This +retains the same transaction identifier throughout the enrollment +transaction, even if the client has rebooted or timed out, and issues a +new enrollment request for the same key pair. It also provides the way +for the CA to uniquely identify a transaction in its database. At the +end entity side, it generates a transaction identifier which is included +in PKCSReq. If the CA returns a response of PENDING, the end entity +will poll by periodically sending out GetCertInitial with the same +transaction identifier until either a response other than PENDING is +obtained, or the configured maximum time has elapsed. + +If the client times out or the client reboots, the client administrator +will start another enrollment transaction with the same key pair. The +second enrollment will have the transaction idenifier. At the server +side, instead of accepting the PKCSReq as a new enrollment request, it +should respond as if another GetCertInitial message had been sent with +that transaction ID. In another word, the second PKCSReq should be +taken as a resynchronization message to allow the enrollment resume as +the same transaction. + +It is important to keep the transaction id unique since CEP requires the +same policy and same identity be applied to the same subject name and + + +Liu/Madson/McGrew/Nourse [Page 38] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +key pair binding. In the current implementation, an SCEP client can +only assume one identity. At any time, only one key pair, with a given +key usage, can be associated with the same identity. + +The following gives several example of client to CA transactions. + +Client actions are indicated in the left column, CA actions are +indicated in the right column. A blank action signifies that no message +was received. Note that these examples assume that the CA enforces the +certificate-name uniqueness property defined in Section 2.1.1.1. + +The first transaction, for example, would read like this: + "Client Sends PKCSReq message with transaction ID 1 to the + CA. The CA signs the certificate and constructs a CertRep Message + containing the signed certificate with a transaction ID 1. The client + receives the message and installs the cert locally." + +Successful Enrollment Case: no manual authentication +PKCSReq (1) ----------> CA Signs Cert +Client Installs Cert <---------- CertRep (1) SIGNED CERT + + + +Successful Enrollment Case: manual authentication required +PKCSReq (10) ----------> Cert Request goes into Queue +Client Polls <---------- CertRep (10) PENDING +GetCertInitial (10) ----------> Still pending +Client Polls <---------- CertRep (10) PENDING +GetCertInitial (10) ----------> Still pending +Client Polls <---------- CertRep (10) PENDING +GetCertInitial (10) ----------> Still pending +Client Polls <---------- CertRep (10) PENDING +GetCertInitial (10) ----------> Cert has been signed +Client Installs Cert <---------- CertRep (10) SIGNED CERT + + + +Resync Case - CA Receive and Signs PKCSReq, Client Did not receive +CertRep: + +PKCSReq (3) ----------> Cert Request goes into queue + <---------- CertRep (3) PENDING +GetCertInitial (3) ----------> + <---------- CertRep (3) PENDING +GetCertInitial (3) -----------> + <----------- CA signed Cert and send back + CertRep(3) +(Time Out) +PKCSReq (3) ----------> Cert already signed, send back to + client +Client Installs Cert <---------- CertRep (3) SIGNED CERT + + + +Liu/Madson/McGrew/Nourse [Page 39] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + + +Case when NVRAM is lost and client has to generate a new key pair, there +is no change of name information: + +PKCSReq (4) ----------> CA Signs Cert +Client Installs Cert <---------- CertRep (4) SIGNED CERT +(Client looses Cert) +PKCSReq (5) ----------> There is already a valid cert with + this DN. +Client Admin Revokes <---------- CertRep (5) OVERLAPPING CERT ERROR +PKCSReq (5) ----------> CA Signs Cert +Client Installs Cert <---------- CertRep (5) SIGNED CERT + + +Case when client admin resync the enrollment using a different PKCS#10: +PKCSReq (6) ----------> CA Signs Cert + <---------- CertRep (6) SIGNED CERT +(Client timeout and admin starts another enrollment with a different + PKCS#10, but the same transaction id) +PKCSReq (6) with different PKCS#10 + ----------> There is already a valid cert with + this entity (by checking FQDN). + <---------- CertRep (6) INVALID PKCS#10 CERT + ERROR +Client admin either revokes the existing cert +or corrects the error by enrolling with +the same PKCS#10 as the first PKCSReq(6) +PKCSReq (6) ----------> CA find the existing Cert +Client Installs Cert <---------- CertRep (6) SIGNED CERT + + +Resync case when server is slow in response: +PKCSReq (13) ----------> Cert Request goes into Queue + <---------- CertRep (13) PENDING +GetCertInitial ----------> Still pending + <---------- CertRep (13) PENDING +GetCertInitial ----------> Still pending + <---------- CertRep (13) PENDING +GetCertInitial ----------> Still pending + <---------- CertRep (13) PENDING +GetCertInitial ----------> Still pending +(TimeOut) <---------- CertRep (13) PENDING +* Case 1 +PKCSReq (13) ----------> Still pending +Client polls <---------- CertRep (13) PENDING +CertCertInitial ----------> Cert has been signed +Client Installs Cert <---------- CertRep (13) SIGNED CERT +* Case 2 +PKCSReq (13) ----------> Cert has been signed +Client Installs Cert <---------- CertRep (13) SIGNED CERT + + + + +Liu/Madson/McGrew/Nourse [Page 40] + +Cisco Systems' Simple Certificate Enrollment Protocol May 2002 + +Appendix F. Author Contact Information + +Xiaoyi Liu Cheryl Madson +Cisco Cisco +170 West Tasman Drive 170 West Tasman Drive +San Jose, CA 94134 San Jose, CA 94134 +xliu@cisco.com cmadson@cisco.com + + +David McGrew Andrew Nourse +Cisco Cisco +170 West Tasman Drive 101 Cooper Street +San Jose, CA 94134 Santa Cruz, CA 95060 +mcgrew@cisco.com nourse@cisco.com + + + + +Appendix G. Copyright Section + +Copyright (C) The Internet Society (2000). All Rights Reserved. + +This document and translations of it may be copied and furnished +to others, and derivative works that comment on or otherwise +explain it or assist in its implmentation may be prepared, copied, +published and distributed, in whole or in part, without +restriction of any kind, provided that the above copyright notice +and this paragraph are included on all such copies and derivative +works. However, this document itself may not be modified in any +way, such as by removing the copyright notice or references to the +Internet Society or other Internet organizations, except as needed +for the purpose of developing Internet standards in which case the +procedures for copyrights defined in the Internet Standards +process must be followed, or as required to translate it into +languages other than English. + +The limited permissions granted above are perpetual and will not +be revoked by the Internet Society or its successors or assigns. + +This document and the information contained herein is provided on +an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET +ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF +THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + + + + +This draft expires 15-November 2002 + +[End of draft-nourse-scep-07.txt] + + diff --git a/draft-nourse-scep-11.txt b/draft-nourse-scep-11.txt index 48a5cbb..70e0f8f 100644 --- a/draft-nourse-scep-11.txt +++ b/draft-nourse-scep-11.txt @@ -1,4734 +1,4734 @@ - -INTERNET DRAFT Xiaoyi Liu -draft-nourse-scep-11.txt Cheryl Madson -expires 11 Aug 2005 David McGrew -(revised 11 Feb 2005) Andrew Nourse - Cisco Systems - -Category: Informational 11 Feb 2005 - - -Cisco Systems' Simple Certificate Enrollment Protocol(SCEP): - -Status of this Memo - -This document is an Internet-Draft and is NOT offered in accordance -with Section 10 of RFC2026, and the author does not provide the IETF -with any rights other than to publish as an Internet-Draft - -Internet-Drafts are working documents of the Internet Engineering Task -Force (IETF), its areas, and its working groups. Note that other -groups may also distribute working documents as Internet-Drafts. - -Internet-Drafts are draft documents valid for a maximum of six months -and may be updated, replaced, or obsoleted by other documents at any -time. It is inappropriate to use Internet- Drafts as reference -material or to cite them other than as "work in progress." - -The list of current Internet-Drafts can be accessed at -http://www.ietf.org/ietf/1id-abstracts.txt - -The list of Internet-Draft Shadow Directories can be accessed at -http://www.ietf.org/shadow.html. - -This memo provides information for the Internet community. This memo -does not specify an Internet standard of any kind. Distribution of -this memo is unlimited. - -By submitting this Internet-Draft, I certify that any applicable patent -or other IPR claims of which I am aware have been disclosed, or will be -disclosed, and any of which I become aware will be disclosed, in accordance -with RFC 3668. - -Abstract - -This document specifies the Simple Certificate Enrollment Protocol, -a PKI communication protocol which leverages existing technology by -using PKCS#7 and PKCS#10. SCEP is the evolution of the enrollment -protocol developed by Verisign, Inc. for Cisco Systems, Inc. -It now enjoys wide support in both client and CA implementations. - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 2 - 2. The Goal of SCEP . . . . . . . . . . . . . . . . . . . . . 3 - 2.1 SCEP Entity types . . . . . . . . . . . . . . . . . . . . 3 - 2.2 SCEP Operations Overview . . . . . . . . . . . . . . . . . 7 - 2.3 PKI Operation Transactional Behavior . . . . . . . . . . . 10 - 2.4 Security . . . . . . . . . . . . . . . . . . . . . . . . . 12 - 3. Transport Protocol . . . . . . . . . . . . . . . . . . . . 13 - 4. Secure Transportation: PKCS #7 . . . . . . . . . . . . . . 14 - 4.1 SCEP Message Format . . . . . . . . . . . . . . . . . . . 14 - - Liu/Madson/McGrew/Nourse [Page 2] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - 4.2 Signed Transaction Attributes . . . . . . . . . . . . . . 15 - 5. SCEP Transaction Specification . . . . . . . . . . . . . . 16 - 5.1 Certificate Enrollment . . . . . . . . . . . . . . . . . . 16 - 5.2 Poll for Requester Initial Certificate . . . . . . . . . . 22 - 5.3 Certificate Access . . . . . . . . . . . . . . . . . . . . 26 - 5.4 CRL Access . . . . . . . . . . . . . . . . . . . . . . . 27 - 5.5 Get Certificate Authority Certificate . . . . . . . . . . 31 - 5.6 Get Certificate Authority Certificate Chain . . . . . . . 33 - 6. Security Considerations . . . . . . . . . . . . . . . . . 33 - 7. Intellectual Propoerty . . . . . . . . . . . . . . . . . . 33 - 8. References . . . . . . . . . . . . . . . . . . . . . . . . 33 - Appendix A. Cisco Requester Subject Name Definition . . . . . . 34 - Appendix B. IPSEC Client Enrollment Certificate Request . . . . 35 - Appendix C. Private OID Definitions . . . . . . . . . . . . . 36 - Appendix D. Obtaining CRL by LDAP Query . . . . . . . . . . . . 36 - Appendix E. SCEP State Transitions . . . . . . . . . . . . . . 37 - Appendix F. CA Capabilities . . . . . . . . . . . . . . . . . . 40 - Appendix G. Certificate Renewal and CA Key Rollover . . . . . . 41 - Appendix H. PKIOperation via HTTP POST Message. . . . . . . . . 42 - Appendix Y. Author Contact Information. . . . . . . . . . . . . 43 - Appendix Z. Copyright Section . . . . . . . . . . . . . . . . . 43 - -Section 1. Introduction - -Public key technology is becoming more widely deployed and is becoming -the basis for standards based security, such as the Internet Engineering -Task Force's IPSEC and IKE protocols. With the use of public key -certificates in network security protocols comes the need for a -certificate management protocol that Public Key Infrastructure (PKI) -clients and Certificate Authority servers can use to support certificate -life cycle operations such as certificate enrollment and revocation, and -certificate and CRL access. - -In the following, Section 2 gives an overview of the PKI operations, -and Section 2.4 describes the security goals of the protocol and the -mechanisms used to achieve them. The transport protocol and the -security protocol PKCS#7 are described at Section 3 and Section 4, -respectively. The last section, Section 5, specifies each PKI -operation in terms of the message formats and the data structures of -each operation. - -The appendices provide detailed specifications and examples. Requester -subject names are specified in Appendix A, attribute OIDs are -specified in Appendix C , and the SCEP state transitions are described -in Appendix E. An example of a certificate enrollment request is -provided in Appendix B, and an example LDAP query URL encoding is -provided in Appendix D. - -The authors would like to thank Peter William of ValiCert, Inc. -(formerly of Verisign, Inc) and Alex Deacon of Verisign, Inc. and -Christopher Welles of IRE, Inc. for their contributions to this protocol -and to this document. - - Liu/Madson/McGrew/Nourse [Page 3] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -2.0 The Goal of SCEP -The goal of SCEP is to support the secure issuance of certificates to -network devices in a scalable manner, using existing technology whenever -possible. The protocol supports the following operations: - - CA and RA public key distribution - Certificate enrollment - Certificate revocation - Certificate query - CRL query - -Certificate and CRL access can be achieved by using the LDAP protocol -(as specified in Appendix D), or by using the query messages defined in -SCEP. The use of HTTP certificate and CRL access, and the support of -CDP as specified in RFC2459, will be specified in a future version of -this document. In Section 2.1, we first define PKI entity types as well -as the properties of each entity type. In Section 2.2, the PKI -operations are described at functional level. Section 2.3 describes the -transaction behavior of each PKI operations. The complete PKI messages -are covered in Section 5. - -2.1 SCEP Entity types - -The entity types defined in SCEP are the "requester" type (i.e., IPSEC -clients), the Certificate Authority (CA) entity type, and the -Registration Authority entity type (RA). A requester is sometimes -called a "SCEP client" in the following. - -2.1.1 Requesters - -A requester is an entity whose name is defined in a certificate -subject name field and optionally, in SubjectAltName, a X.509 -certificate V3 extension. As a requester, a SCEP client is identified -by a subject name consisting of the following naming attributes: - - Fully qualified domain name, for example, router.cisco.com - IP address, Serial number, and/or x.500 distinguished name - -The fully qualified domain name is required for a requester that intends -to use the certificate for ISAKMP. The IP address, serial number, and -x.500 distinguished name are optional name attributes. In the -certificate enrollment request, the PKCS#10 subject field contains the -required and optional name attributes. The distinguished name, if any, -should be the subject name field, while any domain name, serial number, -or IP address supplied should be in the subjectAltName field. The -subject name field may be empty (if there is no distinguished name) -or the subjectAltName may be omitted, but not both. - -It is important to note that a client named as Alice.cisco.com is -different than a client named as Alice.cisco.com plus the IP address -name attribute 117.96.1.219. From CA point of view, the Distinguished -names assigned in these two cases are distinct names. - - - Liu/Madson/McGrew/Nourse [Page 4] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Entity names which are specified as in the IPSEC profile (i.e., FQDN, IP -address and User FQDN) must be presented in certificate's SubjectAltName -extension. Multiple IPSEC entity names, (if any) are encoded as multiple -values of a single SubjectAltName extension. The CA has the authority -to assign a distinguished name to a requester, whether or not one was -included in the request. The assigned DN should contain the SCEP client -names as the relative DN. - -The attribute identifiers and an example of SCEP client subject name are -specified in Appendix A. Appendix B has an example from Cisco VPN Client -enrollment request. - -2.1.1.1 Local Key/Certificate/CRL Storage and Certificate-name uniqueness - -A requester is required to generate asymmetric key pairs and to provide -storage to store its private keys. If the requester does not have enough -permanent memory to save its certificate, then it should be able to query -its own certificate from the CA or an LDAP server, once the certificate -has been issued. The public key pairs can be generated with a specific -key usage. The key usage is conveyed to the CA through the certificate -enrollment request. All current SCEP client implementations expect that -there will be only one pair of keys for a given subject name -and key usage combination and CA, at any time. This property is called -the certificate-name uniqueness property, and it implies that a CA that -implements SCEP will enforce the unique mapping between a SCEP client -subject name and its key pairs with a given key usage. At any time, if -the subject name is changed, or if the key is updated, the existing -certificate would have to be revoked before a new one could be issued. - -It is desirable that the CA enforce certificate-name uniqueness, but -it is not mandatory. However a CA that does not enforce uniqueness -must provide some other mechanism to prevent the re-transmission of an -enrollment request by a SCEP client from creating a second certificate -or certificate request, nor can the second request merely be rejected. -If a client times out from polling for a pending request it can -resynchronize by reissuing the original request with the original -subject name, key, and transaction ID. This should return the status of -the original transaction, including the certificate if it was granted. -It should not create a new transaction unless the original cert has been -revoked, or the transaction arrives more than halfway through the -validity time of the original certificate. - -An enrollment request that occurs more than halfway through the validity -time of an existing certificate for the same subject name and key usage -MAY be interpreted as a re-enrollment or renewal request and accepted. -A new certificate with new validity dates may be issued, even though -the old one is still valid, if the CA policy permits, as described in -2.1.1.3. See also appendix G. - -2.1.1.2 Requester authentication - -As with every protocol that uses public-key cryptography, the -association between the public keys used in the protocol and the -identities with which they are associated must be authenticated in a - Liu/Madson/McGrew/Nourse [Page 5] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -cryptographically secure manner. This requirement is needed to -prevent a "man in the middle" attack, in which an adversary that can -manipulate the data as it travels between the protocol participants -can subvert the security of the protocol. To satisfy this -requirement, SCEP provides two authentication methods: manual -authentication, and authentication based on pre-shared secret. In the -manual mode, the requester is required to wait until its identity can -be verified by the CA operator using any reliable out-of-band -method. To prevent a "man-in-the-middle" attack, a SHA-1 or MD5 -`fingerprint' generated on the PKCS#10 (before PKCS #7 enveloping and -signing) must be compared out-of-band between the server and the -requester. SCEP clients and CAs (or RAs, if appropriate) must display -this fingerprint to the operator to enable this verification if manual -mode is used. Failing to provide this information leaves the protocol -vulnerable to attack by sophisticated adversaries. When utilizing a -pre-shared secret scheme, the server should distribute a shared secret -to the requester which can uniquely associate the enrollment request -with the given end entity. The distribution of the secret must be -private: only the end entity should know this secret. The actual -binding mechanism between the requester and the secret is subject to -the server policy and implementation. When creating the enrollment -request, the requester is asked to provide a challenge password. When -using the pre-shared secret scheme, the requester must enter the -re-distributed secret as the password. In the manual authentication -case, the challenge password only used to authenticate a request for -the certificate's revokation. This challenge password is included as -a PKCS#10 attribute, and is sent to the server as encrypted data. The -PKCS#7 envelope protects the privacy of the challenge password with -DES encryption. - -2.1.1.3 Requester Uses Existing CA-Issued or Self-Signed Certificates - -In this protocol, the communication between the requester and the -certificate authority is secured by using PKCS#7 as the messaging -protocol. PKCS#7, however, is a protocol which assumes the -communicating entities already possess the peer's certificates and -requires both parties use the issuer names and issuer assigned -certificate serial numbers to identify the certificate in order to -verify the signature and decrypt the message. If the requesting -system already has a certificate issued by the CA, that certificate -may be presented as credentials for the renewal of that certificate if -the CA supports the "Renewal" capability and the CA policy permits the -certificate to be renewed. If the requester has no certificate issued -by the CA, or if the CA does not support and permit renewal, the -requestor must generate a self-signed certificate with the requester -subject name (the same name later used in the PKCS#10) as both issuer -and subject name. During the certificate enrollment, the requester -will first post itself as the signing authority by attaching the -self-signed certificate to the signed certificate request. When the -Certificate Authority makes the envelope on the issued certificate -using the public key included in the self-signed certificate, it -should use the same issuer name and serial number as conveyed in the -self-signed certificate to inform the end entity on which private key -should be used to open the envelope. - Liu/Madson/McGrew/Nourse [Page 6] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Note that when a client enrolls for separate encryption and signature -certificates, it may use the signature certificate to sign both -requests, and then expect its signature key to be used to encrypt -both responses. In any case, the recipientinfo on the envelope should -reflect the key used to encrypt the request. - -2.1.1.4 Trusted CA Store - -To support interoperability between IPSEC peers whose certificates are -issued by different CA, SCEP allows the users to configure multiple -trusted certificates. Trusted certificates are have been configured as -such in the client, based on some out-of-band means such as a "fingerprint". -These trusted certificates are used to verify certificate chains that end -in those certificates. - -2.1.2 Certificate Authority - -A Certificate Authority(CA) is an entity whose name is defined in the -certificate issuer name field. Before any PKI operations can begin, -the CA generates its own public key pair and creates a self-signed CA -certificate, or causes another CA to issue a certificate to it. -Associated with the CA certificate is a fingerprint which will be used -by the requester to authenticate the received CA certificate if it is -self-signed. The fingerprint is created by calculating a SHA-1 or MD5 -hash on the whole CA certificate. Before any requester can start its -enrollment, this CA certificate has to be configured at the entity -side securely. For IPSEC clients, the client certificates must have -SubjectAltName extension. To utilize LDAP as a CRL query protocol, -the certificates must have a CRL Distribution Point. Key usage is -optional. Without key usage, the public key is assumed as a general -purpose public key and it can be used for all the purposes. - -A Certificate Authority may enforce certain name policy. When using -X.500 directory name as the subject name, all the name attributes -specified in the PKCS#10 request should be included as Relative DN. All -the name attributes as defined in RFC2459 should be specified in the -SubjectAltName. An example is provided in Appendix A. - - If there is no LDAP query protocol support, the Certificate Authority -should answer certificate and CRL queries, and to this end it should be -online all the time. - -The updating of the CA's public key is addressed in Appendix G. - -2.1.3 Registration Authorities - -In an environment where an RA is present, a requester performs -enrollment through the RA. In order to setup a secure channel with an RA -using PKCS#7, the RA certificate(s) have to be obtained by the client -in addition to the CA certificate(s). - -In the following, the CA and RA are specified as one entity in the -context of PKI operation definitions. - Liu/Madson/McGrew/Nourse [Page 7] -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 -2.2 SCEP Operations Overview - -In this section, we give a high level overview of the PKI operations as -defined in SCEP. - -2.2.1 Requester Initialization - -The requester initialization includes the key pair generation and the -configuring of the required information to communicate with the -certificate authority. - -2.2.1.1 Key Pairs - -Before a requester can start PKI transaction, it must have at least one -asymmetric key pair, using the selected algorithm (the RSA algorithm is -required in SCEP, and is the only algorithm in current implementations). - -Key pairs may be intended for particular purposes, such as encryption only, -or signing only. The usage of any associated certificate can be restricted -by adding key usage and extended key usage attributes to the PKCS#10. - -2.2.1.2 Required Information - -A requester is required to have the following information configured -before starting any PKI operations: - -1. the certificate authority IP address or fully-qualified domain name, -2. the certificate authority HTTP CGI script path, and - the HTTP proxy information in case there is no direct Internet - connection to the server, -3. If CRLs are being published by the CA to an LDAP directory server, - and there is a CRL Distribution Point containing only an X.500 directory - name, then the client will need to know the LDAP server fully-qualified - domain name or IP address. CRL Distribution Points are discussed in - more detail in RFC 2459. - - -2.2.2 CA/RA Certificate Distribution - -Before any PKI operation can be started, the requester needs to get -the CA/RA certificates. At this time, since no public key has been - - Liu/Madson/McGrew/Nourse [Page 8] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -exchanged between the requester and the CA/RA, the message to get the -CA/RA certificate can not be secured using PKCS#7 protocol. Instead, the -CA/RA certificate distribution is implemented as a clear HTTP Get -operation. After the requester gets the CA certificate, it has to -authenticate the CA certificate by comparing the finger print with the -CA/RA operator. Since the RA certificates are signed by the CA, there is -no need to authenticate the RA certificates. - -This operation is defined as a transaction consisting of one HTTP Get -message and one HTTP Response message: - - REQUESTER CA SERVER - Get CA/RA Cert: HTTP Get message - -----------------------------> - CA/RA Cert download: HTTP Response message - <--------------------------------------- - Compute finger print and - call CA operator. - Receive call and check finger print - -If an RA is in use, a degenerated PKCS#7 with a certificate chain -consisting of both RA and CA certificates is sent back to the end -entity. Otherwise the CA certificate is directly sent back as the -HTTP response payload. - - -2.2.3 Certificate Enrollment - -A requester starts an enrollment transaction by creating a certificate -request using PKCS#10 and sends it to the CA/RA enveloped using the -PKCS#7. After the CA/RA receives the request, it will either -automatically approve the request and send the certificate back, or it -will require the requester to wait until the operator can manually -authenticate the identity of the requester. Two attributes are -included in the PKCS#10 certificate request - a Challenge Password -attribute and an optional ExtensionReq attribute which will be a -sequence of extensions the requester would like to be included in its -V3 certificate extensions. The Challenge Password may be used to -authenticate either the enrollment request itself, or a verbal -revocation request for the issued certificate in the event of key -compromise or other reason. - -In the automatic mode, the transaction consists of one PKCSReq PKI -Message, and one CertRep PKI message. In the manual mode, the requester -enters into polling mode by periodically sending a GetCertInitial PKI -message to the server, until the server operator completes the manual -authentication, after which the CA will respond to GetCertInitial by -returning the issued certificate. A CA MAY run in automatic mode for -preapproved requests, and manual mode for the rest. A request with a -non-null password is not necessarily a pre-approved request. It is up -to the CA server to decide. Polling mode is entered whenever the -server returns a PENDING response. - - Liu/Madson/McGrew/Nourse [Page 9] -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -The transaction in automatic mode: - - REQUESTER CA SERVER - -PKCSReq: PKI cert. enrollment msg - --------------------------------> CertRep: pkiStatus = SUCCESS - certificate attached - <------------------------------ - Receive issued certificate. - -The transaction in manual mode: - - REQUESTER CA SERVER - PKCSReq: PKI cert. enrollment msg - --------------------------------> CertRep: pkiStatus = PENDING - <------------------------------ - GetCertInitial: polling msg - --------------------------------> CertRep: pkiStatus = PENDING - <------------------------------ - ................. CertRep: pkiStatus = SUCCESS - certificate attached - <------------------------------ - Receive issued certificate. - -2.2.4 Requester Certificate Revocation - -A requester should be able to revoke its own certificate. Currently -the revocation is implemented as a manual process. In order to revoke a -certificate, the requester makes a phone call to the CA server -operator. The operator will come back asking the ChallengePassword -(which has been sent to the server as an attribute of the PKCS#10 -certificate request). If the ChallengePassword matches, the certificate -is revoked. The reason of the revocation is documented by CA/RA. - -2.2.5 Certificate Access - -There are two methods to query certificates. The first method is to use -LDAP as a query protocol. Using LDAP to query assumes the client -understand the LDAP scheme supported by the CA. The SCEP client assumes -that the subject DN name in the certificate is used as the URL to query the -certificate. The standard attributes (userCertificate and caCertificate) -are used as filter. - -For the environment where LDAP is not available, a certificate query -message is defined to retrieve the certificates from the CA. - -To query a certificate from the certificate authority, a requester -sends a request consisting of the certificate's issuer name and the -serial number. This assumes that the requester has saved the issuer - - Liu/Madson/McGrew/Nourse [Page 10] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -name and the serial number of the issued certificate from the previous -enrollment transaction. The transaction to query a certificate consists -of one GetCert PKI message and one CertRep PKI message: - - REQUESTER CA SERVER - GetCert: PKI cert query msg - -------------------------------> CertRep: pkiStatus = SUCCESS - certificate -attached - <----------------------------- - Receive the certificate. - -2.2.6 CRL Distribution - -The CA/RA will not "push" the CRL to the end entities. The query of the -CRL can only be initialized by the requester. - -There are three methods to query CRL. - -The CRL may be retrieved by a simple HTTP GET. If the CA supports this -method, it should encode the URL into a CRL Distribution Point extension -in the certificates it issues. Support for this method should be -incorporated in new and updated clients, but may not be in older -versions. - -The second method is to query CRL using LDAP. This assumes the CA server -supports CRL LDAP publishing and issues the CRL Distribution Point in -the certificate. The CRL Distribution Point is encoded as a DN. Please -refer to Appendix D for the examples of CRL Distribution Point. - -The third method is implemented for the CA which does not support LDAP -CRL publishing or does not implement the CRL Distribution Point. In this -case, a CRL query is composed by creating a message consists of the CA -issuer name and the CA's certificate serial number. This method is -deprecated because it does not scale well and requires the CA to be a -high-availability service. - -The message is sent to the CA in the same way as the other SCEP -requests: The transaction to query CRL consists of one GetCRL PKI -message and one CertRep PKI message which have no certificates but CRL. - - REQUESTER CA SERVER - GetCRL: PKI CRL query msg - ----------------------------------> CertRep: CRL attached - <-------------------------------- - -2.3 PKI Operation Transactional Behavior - -As described before, a PKI operation is a transaction consisting of the -messages exchanged between a requester and the CA/RA. This section -will specify the transaction behavior on both the requester and the - - - Liu/Madson/McGrew/Nourse [Page 11] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -certificate authority server. Because the protocol is basically a two -way communication protocol without a confirmation message from the -initiating side, state and state resynchronization rules have to be -defined, in case any error happens at either side. Before the state -transition can be defined, the notion of transaction identifier has to -be defined first. - -2.3.1 Transaction Identifier - -A transaction identifier is a string generated by the entity when -starting a transaction. Since all the PKI operations defined in this -protocol are initiated by the requester, it is the responsibility of -the requester to generate a unique string as the transaction -identifier. All the PKI messages exchanged for a given PKI transaction -must carry the same transaction identifier. The transaction identifier -is generated as a SHA-1 or MD5 hash on the public key value for which the -enrollment request is made. This allows the SCEP client to reuse the -same transaction identifier if it is reissuing a request for the same -certificate (i.e. a certificate with the same subject, issuer, and key). -The SCEP protocol requires that transaction identifiers be unique, so -that queries can be matched up with transactions. For this reason, in -those cases in which separate signing and encryption certificates are -issued to the same requester, the keys must be different. - -2.3.2 State Transitions in Certificate Enrollment - -The requester state transitions during enrollment operation are -indicated in the diagram below: - +-<------+ - | | - GetCertInitial triggered by timeout or - | | manual authentication - | | - [CERT-NONEXISTANT] ------> [CERT-REQ-PENDING] ---> [CERT-ISSUED] - | PKCSReq | CertRep with SUCCESS - | | - | | - +--------<-------------------+ - request rejected, timeout, or error - -As described in the section 2.2.3, certificate enrollment starts at the -state CERT-NONEXISTANT. Sending PKCSReq changes the state to -CERT-REQ-PENDING. Receiving CertRep with SUCCESS status changes the -state to CERT-ISSUED. In the case the server sending back the response -with pending status, the requester will keep polling certificate -response by sending GetCertInitial to the server, until either a CertRep -with SUCCESS status is received, or the maximum polling number has been -exceeded. - -If an error or timeout occurs in the CERT-REQ-PENDING state, the end -entity will transition to the CERT-NONEXISTANT state. - - - Liu/Madson/McGrew/Nourse [Page 12] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -The client administrator will, eventually, start up another enrollment -request. It is important to note that, as long as the requester does -not change its subject name or keys, the same transaction id will be -used in the "new" transaction. This is important because based on this -transaction id, the certificate authority server can recognize this as -an existing transaction instead of a new one. - - -2.3.3 Transaction Behavior of Certificate/CRL Access - -There is no state maintained during certificate access and CRL access -transaction. When using the certificate query and CRL query messages -defined in this protocol, the transaction identifier is still required -so that the requester can match the response message with the -upstanding request message. When using LDAP to query the certificate and -the CRL, the behavior is specified by the LDAP protocol. - -2.4 Security - -The security goals of SCEP are that no adversary can: - -o subvert the public key/identity binding from that intended, -o discover the identity information in the enrollment requests and - issued certificates, -o cause the revocation of certificates with any non-negligible - probability. - -Here an adversary is any entity other than the requester and the CA -(and optionally the RA) participating in the protocol that is -computationally limited, but that can manipulate data during -transmission (that is, a man-in-the-middle). The precise meaning of -'computationally limited' depends on the implementer's choice of -cryptographic hash functions and ciphers. The required algorithms are -RSA, DES, and either SHA-1 or MD5, depending on the "SHA-1" CA Capability. -[See Appendix F]. - -The first and second goals are met through the use of PKCS#7 and PKCS#10 -encryption and digital signatures using authenticated public keys. The -CA's public key is authenticated via the checking of the CA fingerprint, -as specified in Section 2.1.2, and the SCEP client's public key is -authenticated through the manual authentication or pre-shared secret -authentication, as specified in Section 2.1.1.2. The third goal is met -through the use of a Challenge Password for revocation, that is chosen -by the SCEP client and communicated to the CA protected by the PKCS#7 -encryption, as specified in Section 2.2.4. - -The motivation of the first security goal is straightforward. The -motivation for the second security goal is to protect the identity -information in the enrollment requests and certificates. For example, -two IPSEC hosts behind a firewall may need to exchange certificates, and -may need to enroll certificates with a CA that is outside of a firewall. -Most networks with firewalls seek to prevent IP addresses and DNS - - Liu/Madson/McGrew/Nourse [Page 13] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -information from the trusted network leaving that network. The second -goal enables the hosts in this example to enroll with a CA outside the -firewall without revealing this information. The motivation for the -third security goal is to protect the SCEP clients from denial of -service attacks. - -Section 3 Transport Protocol - -In the SCEP protocol, HTTP is used as the transport protocol for the PKI -messages. - -3.1 HTTP "GET" and "POST" Message Format - -The following is the syntax definition of a HTTP GET message sent from -a requester to a certificate authority server: - -Request = "GET " CGI-PATH CGI-PROG "?operation=" OPERATION "&message=" MESSAGE -where: - CGI-PATH defines the actual CGI path to invoke the CGI program which - parses the request. - CGI-PROG is set to be the string "pkiclient.exe". This is intended - to be the program that the CA will use to handle the SCEP transactions, - though the CA may ignore CGI-PROG and use only the CGI-PATH. - OPERATION is set to be the string "PKIOperation" when the GET message - carries a PKI message to request certificates or CRL; OPERATION is set - to be the string "GetCACaps", "GetCACert", "GetNextCACert" or - "GetCACertChain" when the GET operation is used to get CA capabilities, - CA/RA certificate, the replacement CA/RA certificates for when the - current ones expire, or the CA Cert chain (respectively). - - When OPERATION is "PKIOperation", MESSAGE is a base64-encoded PKI message, - When OPERATION is GetCACert, MESSAGE is a CRL distribution - point in URI format, otherwise, MESSAGE is a string which represents - the certificate authority issuer identifier. - -SCEP uses the HTTP "GET" and "POST" messages to request information from the CA. -Requests for CA certificates or capabilities are sent in the clear, using "GET", -with the OPERATION and MESSAGE fields identifying the requested data. -CRLs may also be requested in the clear if the CA supports it. - -Other types of requests are sent using the PKCS#7 secure protocol. -These may be issued by means of a GET operation with -OPERATION and MESSAGE parameters in the Request-URL. OPERATION -identifies the type of GET operation, and MESSAGE is actually the PKCS#7 -message Base64-Encoded. - -For example. a requester may submit a message via HTTP to the server -as follows: - -GET /cgi-bin/pkiclient.exe?operation=PKIOperation&message=MIAGCSqGSIb3D -QEHA6CAMIACAQAxgDCBzAIBADB2MGIxETAPBgNVBAcTCE ......AAAAAA== - Liu/Madson/McGrew/Nourse [Page 13a] - -If supported by the CA, the message may also be sent via HTTP POST: - -POST /cgi-bin/pkiclient.exe?operation=PKIOperation - -This is further described in Appendix H. -To determine if the CA supports POST, use the GetCACaps message described -in Appendix F. - - -3.2 Response Message Format - -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. The following is an -example of the response: - -"Content-Type:application/x-pki-message\n\n" - -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. the body of the response is a DER encoded -binary X.509 certificate. For example: - -"Content-Type:application/x-x509-ca-cert\n\n" - -If there is an RA, the RA certificates are sent back together with the -CA certificates, a certificate-only PKCS#7 SignedData is sent back in -the response where the SignerInfo is empty. Section 5 has the detailed -definition of the message format in this case. The content type is -application/x-x509-ca-ra-cert. - -The response to GetNextCACert is always a certificates-only PKCS#7 -SignedData with a content type of application/x-x509-ca-ra-cert. -If there is an RA, The signer is the current RA certificate. Otherwise, -the signer is the current CA certificate. - -If the CA supports it, PKIOperation may also be done via an HTTP POST. -This is described in Appendix H. - - Liu/Madson/McGrew/Nourse [Page 14] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Section 4 Secure Transportation: PKCS#7 - -PKCS#7 is a general enveloping mechanism that enables both signed and -encrypted transmission of arbitrary data. It is widely implemented and -included in the RSA tool kit. In this section, the general PKCS#7 -enveloped PKI message format is specified. The complete PKCS#7 message -format for each PKI transaction will be covered in Section 5. - -4.1 SCEP Message Format - -As a transaction message, a SCEP message has a set of transaction -specific attributes and an information portion. Employing PKCS#7 -protocol, the transaction specific attributes are encoded as a set of -authenticated attributes of the SignedData. The information portion will -first be encrypted to become Enveloped Data, and then the digest of the -enveloped information portion is included as one of the message digest -attributes and being signed together with the other transaction specific -attributes. - -By applying both enveloping and signing transformations, a SCEP message -is protected both for the integrity of its end-end-transition -information and the confidentiality of its information portion. The -advantage of this technique over the conventional transaction message -format is that, the signed transaction type information and the status -of the transaction can be determined prior to invoke security handling -procedures specific to the information portion being processed. - -The following is an example of a SCEP message with its enveloped and -signed data portion represented by pkcsPKISigned and -pkcsPKIEnveloped. The out-most of any PKI message is a blob of -ContentInfo, with its content type set to SignedData and the actual -signed data as the content. - - Liu/Madson/McGrew/Nourse [Page 15] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - pkiMessage ContentInfo ::= { - contentType {pkcs-7 signedData(2)} - content pkcsPKISigned - } - pkcsPKISigned SignedData ::= { - version 1 - digestAlgorithm { iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} -- data content identifier - content pkcsPKIEnvelope -- enveloped information portion - } - certificates -- signer certificate chain - signerInfo -- including signed transaction info and the digest - -- of the enveloped information portion as the - -- authenticated attributes - } - pkcsPKIEnveloped EnvelopedData ::= { - version 0 - recipientInfos -- information required to open the envelop - encryptedContentInfo { - contentType {pkcs-7 1} -- data content identifier - contentEncryptionAlgorithm - encryptedContent -- encrypted information portion - } - } - -4.2 Signed Transaction Attributes - -The following transaction attributes are encoded as authenticated -attributes. Please refer to Appendix B for the OID definitions. - -transactionID PrintableString -- Decimal value as a string - messageType PrintableString -- Decimal value as a string - pkiStatus PrintableString -- Decimal value as a string - failinfo PrintableString -- Decimal value as a string - senderNonce Octet String - recipientNonce Octet String - -where: - - The transactionID is an attribute which uniquely identify a - transaction. This attribute is required in all PKI messages. - - The messageType attribute specify the type of operation performed by the - transaction. This attribute is required in all PKI - messages. Currently, the following message types are defined: - - PKCSReq (19) -- Permits use of PKCS#10 certificate request - CertRep (3) -- Response to certificate or CRL request - GetCertInitial (20) -- Certificate polling in manual enrollment - GetCert (21) -- Retrieve a certificate - GetCRL (22) -- Retrieve a CRL - - Liu/Madson/McGrew/Nourse [Page 16] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - - All response message will include transaction status information which - is defined as pkiStatus attribute: - - SUCCESS (0) -- request granted - FAILURE (2) -- request rejected - PENDING (3) -- request pending for manual approval. - - If the status in the response is FAILURE, the failinfo attribute will - contain one of the following failure reasons: - - badAlg (0) -- Unrecognized or unsupported algorithm ident - badMessageCheck (1) -- integrity check failed - badRequest (2) -- transaction not permitted or supported - badTime (3) -- Message time field was not sufficiently close - to the system time - badCertId (4) -- No certificate could be identified matching - the provided criteria - - The attributes of senderNonce and recipientNonce are the 16 byte - random numbers generated for each transaction to prevent the replay - attack. - -When a requester sends a PKI message to the server, a senderNonce is -included in the message. After the server processes the request, it will -send back the requester senderNonce as the recipientNonce and generates -another nonce as the senderNonce in the response message. Because the -proposed pki protocol is a two-way communication protocol, it is clear -that the nonce can only be used by the requester to prevent the -replay. The server has to employ extra state related information to -prevent a replay attack. - -Section 5. SCEP Transaction Specification - -In this section each SCEP transaction is specified in terms of the -complete messages exchanged during the transaction. - -5.1 Certificate Enrollment - -The certificate enrollment transaction consists of one PKCSReq message -sent to the certificate authority from a requester, and one CertRep -message sent back from the server. The pkiStatus returned in the -response message is either SUCCESS, or FAILURE, or PENDING. The -information portion of a PKCSReq message is a PKCS#10 certificate -request, which contains the subject Distinguished Name, the subject -public key, and two attributes, a ChallengePassword attribute to be used -for revocation, and an optional ExtensionReq attribute which will be a -sequence of extensions the requester expects to be included in its V3 -certificate extensions. One of the extension attribute specifies the key -usage. If the request is granted, the pkiStatus is set to SUCCESS, and -the certificate is returned in CertRep; if the request is rejected, the - - - Liu/Madson/McGrew/Nourse [Page 17] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -pkiStatus is set to FAILURE; if the server requires manual approval of -the request, the pkiStatus is set to PENDING. The messages exchanged -in the manual authentication mode is further specified in Section 5.2. - -Precondition: - Both the requester and the certificate authority have completed their - initialization process. The requester has already been configured - with the CA/RA certificate. - -Postcondition: - Either the certificate is received by the requester, or the end - entity is notified to do the manual authentication, or the request - is rejected. - -5.1.1 PKCSReq Message Format - -A PKCSReq message is created by following the steps defined below: - -1. Create a PKCS#10 certificate request which is signed by the end - entity's private key, corresponding to the public key included in - the PKCS#10 certificate request. This constitutes the information - portion of PKCSReq. - -2. Encrypt the PKCS#10 certificate request using a randomly generated - content-encryption key. This content-encryption key is then - encrypted by the CA's* public key and included in the recipientInfo. - This step completes the "envelope" for the PKCS#10 certificate - request. - -3. Generate a unique string as the transaction id. - -4. Generate a 16 byte random number as senderNonce. - -5. Generate message digest on the enveloped PKCS#10 certificate request - using the selected digest algorithm. - -6. Create SignedData by adding the requester's self- or CA-certificate - as the signer's public key certificate. Include the message type, - transaction id, the senderNonce and the message digest as the - authenticated attributes and sign the attributes using the end - entity's private key. This completes the SignedData. - -7. The SignedData is prepended with the ContenInfo blob which indicates - a SignedData object. This final step completes the create of a - complete PKCSReq PKI message. - -In the following, the PKCSReq message is defined following the ASN.1 -notation. - -For readability, the values of a field is either represented by a quoted -string which specifies the intended value, or a constant when the value -is known. - - - Liu/Madson/McGrew/Nourse [Page 18] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -- PKCSReq information portion - pkcsCertReq CertificationRequest ::= { -- PKCS#10 - version 0 - subject "the requester's subject name" - subjectPublicKeyInfo { - algorithm {pkcs-1 1} -- rsa encryption - subjectPublicKey "DER encoding of the requester's public key" - } - attributes { - challengePassword {{pkcs-9 7} "password string" } - extensions - } - signatureAlgorithm {pkcs-1 4} -- MD5WithRSAEncryption - signature "bit string which is created by signing inner content - of the defined pkcsCertReq using requester's private - key, corresponding to the public key included in - subjectPublicKeyInfo." - } - -- Enveloped information portion - pkcsCertReqEnvelope EnvelopeData ::= { -- PKCS#7 - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the CA issuer name" - serialNumber "the CA certificate serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} -- rsa encryption - encryptedKey "content-encryption key - encrypted by CA public key" - } - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "object identifier - for DES encryption" - encryptedContent "encrypted pkcsCertReq using the content- - encryption key" - } - } - -- Signed PKCSReq - pkcsCertReqSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} -- data content identifier - content pkcsCertReqEnvelope - } - certificate { -- requester self-signed or CA-issued certificate - version 3 - serialNumber "the transaction id associated with enrollment" - signature {pkcs-1 4} -- md5WithRSAEncryption - - - Liu/Madson/McGrew/Nourse [Page 19] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - issuer " the requester's subject name" - validity { - notBefore "a UTC time" - notAfter "a UTC time" - } - subject "the requester's subject name" - subjectPublicKeyInfo { - algorithm {pkcs-1 1} - subjectPublicKey "DER encoding of requester's public key" - } - signatureAlgorithm {pkcs-1 4} - signature "the signature generated by using the requester's - private key corresponding to the public key in - this certificate." - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the requester's subject name" - serialNumber "the transaction id associated - with the enrollment" - } - digestAlgorithm {iso(0) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "an octet string"} - transaction-id {{id-attributes transId(7)} "printable - string"} - -- this transaction id will be used - -- together with the subject name as - -- the identifier of the requester's key - -- pair during enrollment - messageType {{id-attributes messageType(2)} "PKCSReq"} - senderNonce {{id-attributes senderNonce(5)} - "a random number encoded as a string"} - } - digestEncryptionAlgorithm {pkcs-1 1} -- rsa encryption - encryptedDigest "encrypted digest of the authenticated - attributes using requester's private key" - } - } - pkcsReq PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsCertRepSigned - } - - - - - - - - - Liu/Madson/McGrew/Nourse [Page 20] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -5.1.2 CertRep Message Format - -The response to an SCEP enrollment request is a CertRep message. - -5.1.2.1 PENDING Response - -When the CA is configured to manually authenticate the requester, -the CertRep is returned with the attribute pkiStatus set to PENDING. -The data portion for this message is null. Only the transaction -required attributes are sent back. - -CertRepSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo {contentType {pkcs-7 1} -- empty content - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "name of CA that issued the CA [RA] cert" - serialNumber "the serial number of the CA [RA] cert" - } - digestAlgorithm (iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} NULL} - messageType {{id-attribute messageType(0)} "CertRep"} - transaction-id {{id-attributes transid(7)} "printablestring"} - --- same transaction id used in PKCSReq - pkiStatus {{id-attributes pkiStatus(3)} "PENDING"} - recipientNonce {{id-attributes recipientNonce(6)}<16 bytes>} - senderNonce {{id-attributes senderNonce(5)} <16 bytes>} - } - digestEncrytionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted message digest of the authenticated - attributes using the CA's [RA's] private key" - } -} -CertRep PKIMessage ::= { - contentType {pkcs-7 2} - content CertRepSigned -} - -5.1.2.2 Failure Response - -In this case, the CertRep sent back to the requester is same as in -the PENDING case, except that the pkiStatus attribute is set to FAILURE, -and the failInfo attribute should be included: - - pkistatus {{id-attributes pkiStatus(3)} "FAILURE"} - failInfo {{id-attributes failInfo(4)} "the reason to reject"} - - Liu/Madson/McGrew/Nourse [Page 21] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -5.1.2.3 SUCCESS response - -In this case, the information portion of CertRep will be a degenerated -PKCS#7 which contains the requester's certificate. It is then enveloped -and signed as below: - -pkcsCertRep SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { -- empty content since this is degenerated PKCS#7 - contentType {pkcs-7 1} - } - certificates { - certificate { -- issued requester's certificate // must be first - version 3 - serialNumber "issued requester's certificate serial number" - signature {pkcs-1 4} -- md5WithRSAEncryption - issuer "the certificate authority issuer name" - validity { - notBefore "UTC time" - notAfter "UTC time" - } - subject "the requester subject name as given in PKCS#10" - subjectPublicKeyInfo { - algorithm {pkcs-1 1} - subjectPublicKey "a DER encoding of requester public - key as given in PKCS#10" - } - extensions " the extensions as given in PKCS#10" - signatureAlgorithm {pkcs-1 4} - signature " the certificate authority signature" - } - certificate "the certificate authority certificate" (optional) - certificate "the registration authority certificate(s)" (optional) - } -} -pkcsCertRepEnvelope EnvelopedData ::= { -- PKCS#7 - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { -- use issuer name and serial number as - -- conveyed in requester's self-signed - -- certificate, included in the PKCSReq - issuer "the requester's subject name" - serialNumber "the serial number defined by the requester in - its self-signed certificate" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted by the requester's - public key which is same key as authenticated in - the requester's certificate" - } - - - Liu/Madson/McGrew/Nourse [Page 22] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - encryptedContentInfo { - contentType {pkcs-7 1} -- data content identifier - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted pkcsCertRep using content encryption - key" - } -} -pkcsCertRepSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - content pkcsCertRepEnvelope - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the certificate authority issuer name" - serialNumber "the CA certificate's serial number" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "a octet string"} - messageType {{id-attribute messageType(2)} "CertRep"} - transaction-id {{id-attributes transId(7)} "printable - string"} - -- same transaction id as given in PKCSReq - pkiStatus {{id-attributes pkiStatus(3) "SUCCESS"} - recipientNonce {{id-attribute recipientNonce(6)}<16 bytes>} - senderNonce {{ id-attributes senderNonce(5) <16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticate attributes - using CA's private key " - } -} -CertRep PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsCertRepSigned -} - -5.2 Poll for Requester Initial Certificate - -Either triggered by the PENDING status received from the CertRep, or by -the non-response timeout for the previous PKCSReq, a requester will -enter the polling state by periodically sending GetCertInitial to the -server, until either the request is granted and the certificate is sent -back, or the request is rejected, or the configured time limit for -polling is exceeded. - - - Liu/Madson/McGrew/Nourse [Page 23] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -Since GetCertInitial is part of the enrollment, the messages exchanged -during the polling period should carry the same transaction identifier -as the previous PKCSReq. - -PreCondition - Either the requester has received a CertRep with pkiStatus set to be - PENDING, or the previous PKCSReq has timed out. - -PostContition - The requester has either received the certificate, or be rejected of - its request, or the polling period ended as a failure. - -5.2.1 GetCertInitial Message Format - -Since at this time the certificate has not been issued, the requester -can only use the requester's subject name, combined with the -transaction identifier, to identify the polled certificate request. - -The certificate authority server must be able to uniquely identify the -polled certificate request. A subject name can have more than one -outstanding certificate request (with different key usage attributes). - --- Information portion - -pkcsGetCertInitial issuerAndSubject ::= { - issuer "the certificate authority issuer name" - subject "the requester subject name as given in PKCS#10" -} -pkcsGetCertInitialEnvelope EnvelopedData ::= { - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the CA issuer name" - serialNumber "the CA certificate serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted by CA's public key" - } - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted getCertInital" - } -} -pkcsGetCertInitialSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - - - Liu/Madson/McGrew/Nourse [Page 24] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - content pkcsGetCertIntialEnvelope - } - certificate { -- the requester's self-signed certificate - version 3 - serialNumber "the transaction id associated with enrollment" - signature {pkcs-1 4} -- md5WithRSAEncryption - issuer " the requester's subject name" - validity { - notBefore "a UTC time" - notAfter "a UTC time" - } - subject "the requester's subject name" - subjectPublicKeyInfo { - algorithm {pkcs-1 1} - subjectPublicKey "DER encoding of requester's public key" - } - signatureAlgorithm {pkcs-1 4} - signature "the signature generated by using the requester's - private key corresponding to the public key in - this certificate." - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "requester's subject name" - serialNumber "the transaction id used in previous PKCSReq" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "an octet string"} - -- digest of getCertInitial - messageType {{id-attribute messageType(2)} "GetCertInitial"} - transaction-id {{id-attributes transId(7)} "printable - string"} - -- same transaction idused in previous PKCSReq - senderNonce {{id-attribute senderNonce(3)} 0x<16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticateAttributes" - } -} -GetCertInitial PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsGetCertInitialSigned -} - - - -5.2.2 GetCertInitial Response Message Format - -The response messages for GetCertInitial are the same as for PKCSReq. - - Liu/Madson/McGrew/Nourse [Page 25] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -5.3 Certificate Access - -The certificate query message defined in this section is an option when -the LDAP server is not available to provide the certificate query. A -requester should be able to query an issued certificate from the -certificate authority, as long as the issuer name and the issuer -assigned certificate serial number is known to the requesting end -entity. This transaction is not intended to provide the service as a -certificate directory service. A more complicated query mechanism would -have to be defined in order to allow a requester to query a certificate -using various different fields. - -This transaction consists of one GetCert message sent to the server by -a requester, and one CertRep message sent back from the server. - -PreCondition - The queried certificate have been issued by the certificate authority - and the issuer assigned serial number is known. - -PostCondition - Either the certificate is sent back or the request is rejected. - - -5.3.1 GetCert Message Format - -The queried certificate is identified by its issuer name and the issuer -assigned serial number. If this is a query for an arbitrary requester's -certificate, the requesting requester should includes its own CA issued -certificate in the signed envelope. If this is a query for its own -certificate (assume the requester lost the issued certificate, or does -not have enough non-volatile memory to save the certificate), then the -self-signed certificate has to be included in the signed envelope. - - pkcsGetCert issuerAndSerialNumber ::= { - issuer "the certificate issuer name" - serialNumber "the certificate serial number" - } - pkcsGetCertEnvelope EnvelopedData ::= { - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the CA [RA] issuer name" - serialNumber "the CA [RA] certificate serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted - by CA [RA] public key" - } - - - - - - Liu/Madson/McGrew/Nourse [Page 26] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted pkcsGetCert using the content - encryption key" - } - } - pkcsGetCertSigned SignedData ::= { - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - content pkcsGetCertEnvelope - } - certificates { - certificate "CA issued certificate" - or "self-signed certificate" - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the requester's subject name" - serialNumber "requester's certificate serial number" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "an octet string"} - -- digest of pkcsGetCertEnvelope - messageType {{id-attribute messageType(2)} "GetCert"} - transaction-id {{id-attributes transId(7)} "printable - string"} - senderNonce {{id-attribute senderNonce(3)} <16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticateAttributes" - } - } - GetCert PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsGetCertSigned - } - - - - - - - - - - Liu/Madson/McGrew/Nourse [Page 27] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -5.3.2 CertRep Message Format - -In this case, the CertRep from the server is same as the CertRep for the -PKCSReq, except that the server will only either grant the request or -reject the request. Also, the recipientInfo should use the CA issuer -name and CA assigned serial number to identify the requester's key pair -since at this time, the requester has received its own certificate. - -5.4 CRL Access - -The CRL query message defined in this section is an option when the LDAP -server is not available to provide the CRL query. In the PKI protocol -proposed here, only the requester can initiate the transaction to -download CRL. A requester sends GetCRL request to the server and the -server sends back CertRep whose information portion is a degenerated -PKCS#7 which contains only the most recent CRL. The size of CRL included -in the CertRep should be determined by the implementation. - -PreCondition - The certificate authority certificate has been downloaded to the end - entity. - -PostCondition - CRL sent back to the requester. - -5.4.1 GetCRL Message format - -The CRL is identified by using both CA's issuer name and the CA -certificate's serial number: - - pkcsGetCRL issuerAndSerialNumber { - issuer "the certificate authority issuer name" - serialNumber "certificate authority certificate's serial number" - } - -When the CRLDistributionPoint is supported, the pkcsGetCRL is defined as -the following: - - pkcsGetCRL SEQUENCE { - crlIssuer issuerAndSerialNumber - distributionPoint CE-CRLDistPoints - } - -where CE-CRLDisPoints is defined in X.509, but must contain only one -CRL distribution point. - - - - - - - - - - - Liu/Madson/McGrew/Nourse [Page 28] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - pkcsGetCRLEnvelope EnvelopedData ::= { - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the certificate authority (or RA) issuer name" - serialNumber "the CA (RA) certificate's serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted by CA (RA) public key" - } - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted pkcsGetCRL" - } - } - pkcsGetCRLSigned SignedData ::= { - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - content pkcsGetCRLEnvelope - } - certificates { - certificate "CA-issued or self-signed requester's certificate" - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the requester's issuer name" - serialNumber "the requester's certificate serial number" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} 0x<16/20 bytes>} - -- digest of pkcsGetCRLEnvelope - messageType {{id-attribute messageType(2)} "CertCRL"} - transaction-id {{id-attributes transId(7)} "printable - string"} - senderNonce {{id-attribute senderNonce(3)} <16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticateAttributes" - } - } - GetCRL PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsGetCRLSigned - } - - Liu/Madson/McGrew/Nourse [Page 29] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -5.4.2 CertRep Message Format - -The CRL is sent back to the requester through CertRep message. The -information portion of this message is a degenerated PKCS#7 SignedData -which contains only a CRL. - - pkcsCertRep SignedData ::= { - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - } - crl { - signature {pkcs-1 4} - issuer "the certificate authority issuer name" - lastUpdate "UTC time" - nextUpdate "UTC time" - revokedCertificate { - -- the first entry - userCertificate "certificate serial number" - revocationData "UTC time" - .... - -- last entry - userCertificate "certificate serial number" - revocationData "UTC time" - } - } - pkcsCertRepEnvelope EnvelopedData ::= { - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the requester's issuer name" - serialNumber "the requester certificate serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted by requester's - public key " - } - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted pkcsCertRep using requester's - public key" - } - } - - - - - - - Liu/Madson/McGrew/Nourse [Page 30] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - - pkcsCertRepSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - content pkcsCertRepEnvelope - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the certificate authority issuer name" - serialNumber "the CA certificate's serial number" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "an octet string"} - -- digest of pkcsCertRepEnvelope - messageType {{id-attribute messageType(2)} "CertRep"} - transaction-id {{id-attributes transId(7)} "printable - string"} - -- same transaction id as given in PKCSReq - pkiStatus {{id-attributes pkiStatus(3) "SUCCESS"} - recipientNonce{{id-attribute recipientNonce(6)}<16 bytes>} - senderNonce {{id-attribute senderNonce (5) 0x<16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticatedAttributes - using CA private key" - } - } - - -NOTE:The PKCS#7 EncryptedContent is specified as an octet string, but -SCEP entities must also accept a sequence of octet strings as a valid -alternate encoding. - -This alternate encoding must be accepted wherever PKCS #7 Enveloped -Data is specified in this document. - - - - - - - - - - - - Liu/Madson/McGrew/Nourse [Page 31] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -5.5 Get Certificate Authority Certificate - -Before any transaction begins, end entities have to get the CA (and -possibly RA) certificate(s) first. Since the requester may have no CA -certificates or CA public keys at all, this message can not be -encrypted and the response must be authenticated by out-of-band means. -These certs are obtained by means of an HTTP GET message. To get the -CA certificate, the requester does a "HTTP GET" with a URL that -identifies a CGI script on the server and an optional CA issuer -identifier as the parameter to the CGI script. The response is either -a single X.509 CA certificate ("CA mode"), or a PKCS7 message -containing the CA certificate and RA certificates ("RA mode"). The -client can determine which mode the CA operates in by which response -it gets. Once the CA certificate is received by the requester, a -fingerprint is generated using either the SHA-1 or the MD5 hash -algorithm on the whole CA certificate. If the requester does not have -a certificate path to a trusted CA certificate, this fingerprint may -be used to verify the certificate, by some positive out-of-band means, -such as a phone call. - -5.5.1 GetCACert HTTP Message Format - "GET" CGI-PATH CGI-PROG "?operation=GetCACert" "&message=" CA-IDENT - where: - CGI-PATH defines the actual CGI path to invoke the CGI program - which parses the request. - CGI-PROG is set to be the string "pkiclient.exe" and this is - expected to be the program that the CA will use to handle the - SCEP transactions. - CA-IDENT is any string which is understood by the CA. - For example, it could be a domain name like ietf.org. - If a certificate authority has multiple CA certificates - this field can be used to distinguish which is required. - Otherwise it may be ignored. - -5.5.2 Response - -The response for GetCACert is different between the case where the CA -directly communicated with the requester during the enrollment, and the -case where a RA exists and the requester communicates with the RA -during the enrollment. - -5.5.2.1 CA Certificate Only Response - -A binary X.509 CA certificate is sent back as a MIME object with a -Content-Type of application/x-x509-ca-cert. - -5.5.2.2 CA and RA Certificates Response - -When an RA exists, both CA and RA certificates must be sent back in -the response to the GetCACert request. The RA certificate(s) must be -signed by the CA. A certificates-only PKCS#7 SignedData is used to -carry the certificates to the requester, with a Content-Type of -application/x-x509-ca-ra-cert. - - Liu/Madson/McGrew/Nourse [Page 32] - -5.5.3 Get Next Certificate Authority Certificate - -5.5.3.1 GetNextCACert HTTP Message Format - "GET" CGI-PATH CGI-PROG "?operation=GetNextCACert" "&message=" CA-IDENT - -The response to this message is a PKCS#7 certificates-only message containing -a CA certificate (and possibly RA certificates) to be used when the current CA -certificate expires, signed with the current CA cert (or RA certificate, if -the CA is in RA mode. Note that a PKCS#7 is returned even in CA mode. - -5.5.3.2 GetCACaps HTTP Message Format - "GET" CGI-PATH CGI-PROG "?operation=GetCACaps" "&message=" CA-IDENT - -This message requests capabilities from CA. The response is a list of -text capabilities, as defined in Appendix F. Support for this message -is optional, but if it is not supported, the client should assume that -none of the capabilities in Appendix F are supported. - -5.6 Get Certificate Authority Certificate Chain - -GetCACertChain provides a way to get the entire certificate chain. - -5.6.1 GetCACertChain HTTP Message Format - - "GET" CGI-SCRIPT "?" "operation=GetCACertChain" "&" "message" CA-IDENT - where CGI-SCRIPT and CA-IDENT are as described for GetCACert. - -5.6.2 Response - -The response for GetCACertChain is a certificates-only PKCS#7 SignedData -to carry the certificates to the requester, with a Content-Type of -application/x-x509-ca-ra-cert-chain. - -5.6.3 Backwards Compatability - -Versions of SCEP prior to revision 3 do not support GetCACertChain. -Certificate Authorities written to these prior versions will not be -able to process the message and may return an HTML error. - -To avoid this, clients should send the GetCACert message first. If the -returned certificate is self-signed or is signed by a Certificate -Authority that is trusted by the client, then it is not necessary to -send the GetCACertChain message and it should not be sent. - -If a Certificate Authority is configured with a certificate that is -not either self-signed or has a self-signed issuer, then it should -support this message. In other words, it should be supported if the -CA hierarchy is more than two-deep. - -An old CA in a two-deep hierarchy might still get this message from -a client if the client did not trust either that CA or its issuer. -In that event, the certificate cannot be trusted anyway. In any case -the CA must not crash or hang upon the receipt of the message and the -client must be able to handle whatever error is returned by the CA, -including an HTML error or an ungraceful disconnect. - - Liu/Madson/McGrew/Nourse [Page 33] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -The following is the ASN.1 definition of Cert-Only PKCS#7: - - certOnly SignedData ::= { - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - -contentInfo { - contentType {pkcs-7 1} -- data content identifier - content -- NULL - } - certificates -- the RA and CA certificates. - } - - CARACerts PKIMessage ::= { -- special pki message sent in the clear - contentType {pkcs-7 2} - content certOnly - } - - -6.0 Security Considerations - -This entire document is about security. Common security considerations -such as keeping private keys truly private and using adequate lengths -for symmetric and asymmetric keys must be followed in order to maintain -the security of this protocol. - - -7.0 Intellectual Property - -This protcol includes the optional use of Certificate Revocation List -Distribution Point (CRLDP) technology, which is a patented technology -of Entrust Technologies, Inc. (Method for Efficient Management of -Certificate Revocation Lists and Update Information (U.S. Patent -5,699,431)). Please contact Entrust Technologies, Inc. -(www.entrust.com) for more information on licensing CRLDP technology. - - -8.0 References - -[PKCS7] Kaliski, B., "PKCS #7: Cryptographic Message Syntax Version -1.5", RFC 2315, March 1998. - -[PKCS10] Kaliski, B., "PKCS #10: Certification Request Syntax Version -1.5", RFC 2314, March 1998. - -[RFC2459] Housley, R., ec. al., "Internet X.509 Public Key -Infrastructure Certificate and CRL Profile", RFC 2459, January 1999. - - - - - - - Liu/Madson/McGrew/Nourse [Page 34] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Appendix A: Cisco Requester Subject Name Definition - -The ip address and the FQDN of a SCEP client should be included in the -V3 extension subjectAltName. When the subjectAltName extension attribute -is present, both the subjectAltName fields and the subjectName field could -have the IP address and the FQDN information. - -When the X.500 directory is used by the CA to define the name space, the -subject name defined above become a RDN which is part of DN binded to -the requester's public key in the certificate. - - -A sample of DN assigned by Entrust CA is given below (assume the same -ciscoRouterAlice is used as the requester defined subject name): - - OU = InteropTesting, O = Entrust Technologies, C = CA - RDN = {"alice.cisco.com", "172.21.114.67", "22334455"} - - - Liu/Madson/McGrew/Nourse [Page 35] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Appendix B: IPSEC Client Enrollment Certificate Request - -The following is the certificate enrollment request (PKCS#10) as created -by Cisco VPN Client: - ------END NEW CERTIFICATE REQUEST----- - 0 30 439: SEQUENCE { - 4 30 288: SEQUENCE { - 8 02 1: INTEGER 0 - 11 30 57: SEQUENCE { - 13 31 55: SET { - 15 30 53: SEQUENCE { - 17 06 3: OBJECT IDENTIFIER commonName (2 5 4 3) - 22 13 46: PrintableString - : 'For Xiaoyi, IPSEC attrs in alternate name - extn' - : } - : } - : } - 70 30 158: SEQUENCE { - 73 30 13: SEQUENCE { - 75 06 9: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 - 1 1) - 86 05 0: NULL - : } - 88 03 140: BIT STRING 0 unused bits - : 30 81 88 02 81 80 73 DB 1D D5 65 AA EF C7 D4 8E - : AA 6E EB 46 AC 91 2A 0F 50 51 17 AD 50 A2 2A F2 - : CE BE F1 E4 22 8C D7 61 A1 6C 87 61 62 92 CB A6 - : 80 EA B4 0F 09 9D 18 5F 39 A3 02 0E DB 38 4C E4 - : 8A 63 2E 72 8B DC BE 9E ED 6C 1A 47 DE 13 1B 0F - : 83 29 4D 3E 08 86 FF 08 2B 43 09 EF 67 A7 6B EA - : 77 62 30 35 4D A9 0F 0F DF CC 44 F5 4D 2C 2E 19 - : E8 63 94 AC 84 A4 D0 01 E1 E3 97 16 CD 86 64 18 - : [ Another 11 bytes skipped ] - : } - 231 A0 63: [0] { - 233 30 61: SEQUENCE { - 235 06 9: OBJECT IDENTIFIER extensionReq (1 2 840 113549 1 9 - 14) - 246 31 48: SET { - 248 30 46: SEQUENCE { - 250 30 44: SEQUENCE { - 252 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17) - 257 04 37: OCTET STRING - 30 23 87 04 01 02 03 04 81 0D 65 6D 61 69 - - - Liu/Madson/McGrew/Nourse [Page 36] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - 6C 40 69 72 65 2E 63 6F 6D 82 0C 66 71 64 - 6E 2E 69 72 65 2E 63 6F 6D - : } - : } - : } - : } - : } - : } - - 296 30 13: SEQUENCE { - 298 06 9: OBJECT IDENTIFIER md5withRSAEncryption (1 2 840 113549 - 1 1 4) - 309 05 0: NULL - : } - 311 03 129: BIT STRING 0 unused bits - : 19 60 55 45 7F 72 FD 4E E5 3F D2 66 B0 77 13 9A - : 87 86 75 6A E1 36 C6 B6 21 71 68 BD 96 F0 B4 60 - : 95 8F 12 F1 65 33 16 FD 46 8A 63 19 90 40 B4 B7 - : 2C B5 AC 63 17 50 28 F0 CD A4 F0 00 4E D2 DE 6D - : C3 4F F5 CB 03 4D C8 D8 31 5A 7C 01 47 D2 2B 91 - : B5 48 55 C8 A7 0B DD 45 D3 4A 8D 94 04 3A 6C B0 - : A7 1D 64 74 AB 8A F7 FF 82 C7 22 0A 2A 95 FB 24 - : 88 AA B6 27 83 C1 EC 5E A0 BA 0C BA 2E 6D 50 C7 - : } - - -Appendix C: Private OID Definitions - -The OIDs used in defining pkiStatus are VeriSign self-maintained -OIDs. Please note, work is in progress to replace the VeriSign owned -object identifiers with the standard object identifiers. Once the -standarlization is completed, this documentation will be updated. - -id-VeriSign OBJECT_IDENTIFIER ::= {2 16 US(840) 1 VeriSign(113733)} -id-pki OBJECT_IDENTIFIER ::= {id-VeriSign pki(1)} -id-attributes OBJECT_IDENTIFIER ::= {id-pki attributes(9)} -id-messageType OBJECT_IDENTIFIER ::= {id-attributes messageType(2)} -id-pkiStatus OBJECT_IDENTIFIER ::= {id-attributes pkiStatus(3)} -id-failInfo OBJECT_IDENTIFIER ::= {id-attributes failInfo(4)} -id-senderNonce OBJECT_IDENTIFIER ::= {id-attributes senderNonce(5)} -id-recipientNonce OBJECT_IDENTIFIER ::= {id-attributes recipientNonce(6)} -id-transId OBJECT_IDENTIFIER ::= {id-attributes transId(7)} -id-extensionReq OBJECT_IDENTIFIER ::= {id-attributes extensionReq(8)} - - - Liu/Madson/McGrew/Nourse [Page 37] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - Appendix D: CRL Query by means of LDAP - - In order to retrieve the CRL by means of LDAP, the client needs to know - where in the directory it is stored. The certificate must contain a - CRL Distribution Point extension encoded as a DN or as an LDAP URI. - -For example, the certificate issued by Entrust VPN contains -the following DN as the CRL distribution point: - - - -CN = CRL1, O = cisco, C = US. - - The asn.1 encoding of this distribution point is: - - 30 2C 31 0B 30 09 06 03 55 04 06 13 02 55 53 31 0E 30 0C 06 - 03 55 04 0A 13 05 63 69 73 63 6F 31 0D 30 0B 06 03 55 04 03 - 13 04 43 52 4C 31 - - -The ldap form would be: - -ldap://servername/CN=CRL1,O=cisco,C=US - - - -Appendix E: SCEP State Transitions - -SCEP state transitions are based on transaction identifier. The design -goal is to ensure the synchronization between the CA and the requester -under various error situations. - - -An identity is defined by the combination of FQDN, the IP address and -the client serial number. FQDN is the required name attribute. It is -important to notice that, a client named as Alice.cisco.com is different -from the client named as Alice.cisco.com plus IPAddress 117.96.1.219. - -Each enrollment transaction is uniquely associated with a transaction -identifier. Because the enrollment transaction could be interrupted by -various errors, including network connection errors or client reboot, -the SCEP client generates a transaction identifier by calculating a -hash on the public key value for which the enrollment is requested. This -retains the same transaction identifier throughout the enrollment -transaction, even if the client has rebooted or timed out, and issues a -new enrollment request for the same key pair. It also provides the way -for the CA to uniquely identify a transaction in its database. At the -requester side, it generates a transaction identifier which is included -in PKCSReq. If the CA returns a response of PENDING, the requester -will poll by periodically sending out GetCertInitial with the same -transaction identifier until either a response other than PENDING is -obtained, or the configured maximum time has elapsed. - -If the client times out or the client reboots, the client administrator -will start another enrollment transaction with the same key pair. The -second enrollment will have the transaction idenifier. At the server -side, instead of accepting the PKCSReq as a new enrollment request, it -should respond as if another GetCertInitial message had been sent with -that transaction ID. In another word, the second PKCSReq should be -taken as a resynchronization message to allow the enrollment resume as -the same transaction. - -It is important to keep the transaction id unique since SCEP requires the -same policy and same identity be applied to the same subject name and - - - Liu/Madson/McGrew/Nourse [Page 38] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -key pair binding. In the current implementation, an SCEP client can -only assume one identity. At any time, only one key pair, with a given -key usage, can be associated with the same identity. - -The following gives several examples of client to CA transactions. - -Client actions are indicated in the left column, CA actions are -indicated in the right column. A blank action signifies that no message -was received. Note that these examples assume that the CA enforces the -certificate-name uniqueness property defined in Section 2.1.1.1. - -The first transaction, for example, would read like this: - "Client Sends PKCSReq message with transaction ID 1 to the - CA. The CA signs the certificate and constructs a CertRep Message - containing the signed certificate with a transaction ID 1. The client - receives the message and installs the cert locally." - -Successful Enrollment Case: no manual authentication -PKCSReq (1) ----------> CA Signs Cert -Client Installs Cert <---------- CertRep (1) SIGNED CERT - - - -Successful Enrollment Case: manual authentication required -PKCSReq (10) ----------> Cert Request goes into Queue -Client Polls <---------- CertRep (10) PENDING -GetCertInitial (10) ----------> Still pending -Client Polls <---------- CertRep (10) PENDING -GetCertInitial (10) ----------> Still pending -Client Polls <---------- CertRep (10) PENDING -GetCertInitial (10) ----------> Still pending -Client Polls <---------- CertRep (10) PENDING -GetCertInitial (10) ----------> Cert has been signed -Client Installs Cert <---------- CertRep (10) SIGNED CERT - - - -Resync Case - CA Receive and Signs PKCSReq, Client Did not receive -CertRep: - -PKCSReq (3) ----------> Cert Request goes into queue - <---------- CertRep (3) PENDING -GetCertInitial (3) ----------> - <---------- CertRep (3) PENDING -GetCertInitial (3) -----------> - <----------- CA signed Cert and sent back - CertRep(3) -(Time Out) -PKCSReq (3) ----------> Cert already signed, sent back to - client -Client Installs Cert <---------- CertRep (3) SIGNED CERT - - - - Liu/Madson/McGrew/Nourse [Page 39] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -Case when NVRAM is lost and client has to generate a new key pair, there -is no change of name information: - -PKCSReq (4) ----------> CA Signs Cert -Client Installs Cert <---------- CertRep (4) SIGNED CERT -(Client looses Cert) -PKCSReq (5) ----------> There is already a valid cert with - this DN. -Client Admin Revokes <---------- CertRep (5) OVERLAPPING CERT ERROR -PKCSReq (5) ----------> CA Signs Cert -Client Installs Cert <---------- CertRep (5) SIGNED CERT - - -Case when client admin resync the enrollment using a different PKCS#10: -PKCSReq (6) ----------> CA Signs Cert - <---------- CertRep (6) SIGNED CERT -(Client timeout and admin starts another enrollment with a different - PKCS#10, but the same transaction id) -PKCSReq (6) with different PKCS#10 - ----------> There is already a valid cert with - this entity (by checking FQDN). - <---------- CertRep (6) INVALID PKCS#10 CERT - ERROR -Client admin either revokes the existing cert -or corrects the error by enrolling with -the same PKCS#10 as the first PKCSReq(6) -PKCSReq (6) ----------> CA find the existing Cert -Client Installs Cert <---------- CertRep (6) SIGNED CERT - - -Resync case when server is slow in response: -PKCSReq (13) ----------> Cert Request goes into Queue - <---------- CertRep (13) PENDING -GetCertInitial ----------> Still pending - <---------- CertRep (13) PENDING -GetCertInitial ----------> Still pending - <---------- CertRep (13) PENDING -GetCertInitial ----------> Still pending - <---------- CertRep (13) PENDING -GetCertInitial ----------> Still pending -(TimeOut) <---------- CertRep (13) PENDING -* Case 1 -PKCSReq (13) ----------> Still pending -Client polls <---------- CertRep (13) PENDING -CertCertInitial ----------> Cert has been signed -Client Installs Cert <---------- CertRep (13) SIGNED CERT -* Case 2 -PKCSReq (13) ----------> Cert has been signed -Client Installs Cert <---------- CertRep (13) SIGNED CERT - - - - - Liu/Madson/McGrew/Nourse [Page 40] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Appendix F. CA Capabilities - -The response for a GetCACaps message is a list of CA capabilities, in -plain text, separated by characters, as follows (quotation marks -are NOT sent): - -Keyword Description - -"GetNextCACert" CA Supports the GetNextCACert message. -"POSTPKIOperation" PKIOPeration messages may be sent via HTTP POST. -"SHA-1" CA Supports the SHA-1 hashing algorithm in - signatures and fingerprints. If present, the - client SHOULD use SHA-1. If absent, the client - MUST use MD5 to maintain backward compatability. -"Renewal" Clients may use current certificate and key to - authenticate an enrollment request for a new - certificate. - -A client must be able to accept and ignore any unknown keywords that -might be sent back by a CA that implements a future version of SCEP. - -Example: - -GET /cgi-bin/pkiclient.exe?operation=GetCACaps&message=myca - -returns: - -GetNextCACert -POSTPKIOperation - -This means that the CA supports the GetNextCACert message and allows -PKIOperation messages (PKCSreq, GetCert, GetCertInitial...) to be sent -using HTTP POST. - - - Liu/Madson/McGrew/Nourse [Page 41] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Appendix G. Certificate Renewal and CA Key Rollover - -To renew a client certificate, use the PKCSreq message and sign it with -the existing client certificate instead of a self-signed certificate. - -To obtain the new CA certificate prior to the expiration of the current -one, use the GetNextCACert message if the CA supports it. - -To obtain a new client certificate signed by the new CA certificate, -use the new CA or RA certificate in the message envelope. - - -Example: - -GetNextCACert ----------> - <---------- CertRep (3) New CA certificate - -PKCSReq* (1) ----------> CA Signs certificate with NEW key -Client Stores Cert <---------- CertRep (3) Certificate issued -for installation when from NEW CA certificate and keypair. -existing cert expires. - - -*enveloped for new CA or RA cert and keypair. The CA will use the -envelope to determine which key and certificate to use to issue the -client certificate. - - - Liu/Madson/McGrew/Nourse [Page 42] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Appendix H. PKIOperation via HTTP POST Message - -If the remote CA supports it, any of the PKCS#7-encoded SCEP messages -may be sent via HTTP POST instead of HTTP GET. This is allowed for -any SCEP message except GetCACert, GetCACertChain, GetNextCACert, -or GetCACaps. In this form of the message, Base 64 encoding is not -used. - -POST /cgi-bin/pkiclient.exe?operation=PKIOperation - - -The client can verify that the CA supports SCEP messages via POST by -looking for the "POSTPKIOperation" capability (See Appendix F). - - - - - - - Liu/Madson/McGrew/Nourse [Page 43] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Appendix Y. Author Contact Information - -Xiaoyi Liu Cheryl Madson -Cisco Cisco -510 McCarthy Drive 510 McCarthy Drive -Milpitas, CA Milpitas, CA. -xliu@cisco.com cmadson@cisco.com - - -David McGrew Andrew Nourse -Cisco Cisco -170 West Tasman Drive 510 McCarthy Drive -San Jose, CA 94134 Milpitas, CA. -mcgrew@cisco.com nourse@cisco.com - - - - -Appendix Z. Copyright Section - -Copyright (C) The Internet Society (2005). This document is subject -to the rights, licenses and restrictions contained in BCP 78, and -except as set forth therein, the authors retain all their rights. - -This document and the information contained herein are provided on an -"AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS -OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET -ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE -INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED -WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - -This draft expires 11 Aug 2005 - -[End of draft-nourse-scep-11.txt] - - -INTERNET DRAFT Xiaoyi Liu -draft-nourse-scep-11.txt Cheryl Madson -expires 11 Aug 2005 David McGrew -(revised 11 Feb 2005) Andrew Nourse - Cisco Systems - -Category: Informational 11 Feb 2005 - - -Cisco Systems' Simple Certificate Enrollment Protocol(SCEP): - -Status of this Memo - -This document is an Internet-Draft and is NOT offered in accordance -with Section 10 of RFC2026, and the author does not provide the IETF -with any rights other than to publish as an Internet-Draft - -Internet-Drafts are working documents of the Internet Engineering Task -Force (IETF), its areas, and its working groups. Note that other -groups may also distribute working documents as Internet-Drafts. - -Internet-Drafts are draft documents valid for a maximum of six months -and may be updated, replaced, or obsoleted by other documents at any -time. It is inappropriate to use Internet- Drafts as reference -material or to cite them other than as "work in progress." - -The list of current Internet-Drafts can be accessed at -http://www.ietf.org/ietf/1id-abstracts.txt - -The list of Internet-Draft Shadow Directories can be accessed at -http://www.ietf.org/shadow.html. - -This memo provides information for the Internet community. This memo -does not specify an Internet standard of any kind. Distribution of -this memo is unlimited. - -By submitting this Internet-Draft, I certify that any applicable patent -or other IPR claims of which I am aware have been disclosed, or will be -disclosed, and any of which I become aware will be disclosed, in accordance -with RFC 3668. - -Abstract - -This document specifies the Simple Certificate Enrollment Protocol, -a PKI communication protocol which leverages existing technology by -using PKCS#7 and PKCS#10. SCEP is the evolution of the enrollment -protocol developed by Verisign, Inc. for Cisco Systems, Inc. -It now enjoys wide support in both client and CA implementations. - - -Table of Contents - - 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 2 - 2. The Goal of SCEP . . . . . . . . . . . . . . . . . . . . . 3 - 2.1 SCEP Entity types . . . . . . . . . . . . . . . . . . . . 3 - 2.2 SCEP Operations Overview . . . . . . . . . . . . . . . . . 7 - 2.3 PKI Operation Transactional Behavior . . . . . . . . . . . 10 - 2.4 Security . . . . . . . . . . . . . . . . . . . . . . . . . 12 - 3. Transport Protocol . . . . . . . . . . . . . . . . . . . . 13 - 4. Secure Transportation: PKCS #7 . . . . . . . . . . . . . . 14 - 4.1 SCEP Message Format . . . . . . . . . . . . . . . . . . . 14 - - Liu/Madson/McGrew/Nourse [Page 2] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - 4.2 Signed Transaction Attributes . . . . . . . . . . . . . . 15 - 5. SCEP Transaction Specification . . . . . . . . . . . . . . 16 - 5.1 Certificate Enrollment . . . . . . . . . . . . . . . . . . 16 - 5.2 Poll for Requester Initial Certificate . . . . . . . . . . 22 - 5.3 Certificate Access . . . . . . . . . . . . . . . . . . . . 26 - 5.4 CRL Access . . . . . . . . . . . . . . . . . . . . . . . 27 - 5.5 Get Certificate Authority Certificate . . . . . . . . . . 31 - 5.6 Get Certificate Authority Certificate Chain . . . . . . . 33 - 6. Security Considerations . . . . . . . . . . . . . . . . . 33 - 7. Intellectual Propoerty . . . . . . . . . . . . . . . . . . 33 - 8. References . . . . . . . . . . . . . . . . . . . . . . . . 33 - Appendix A. Cisco Requester Subject Name Definition . . . . . . 34 - Appendix B. IPSEC Client Enrollment Certificate Request . . . . 35 - Appendix C. Private OID Definitions . . . . . . . . . . . . . 36 - Appendix D. Obtaining CRL by LDAP Query . . . . . . . . . . . . 36 - Appendix E. SCEP State Transitions . . . . . . . . . . . . . . 37 - Appendix F. CA Capabilities . . . . . . . . . . . . . . . . . . 40 - Appendix G. Certificate Renewal and CA Key Rollover . . . . . . 41 - Appendix H. PKIOperation via HTTP POST Message. . . . . . . . . 42 - Appendix Y. Author Contact Information. . . . . . . . . . . . . 43 - Appendix Z. Copyright Section . . . . . . . . . . . . . . . . . 43 - -Section 1. Introduction - -Public key technology is becoming more widely deployed and is becoming -the basis for standards based security, such as the Internet Engineering -Task Force's IPSEC and IKE protocols. With the use of public key -certificates in network security protocols comes the need for a -certificate management protocol that Public Key Infrastructure (PKI) -clients and Certificate Authority servers can use to support certificate -life cycle operations such as certificate enrollment and revocation, and -certificate and CRL access. - -In the following, Section 2 gives an overview of the PKI operations, -and Section 2.4 describes the security goals of the protocol and the -mechanisms used to achieve them. The transport protocol and the -security protocol PKCS#7 are described at Section 3 and Section 4, -respectively. The last section, Section 5, specifies each PKI -operation in terms of the message formats and the data structures of -each operation. - -The appendices provide detailed specifications and examples. Requester -subject names are specified in Appendix A, attribute OIDs are -specified in Appendix C , and the SCEP state transitions are described -in Appendix E. An example of a certificate enrollment request is -provided in Appendix B, and an example LDAP query URL encoding is -provided in Appendix D. - -The authors would like to thank Peter William of ValiCert, Inc. -(formerly of Verisign, Inc) and Alex Deacon of Verisign, Inc. and -Christopher Welles of IRE, Inc. for their contributions to this protocol -and to this document. - - Liu/Madson/McGrew/Nourse [Page 3] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -2.0 The Goal of SCEP -The goal of SCEP is to support the secure issuance of certificates to -network devices in a scalable manner, using existing technology whenever -possible. The protocol supports the following operations: - - CA and RA public key distribution - Certificate enrollment - Certificate revocation - Certificate query - CRL query - -Certificate and CRL access can be achieved by using the LDAP protocol -(as specified in Appendix D), or by using the query messages defined in -SCEP. The use of HTTP certificate and CRL access, and the support of -CDP as specified in RFC2459, will be specified in a future version of -this document. In Section 2.1, we first define PKI entity types as well -as the properties of each entity type. In Section 2.2, the PKI -operations are described at functional level. Section 2.3 describes the -transaction behavior of each PKI operations. The complete PKI messages -are covered in Section 5. - -2.1 SCEP Entity types - -The entity types defined in SCEP are the "requester" type (i.e., IPSEC -clients), the Certificate Authority (CA) entity type, and the -Registration Authority entity type (RA). A requester is sometimes -called a "SCEP client" in the following. - -2.1.1 Requesters - -A requester is an entity whose name is defined in a certificate -subject name field and optionally, in SubjectAltName, a X.509 -certificate V3 extension. As a requester, a SCEP client is identified -by a subject name consisting of the following naming attributes: - - Fully qualified domain name, for example, router.cisco.com - IP address, Serial number, and/or x.500 distinguished name - -The fully qualified domain name is required for a requester that intends -to use the certificate for ISAKMP. The IP address, serial number, and -x.500 distinguished name are optional name attributes. In the -certificate enrollment request, the PKCS#10 subject field contains the -required and optional name attributes. The distinguished name, if any, -should be the subject name field, while any domain name, serial number, -or IP address supplied should be in the subjectAltName field. The -subject name field may be empty (if there is no distinguished name) -or the subjectAltName may be omitted, but not both. - -It is important to note that a client named as Alice.cisco.com is -different than a client named as Alice.cisco.com plus the IP address -name attribute 117.96.1.219. From CA point of view, the Distinguished -names assigned in these two cases are distinct names. - - - Liu/Madson/McGrew/Nourse [Page 4] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Entity names which are specified as in the IPSEC profile (i.e., FQDN, IP -address and User FQDN) must be presented in certificate's SubjectAltName -extension. Multiple IPSEC entity names, (if any) are encoded as multiple -values of a single SubjectAltName extension. The CA has the authority -to assign a distinguished name to a requester, whether or not one was -included in the request. The assigned DN should contain the SCEP client -names as the relative DN. - -The attribute identifiers and an example of SCEP client subject name are -specified in Appendix A. Appendix B has an example from Cisco VPN Client -enrollment request. - -2.1.1.1 Local Key/Certificate/CRL Storage and Certificate-name uniqueness - -A requester is required to generate asymmetric key pairs and to provide -storage to store its private keys. If the requester does not have enough -permanent memory to save its certificate, then it should be able to query -its own certificate from the CA or an LDAP server, once the certificate -has been issued. The public key pairs can be generated with a specific -key usage. The key usage is conveyed to the CA through the certificate -enrollment request. All current SCEP client implementations expect that -there will be only one pair of keys for a given subject name -and key usage combination and CA, at any time. This property is called -the certificate-name uniqueness property, and it implies that a CA that -implements SCEP will enforce the unique mapping between a SCEP client -subject name and its key pairs with a given key usage. At any time, if -the subject name is changed, or if the key is updated, the existing -certificate would have to be revoked before a new one could be issued. - -It is desirable that the CA enforce certificate-name uniqueness, but -it is not mandatory. However a CA that does not enforce uniqueness -must provide some other mechanism to prevent the re-transmission of an -enrollment request by a SCEP client from creating a second certificate -or certificate request, nor can the second request merely be rejected. -If a client times out from polling for a pending request it can -resynchronize by reissuing the original request with the original -subject name, key, and transaction ID. This should return the status of -the original transaction, including the certificate if it was granted. -It should not create a new transaction unless the original cert has been -revoked, or the transaction arrives more than halfway through the -validity time of the original certificate. - -An enrollment request that occurs more than halfway through the validity -time of an existing certificate for the same subject name and key usage -MAY be interpreted as a re-enrollment or renewal request and accepted. -A new certificate with new validity dates may be issued, even though -the old one is still valid, if the CA policy permits, as described in -2.1.1.3. See also appendix G. - -2.1.1.2 Requester authentication - -As with every protocol that uses public-key cryptography, the -association between the public keys used in the protocol and the -identities with which they are associated must be authenticated in a - Liu/Madson/McGrew/Nourse [Page 5] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -cryptographically secure manner. This requirement is needed to -prevent a "man in the middle" attack, in which an adversary that can -manipulate the data as it travels between the protocol participants -can subvert the security of the protocol. To satisfy this -requirement, SCEP provides two authentication methods: manual -authentication, and authentication based on pre-shared secret. In the -manual mode, the requester is required to wait until its identity can -be verified by the CA operator using any reliable out-of-band -method. To prevent a "man-in-the-middle" attack, a SHA-1 or MD5 -`fingerprint' generated on the PKCS#10 (before PKCS #7 enveloping and -signing) must be compared out-of-band between the server and the -requester. SCEP clients and CAs (or RAs, if appropriate) must display -this fingerprint to the operator to enable this verification if manual -mode is used. Failing to provide this information leaves the protocol -vulnerable to attack by sophisticated adversaries. When utilizing a -pre-shared secret scheme, the server should distribute a shared secret -to the requester which can uniquely associate the enrollment request -with the given end entity. The distribution of the secret must be -private: only the end entity should know this secret. The actual -binding mechanism between the requester and the secret is subject to -the server policy and implementation. When creating the enrollment -request, the requester is asked to provide a challenge password. When -using the pre-shared secret scheme, the requester must enter the -re-distributed secret as the password. In the manual authentication -case, the challenge password only used to authenticate a request for -the certificate's revokation. This challenge password is included as -a PKCS#10 attribute, and is sent to the server as encrypted data. The -PKCS#7 envelope protects the privacy of the challenge password with -DES encryption. - -2.1.1.3 Requester Uses Existing CA-Issued or Self-Signed Certificates - -In this protocol, the communication between the requester and the -certificate authority is secured by using PKCS#7 as the messaging -protocol. PKCS#7, however, is a protocol which assumes the -communicating entities already possess the peer's certificates and -requires both parties use the issuer names and issuer assigned -certificate serial numbers to identify the certificate in order to -verify the signature and decrypt the message. If the requesting -system already has a certificate issued by the CA, that certificate -may be presented as credentials for the renewal of that certificate if -the CA supports the "Renewal" capability and the CA policy permits the -certificate to be renewed. If the requester has no certificate issued -by the CA, or if the CA does not support and permit renewal, the -requestor must generate a self-signed certificate with the requester -subject name (the same name later used in the PKCS#10) as both issuer -and subject name. During the certificate enrollment, the requester -will first post itself as the signing authority by attaching the -self-signed certificate to the signed certificate request. When the -Certificate Authority makes the envelope on the issued certificate -using the public key included in the self-signed certificate, it -should use the same issuer name and serial number as conveyed in the -self-signed certificate to inform the end entity on which private key -should be used to open the envelope. - Liu/Madson/McGrew/Nourse [Page 6] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Note that when a client enrolls for separate encryption and signature -certificates, it may use the signature certificate to sign both -requests, and then expect its signature key to be used to encrypt -both responses. In any case, the recipientinfo on the envelope should -reflect the key used to encrypt the request. - -2.1.1.4 Trusted CA Store - -To support interoperability between IPSEC peers whose certificates are -issued by different CA, SCEP allows the users to configure multiple -trusted certificates. Trusted certificates are have been configured as -such in the client, based on some out-of-band means such as a "fingerprint". -These trusted certificates are used to verify certificate chains that end -in those certificates. - -2.1.2 Certificate Authority - -A Certificate Authority(CA) is an entity whose name is defined in the -certificate issuer name field. Before any PKI operations can begin, -the CA generates its own public key pair and creates a self-signed CA -certificate, or causes another CA to issue a certificate to it. -Associated with the CA certificate is a fingerprint which will be used -by the requester to authenticate the received CA certificate if it is -self-signed. The fingerprint is created by calculating a SHA-1 or MD5 -hash on the whole CA certificate. Before any requester can start its -enrollment, this CA certificate has to be configured at the entity -side securely. For IPSEC clients, the client certificates must have -SubjectAltName extension. To utilize LDAP as a CRL query protocol, -the certificates must have a CRL Distribution Point. Key usage is -optional. Without key usage, the public key is assumed as a general -purpose public key and it can be used for all the purposes. - -A Certificate Authority may enforce certain name policy. When using -X.500 directory name as the subject name, all the name attributes -specified in the PKCS#10 request should be included as Relative DN. All -the name attributes as defined in RFC2459 should be specified in the -SubjectAltName. An example is provided in Appendix A. - - If there is no LDAP query protocol support, the Certificate Authority -should answer certificate and CRL queries, and to this end it should be -online all the time. - -The updating of the CA's public key is addressed in Appendix G. - -2.1.3 Registration Authorities - -In an environment where an RA is present, a requester performs -enrollment through the RA. In order to setup a secure channel with an RA -using PKCS#7, the RA certificate(s) have to be obtained by the client -in addition to the CA certificate(s). - -In the following, the CA and RA are specified as one entity in the -context of PKI operation definitions. - Liu/Madson/McGrew/Nourse [Page 7] -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 -2.2 SCEP Operations Overview - -In this section, we give a high level overview of the PKI operations as -defined in SCEP. - -2.2.1 Requester Initialization - -The requester initialization includes the key pair generation and the -configuring of the required information to communicate with the -certificate authority. - -2.2.1.1 Key Pairs - -Before a requester can start PKI transaction, it must have at least one -asymmetric key pair, using the selected algorithm (the RSA algorithm is -required in SCEP, and is the only algorithm in current implementations). - -Key pairs may be intended for particular purposes, such as encryption only, -or signing only. The usage of any associated certificate can be restricted -by adding key usage and extended key usage attributes to the PKCS#10. - -2.2.1.2 Required Information - -A requester is required to have the following information configured -before starting any PKI operations: - -1. the certificate authority IP address or fully-qualified domain name, -2. the certificate authority HTTP CGI script path, and - the HTTP proxy information in case there is no direct Internet - connection to the server, -3. If CRLs are being published by the CA to an LDAP directory server, - and there is a CRL Distribution Point containing only an X.500 directory - name, then the client will need to know the LDAP server fully-qualified - domain name or IP address. CRL Distribution Points are discussed in - more detail in RFC 2459. - - -2.2.2 CA/RA Certificate Distribution - -Before any PKI operation can be started, the requester needs to get -the CA/RA certificates. At this time, since no public key has been - - Liu/Madson/McGrew/Nourse [Page 8] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -exchanged between the requester and the CA/RA, the message to get the -CA/RA certificate can not be secured using PKCS#7 protocol. Instead, the -CA/RA certificate distribution is implemented as a clear HTTP Get -operation. After the requester gets the CA certificate, it has to -authenticate the CA certificate by comparing the finger print with the -CA/RA operator. Since the RA certificates are signed by the CA, there is -no need to authenticate the RA certificates. - -This operation is defined as a transaction consisting of one HTTP Get -message and one HTTP Response message: - - REQUESTER CA SERVER - Get CA/RA Cert: HTTP Get message - -----------------------------> - CA/RA Cert download: HTTP Response message - <--------------------------------------- - Compute finger print and - call CA operator. - Receive call and check finger print - -If an RA is in use, a degenerated PKCS#7 with a certificate chain -consisting of both RA and CA certificates is sent back to the end -entity. Otherwise the CA certificate is directly sent back as the -HTTP response payload. - - -2.2.3 Certificate Enrollment - -A requester starts an enrollment transaction by creating a certificate -request using PKCS#10 and sends it to the CA/RA enveloped using the -PKCS#7. After the CA/RA receives the request, it will either -automatically approve the request and send the certificate back, or it -will require the requester to wait until the operator can manually -authenticate the identity of the requester. Two attributes are -included in the PKCS#10 certificate request - a Challenge Password -attribute and an optional ExtensionReq attribute which will be a -sequence of extensions the requester would like to be included in its -V3 certificate extensions. The Challenge Password may be used to -authenticate either the enrollment request itself, or a verbal -revocation request for the issued certificate in the event of key -compromise or other reason. - -In the automatic mode, the transaction consists of one PKCSReq PKI -Message, and one CertRep PKI message. In the manual mode, the requester -enters into polling mode by periodically sending a GetCertInitial PKI -message to the server, until the server operator completes the manual -authentication, after which the CA will respond to GetCertInitial by -returning the issued certificate. A CA MAY run in automatic mode for -preapproved requests, and manual mode for the rest. A request with a -non-null password is not necessarily a pre-approved request. It is up -to the CA server to decide. Polling mode is entered whenever the -server returns a PENDING response. - - Liu/Madson/McGrew/Nourse [Page 9] -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -The transaction in automatic mode: - - REQUESTER CA SERVER - -PKCSReq: PKI cert. enrollment msg - --------------------------------> CertRep: pkiStatus = SUCCESS - certificate attached - <------------------------------ - Receive issued certificate. - -The transaction in manual mode: - - REQUESTER CA SERVER - PKCSReq: PKI cert. enrollment msg - --------------------------------> CertRep: pkiStatus = PENDING - <------------------------------ - GetCertInitial: polling msg - --------------------------------> CertRep: pkiStatus = PENDING - <------------------------------ - ................. CertRep: pkiStatus = SUCCESS - certificate attached - <------------------------------ - Receive issued certificate. - -2.2.4 Requester Certificate Revocation - -A requester should be able to revoke its own certificate. Currently -the revocation is implemented as a manual process. In order to revoke a -certificate, the requester makes a phone call to the CA server -operator. The operator will come back asking the ChallengePassword -(which has been sent to the server as an attribute of the PKCS#10 -certificate request). If the ChallengePassword matches, the certificate -is revoked. The reason of the revocation is documented by CA/RA. - -2.2.5 Certificate Access - -There are two methods to query certificates. The first method is to use -LDAP as a query protocol. Using LDAP to query assumes the client -understand the LDAP scheme supported by the CA. The SCEP client assumes -that the subject DN name in the certificate is used as the URL to query the -certificate. The standard attributes (userCertificate and caCertificate) -are used as filter. - -For the environment where LDAP is not available, a certificate query -message is defined to retrieve the certificates from the CA. - -To query a certificate from the certificate authority, a requester -sends a request consisting of the certificate's issuer name and the -serial number. This assumes that the requester has saved the issuer - - Liu/Madson/McGrew/Nourse [Page 10] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -name and the serial number of the issued certificate from the previous -enrollment transaction. The transaction to query a certificate consists -of one GetCert PKI message and one CertRep PKI message: - - REQUESTER CA SERVER - GetCert: PKI cert query msg - -------------------------------> CertRep: pkiStatus = SUCCESS - certificate -attached - <----------------------------- - Receive the certificate. - -2.2.6 CRL Distribution - -The CA/RA will not "push" the CRL to the end entities. The query of the -CRL can only be initialized by the requester. - -There are three methods to query CRL. - -The CRL may be retrieved by a simple HTTP GET. If the CA supports this -method, it should encode the URL into a CRL Distribution Point extension -in the certificates it issues. Support for this method should be -incorporated in new and updated clients, but may not be in older -versions. - -The second method is to query CRL using LDAP. This assumes the CA server -supports CRL LDAP publishing and issues the CRL Distribution Point in -the certificate. The CRL Distribution Point is encoded as a DN. Please -refer to Appendix D for the examples of CRL Distribution Point. - -The third method is implemented for the CA which does not support LDAP -CRL publishing or does not implement the CRL Distribution Point. In this -case, a CRL query is composed by creating a message consists of the CA -issuer name and the CA's certificate serial number. This method is -deprecated because it does not scale well and requires the CA to be a -high-availability service. - -The message is sent to the CA in the same way as the other SCEP -requests: The transaction to query CRL consists of one GetCRL PKI -message and one CertRep PKI message which have no certificates but CRL. - - REQUESTER CA SERVER - GetCRL: PKI CRL query msg - ----------------------------------> CertRep: CRL attached - <-------------------------------- - -2.3 PKI Operation Transactional Behavior - -As described before, a PKI operation is a transaction consisting of the -messages exchanged between a requester and the CA/RA. This section -will specify the transaction behavior on both the requester and the - - - Liu/Madson/McGrew/Nourse [Page 11] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -certificate authority server. Because the protocol is basically a two -way communication protocol without a confirmation message from the -initiating side, state and state resynchronization rules have to be -defined, in case any error happens at either side. Before the state -transition can be defined, the notion of transaction identifier has to -be defined first. - -2.3.1 Transaction Identifier - -A transaction identifier is a string generated by the entity when -starting a transaction. Since all the PKI operations defined in this -protocol are initiated by the requester, it is the responsibility of -the requester to generate a unique string as the transaction -identifier. All the PKI messages exchanged for a given PKI transaction -must carry the same transaction identifier. The transaction identifier -is generated as a SHA-1 or MD5 hash on the public key value for which the -enrollment request is made. This allows the SCEP client to reuse the -same transaction identifier if it is reissuing a request for the same -certificate (i.e. a certificate with the same subject, issuer, and key). -The SCEP protocol requires that transaction identifiers be unique, so -that queries can be matched up with transactions. For this reason, in -those cases in which separate signing and encryption certificates are -issued to the same requester, the keys must be different. - -2.3.2 State Transitions in Certificate Enrollment - -The requester state transitions during enrollment operation are -indicated in the diagram below: - +-<------+ - | | - GetCertInitial triggered by timeout or - | | manual authentication - | | - [CERT-NONEXISTANT] ------> [CERT-REQ-PENDING] ---> [CERT-ISSUED] - | PKCSReq | CertRep with SUCCESS - | | - | | - +--------<-------------------+ - request rejected, timeout, or error - -As described in the section 2.2.3, certificate enrollment starts at the -state CERT-NONEXISTANT. Sending PKCSReq changes the state to -CERT-REQ-PENDING. Receiving CertRep with SUCCESS status changes the -state to CERT-ISSUED. In the case the server sending back the response -with pending status, the requester will keep polling certificate -response by sending GetCertInitial to the server, until either a CertRep -with SUCCESS status is received, or the maximum polling number has been -exceeded. - -If an error or timeout occurs in the CERT-REQ-PENDING state, the end -entity will transition to the CERT-NONEXISTANT state. - - - Liu/Madson/McGrew/Nourse [Page 12] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -The client administrator will, eventually, start up another enrollment -request. It is important to note that, as long as the requester does -not change its subject name or keys, the same transaction id will be -used in the "new" transaction. This is important because based on this -transaction id, the certificate authority server can recognize this as -an existing transaction instead of a new one. - - -2.3.3 Transaction Behavior of Certificate/CRL Access - -There is no state maintained during certificate access and CRL access -transaction. When using the certificate query and CRL query messages -defined in this protocol, the transaction identifier is still required -so that the requester can match the response message with the -upstanding request message. When using LDAP to query the certificate and -the CRL, the behavior is specified by the LDAP protocol. - -2.4 Security - -The security goals of SCEP are that no adversary can: - -o subvert the public key/identity binding from that intended, -o discover the identity information in the enrollment requests and - issued certificates, -o cause the revocation of certificates with any non-negligible - probability. - -Here an adversary is any entity other than the requester and the CA -(and optionally the RA) participating in the protocol that is -computationally limited, but that can manipulate data during -transmission (that is, a man-in-the-middle). The precise meaning of -'computationally limited' depends on the implementer's choice of -cryptographic hash functions and ciphers. The required algorithms are -RSA, DES, and either SHA-1 or MD5, depending on the "SHA-1" CA Capability. -[See Appendix F]. - -The first and second goals are met through the use of PKCS#7 and PKCS#10 -encryption and digital signatures using authenticated public keys. The -CA's public key is authenticated via the checking of the CA fingerprint, -as specified in Section 2.1.2, and the SCEP client's public key is -authenticated through the manual authentication or pre-shared secret -authentication, as specified in Section 2.1.1.2. The third goal is met -through the use of a Challenge Password for revocation, that is chosen -by the SCEP client and communicated to the CA protected by the PKCS#7 -encryption, as specified in Section 2.2.4. - -The motivation of the first security goal is straightforward. The -motivation for the second security goal is to protect the identity -information in the enrollment requests and certificates. For example, -two IPSEC hosts behind a firewall may need to exchange certificates, and -may need to enroll certificates with a CA that is outside of a firewall. -Most networks with firewalls seek to prevent IP addresses and DNS - - Liu/Madson/McGrew/Nourse [Page 13] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -information from the trusted network leaving that network. The second -goal enables the hosts in this example to enroll with a CA outside the -firewall without revealing this information. The motivation for the -third security goal is to protect the SCEP clients from denial of -service attacks. - -Section 3 Transport Protocol - -In the SCEP protocol, HTTP is used as the transport protocol for the PKI -messages. - -3.1 HTTP "GET" and "POST" Message Format - -The following is the syntax definition of a HTTP GET message sent from -a requester to a certificate authority server: - -Request = "GET " CGI-PATH CGI-PROG "?operation=" OPERATION "&message=" MESSAGE -where: - CGI-PATH defines the actual CGI path to invoke the CGI program which - parses the request. - CGI-PROG is set to be the string "pkiclient.exe". This is intended - to be the program that the CA will use to handle the SCEP transactions, - though the CA may ignore CGI-PROG and use only the CGI-PATH. - OPERATION is set to be the string "PKIOperation" when the GET message - carries a PKI message to request certificates or CRL; OPERATION is set - to be the string "GetCACaps", "GetCACert", "GetNextCACert" or - "GetCACertChain" when the GET operation is used to get CA capabilities, - CA/RA certificate, the replacement CA/RA certificates for when the - current ones expire, or the CA Cert chain (respectively). - - When OPERATION is "PKIOperation", MESSAGE is a base64-encoded PKI message, - When OPERATION is GetCACert, MESSAGE is a CRL distribution - point in URI format, otherwise, MESSAGE is a string which represents - the certificate authority issuer identifier. - -SCEP uses the HTTP "GET" and "POST" messages to request information from the CA. -Requests for CA certificates or capabilities are sent in the clear, using "GET", -with the OPERATION and MESSAGE fields identifying the requested data. -CRLs may also be requested in the clear if the CA supports it. - -Other types of requests are sent using the PKCS#7 secure protocol. -These may be issued by means of a GET operation with -OPERATION and MESSAGE parameters in the Request-URL. OPERATION -identifies the type of GET operation, and MESSAGE is actually the PKCS#7 -message Base64-Encoded. - -For example. a requester may submit a message via HTTP to the server -as follows: - -GET /cgi-bin/pkiclient.exe?operation=PKIOperation&message=MIAGCSqGSIb3D -QEHA6CAMIACAQAxgDCBzAIBADB2MGIxETAPBgNVBAcTCE ......AAAAAA== - Liu/Madson/McGrew/Nourse [Page 13a] - -If supported by the CA, the message may also be sent via HTTP POST: - -POST /cgi-bin/pkiclient.exe?operation=PKIOperation - -This is further described in Appendix H. -To determine if the CA supports POST, use the GetCACaps message described -in Appendix F. - - -3.2 Response Message Format - -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. The following is an -example of the response: - -"Content-Type:application/x-pki-message\n\n" - -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. the body of the response is a DER encoded -binary X.509 certificate. For example: - -"Content-Type:application/x-x509-ca-cert\n\n" - -If there is an RA, the RA certificates are sent back together with the -CA certificates, a certificate-only PKCS#7 SignedData is sent back in -the response where the SignerInfo is empty. Section 5 has the detailed -definition of the message format in this case. The content type is -application/x-x509-ca-ra-cert. - -The response to GetNextCACert is always a certificates-only PKCS#7 -SignedData with a content type of application/x-x509-ca-ra-cert. -If there is an RA, The signer is the current RA certificate. Otherwise, -the signer is the current CA certificate. - -If the CA supports it, PKIOperation may also be done via an HTTP POST. -This is described in Appendix H. - - Liu/Madson/McGrew/Nourse [Page 14] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Section 4 Secure Transportation: PKCS#7 - -PKCS#7 is a general enveloping mechanism that enables both signed and -encrypted transmission of arbitrary data. It is widely implemented and -included in the RSA tool kit. In this section, the general PKCS#7 -enveloped PKI message format is specified. The complete PKCS#7 message -format for each PKI transaction will be covered in Section 5. - -4.1 SCEP Message Format - -As a transaction message, a SCEP message has a set of transaction -specific attributes and an information portion. Employing PKCS#7 -protocol, the transaction specific attributes are encoded as a set of -authenticated attributes of the SignedData. The information portion will -first be encrypted to become Enveloped Data, and then the digest of the -enveloped information portion is included as one of the message digest -attributes and being signed together with the other transaction specific -attributes. - -By applying both enveloping and signing transformations, a SCEP message -is protected both for the integrity of its end-end-transition -information and the confidentiality of its information portion. The -advantage of this technique over the conventional transaction message -format is that, the signed transaction type information and the status -of the transaction can be determined prior to invoke security handling -procedures specific to the information portion being processed. - -The following is an example of a SCEP message with its enveloped and -signed data portion represented by pkcsPKISigned and -pkcsPKIEnveloped. The out-most of any PKI message is a blob of -ContentInfo, with its content type set to SignedData and the actual -signed data as the content. - - Liu/Madson/McGrew/Nourse [Page 15] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - pkiMessage ContentInfo ::= { - contentType {pkcs-7 signedData(2)} - content pkcsPKISigned - } - pkcsPKISigned SignedData ::= { - version 1 - digestAlgorithm { iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} -- data content identifier - content pkcsPKIEnvelope -- enveloped information portion - } - certificates -- signer certificate chain - signerInfo -- including signed transaction info and the digest - -- of the enveloped information portion as the - -- authenticated attributes - } - pkcsPKIEnveloped EnvelopedData ::= { - version 0 - recipientInfos -- information required to open the envelop - encryptedContentInfo { - contentType {pkcs-7 1} -- data content identifier - contentEncryptionAlgorithm - encryptedContent -- encrypted information portion - } - } - -4.2 Signed Transaction Attributes - -The following transaction attributes are encoded as authenticated -attributes. Please refer to Appendix B for the OID definitions. - -transactionID PrintableString -- Decimal value as a string - messageType PrintableString -- Decimal value as a string - pkiStatus PrintableString -- Decimal value as a string - failinfo PrintableString -- Decimal value as a string - senderNonce Octet String - recipientNonce Octet String - -where: - - The transactionID is an attribute which uniquely identify a - transaction. This attribute is required in all PKI messages. - - The messageType attribute specify the type of operation performed by the - transaction. This attribute is required in all PKI - messages. Currently, the following message types are defined: - - PKCSReq (19) -- Permits use of PKCS#10 certificate request - CertRep (3) -- Response to certificate or CRL request - GetCertInitial (20) -- Certificate polling in manual enrollment - GetCert (21) -- Retrieve a certificate - GetCRL (22) -- Retrieve a CRL - - Liu/Madson/McGrew/Nourse [Page 16] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - - All response message will include transaction status information which - is defined as pkiStatus attribute: - - SUCCESS (0) -- request granted - FAILURE (2) -- request rejected - PENDING (3) -- request pending for manual approval. - - If the status in the response is FAILURE, the failinfo attribute will - contain one of the following failure reasons: - - badAlg (0) -- Unrecognized or unsupported algorithm ident - badMessageCheck (1) -- integrity check failed - badRequest (2) -- transaction not permitted or supported - badTime (3) -- Message time field was not sufficiently close - to the system time - badCertId (4) -- No certificate could be identified matching - the provided criteria - - The attributes of senderNonce and recipientNonce are the 16 byte - random numbers generated for each transaction to prevent the replay - attack. - -When a requester sends a PKI message to the server, a senderNonce is -included in the message. After the server processes the request, it will -send back the requester senderNonce as the recipientNonce and generates -another nonce as the senderNonce in the response message. Because the -proposed pki protocol is a two-way communication protocol, it is clear -that the nonce can only be used by the requester to prevent the -replay. The server has to employ extra state related information to -prevent a replay attack. - -Section 5. SCEP Transaction Specification - -In this section each SCEP transaction is specified in terms of the -complete messages exchanged during the transaction. - -5.1 Certificate Enrollment - -The certificate enrollment transaction consists of one PKCSReq message -sent to the certificate authority from a requester, and one CertRep -message sent back from the server. The pkiStatus returned in the -response message is either SUCCESS, or FAILURE, or PENDING. The -information portion of a PKCSReq message is a PKCS#10 certificate -request, which contains the subject Distinguished Name, the subject -public key, and two attributes, a ChallengePassword attribute to be used -for revocation, and an optional ExtensionReq attribute which will be a -sequence of extensions the requester expects to be included in its V3 -certificate extensions. One of the extension attribute specifies the key -usage. If the request is granted, the pkiStatus is set to SUCCESS, and -the certificate is returned in CertRep; if the request is rejected, the - - - Liu/Madson/McGrew/Nourse [Page 17] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -pkiStatus is set to FAILURE; if the server requires manual approval of -the request, the pkiStatus is set to PENDING. The messages exchanged -in the manual authentication mode is further specified in Section 5.2. - -Precondition: - Both the requester and the certificate authority have completed their - initialization process. The requester has already been configured - with the CA/RA certificate. - -Postcondition: - Either the certificate is received by the requester, or the end - entity is notified to do the manual authentication, or the request - is rejected. - -5.1.1 PKCSReq Message Format - -A PKCSReq message is created by following the steps defined below: - -1. Create a PKCS#10 certificate request which is signed by the end - entity's private key, corresponding to the public key included in - the PKCS#10 certificate request. This constitutes the information - portion of PKCSReq. - -2. Encrypt the PKCS#10 certificate request using a randomly generated - content-encryption key. This content-encryption key is then - encrypted by the CA's* public key and included in the recipientInfo. - This step completes the "envelope" for the PKCS#10 certificate - request. - -3. Generate a unique string as the transaction id. - -4. Generate a 16 byte random number as senderNonce. - -5. Generate message digest on the enveloped PKCS#10 certificate request - using the selected digest algorithm. - -6. Create SignedData by adding the requester's self- or CA-certificate - as the signer's public key certificate. Include the message type, - transaction id, the senderNonce and the message digest as the - authenticated attributes and sign the attributes using the end - entity's private key. This completes the SignedData. - -7. The SignedData is prepended with the ContenInfo blob which indicates - a SignedData object. This final step completes the create of a - complete PKCSReq PKI message. - -In the following, the PKCSReq message is defined following the ASN.1 -notation. - -For readability, the values of a field is either represented by a quoted -string which specifies the intended value, or a constant when the value -is known. - - - Liu/Madson/McGrew/Nourse [Page 18] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -- PKCSReq information portion - pkcsCertReq CertificationRequest ::= { -- PKCS#10 - version 0 - subject "the requester's subject name" - subjectPublicKeyInfo { - algorithm {pkcs-1 1} -- rsa encryption - subjectPublicKey "DER encoding of the requester's public key" - } - attributes { - challengePassword {{pkcs-9 7} "password string" } - extensions - } - signatureAlgorithm {pkcs-1 4} -- MD5WithRSAEncryption - signature "bit string which is created by signing inner content - of the defined pkcsCertReq using requester's private - key, corresponding to the public key included in - subjectPublicKeyInfo." - } - -- Enveloped information portion - pkcsCertReqEnvelope EnvelopeData ::= { -- PKCS#7 - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the CA issuer name" - serialNumber "the CA certificate serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} -- rsa encryption - encryptedKey "content-encryption key - encrypted by CA public key" - } - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "object identifier - for DES encryption" - encryptedContent "encrypted pkcsCertReq using the content- - encryption key" - } - } - -- Signed PKCSReq - pkcsCertReqSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} -- data content identifier - content pkcsCertReqEnvelope - } - certificate { -- requester self-signed or CA-issued certificate - version 3 - serialNumber "the transaction id associated with enrollment" - signature {pkcs-1 4} -- md5WithRSAEncryption - - - Liu/Madson/McGrew/Nourse [Page 19] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - issuer " the requester's subject name" - validity { - notBefore "a UTC time" - notAfter "a UTC time" - } - subject "the requester's subject name" - subjectPublicKeyInfo { - algorithm {pkcs-1 1} - subjectPublicKey "DER encoding of requester's public key" - } - signatureAlgorithm {pkcs-1 4} - signature "the signature generated by using the requester's - private key corresponding to the public key in - this certificate." - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the requester's subject name" - serialNumber "the transaction id associated - with the enrollment" - } - digestAlgorithm {iso(0) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "an octet string"} - transaction-id {{id-attributes transId(7)} "printable - string"} - -- this transaction id will be used - -- together with the subject name as - -- the identifier of the requester's key - -- pair during enrollment - messageType {{id-attributes messageType(2)} "PKCSReq"} - senderNonce {{id-attributes senderNonce(5)} - "a random number encoded as a string"} - } - digestEncryptionAlgorithm {pkcs-1 1} -- rsa encryption - encryptedDigest "encrypted digest of the authenticated - attributes using requester's private key" - } - } - pkcsReq PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsCertRepSigned - } - - - - - - - - - Liu/Madson/McGrew/Nourse [Page 20] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -5.1.2 CertRep Message Format - -The response to an SCEP enrollment request is a CertRep message. - -5.1.2.1 PENDING Response - -When the CA is configured to manually authenticate the requester, -the CertRep is returned with the attribute pkiStatus set to PENDING. -The data portion for this message is null. Only the transaction -required attributes are sent back. - -CertRepSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo {contentType {pkcs-7 1} -- empty content - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "name of CA that issued the CA [RA] cert" - serialNumber "the serial number of the CA [RA] cert" - } - digestAlgorithm (iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} NULL} - messageType {{id-attribute messageType(0)} "CertRep"} - transaction-id {{id-attributes transid(7)} "printablestring"} - --- same transaction id used in PKCSReq - pkiStatus {{id-attributes pkiStatus(3)} "PENDING"} - recipientNonce {{id-attributes recipientNonce(6)}<16 bytes>} - senderNonce {{id-attributes senderNonce(5)} <16 bytes>} - } - digestEncrytionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted message digest of the authenticated - attributes using the CA's [RA's] private key" - } -} -CertRep PKIMessage ::= { - contentType {pkcs-7 2} - content CertRepSigned -} - -5.1.2.2 Failure Response - -In this case, the CertRep sent back to the requester is same as in -the PENDING case, except that the pkiStatus attribute is set to FAILURE, -and the failInfo attribute should be included: - - pkistatus {{id-attributes pkiStatus(3)} "FAILURE"} - failInfo {{id-attributes failInfo(4)} "the reason to reject"} - - Liu/Madson/McGrew/Nourse [Page 21] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -5.1.2.3 SUCCESS response - -In this case, the information portion of CertRep will be a degenerated -PKCS#7 which contains the requester's certificate. It is then enveloped -and signed as below: - -pkcsCertRep SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { -- empty content since this is degenerated PKCS#7 - contentType {pkcs-7 1} - } - certificates { - certificate { -- issued requester's certificate // must be first - version 3 - serialNumber "issued requester's certificate serial number" - signature {pkcs-1 4} -- md5WithRSAEncryption - issuer "the certificate authority issuer name" - validity { - notBefore "UTC time" - notAfter "UTC time" - } - subject "the requester subject name as given in PKCS#10" - subjectPublicKeyInfo { - algorithm {pkcs-1 1} - subjectPublicKey "a DER encoding of requester public - key as given in PKCS#10" - } - extensions " the extensions as given in PKCS#10" - signatureAlgorithm {pkcs-1 4} - signature " the certificate authority signature" - } - certificate "the certificate authority certificate" (optional) - certificate "the registration authority certificate(s)" (optional) - } -} -pkcsCertRepEnvelope EnvelopedData ::= { -- PKCS#7 - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { -- use issuer name and serial number as - -- conveyed in requester's self-signed - -- certificate, included in the PKCSReq - issuer "the requester's subject name" - serialNumber "the serial number defined by the requester in - its self-signed certificate" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted by the requester's - public key which is same key as authenticated in - the requester's certificate" - } - - - Liu/Madson/McGrew/Nourse [Page 22] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - encryptedContentInfo { - contentType {pkcs-7 1} -- data content identifier - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted pkcsCertRep using content encryption - key" - } -} -pkcsCertRepSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - content pkcsCertRepEnvelope - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the certificate authority issuer name" - serialNumber "the CA certificate's serial number" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "a octet string"} - messageType {{id-attribute messageType(2)} "CertRep"} - transaction-id {{id-attributes transId(7)} "printable - string"} - -- same transaction id as given in PKCSReq - pkiStatus {{id-attributes pkiStatus(3) "SUCCESS"} - recipientNonce {{id-attribute recipientNonce(6)}<16 bytes>} - senderNonce {{ id-attributes senderNonce(5) <16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticate attributes - using CA's private key " - } -} -CertRep PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsCertRepSigned -} - -5.2 Poll for Requester Initial Certificate - -Either triggered by the PENDING status received from the CertRep, or by -the non-response timeout for the previous PKCSReq, a requester will -enter the polling state by periodically sending GetCertInitial to the -server, until either the request is granted and the certificate is sent -back, or the request is rejected, or the configured time limit for -polling is exceeded. - - - Liu/Madson/McGrew/Nourse [Page 23] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -Since GetCertInitial is part of the enrollment, the messages exchanged -during the polling period should carry the same transaction identifier -as the previous PKCSReq. - -PreCondition - Either the requester has received a CertRep with pkiStatus set to be - PENDING, or the previous PKCSReq has timed out. - -PostContition - The requester has either received the certificate, or be rejected of - its request, or the polling period ended as a failure. - -5.2.1 GetCertInitial Message Format - -Since at this time the certificate has not been issued, the requester -can only use the requester's subject name, combined with the -transaction identifier, to identify the polled certificate request. - -The certificate authority server must be able to uniquely identify the -polled certificate request. A subject name can have more than one -outstanding certificate request (with different key usage attributes). - --- Information portion - -pkcsGetCertInitial issuerAndSubject ::= { - issuer "the certificate authority issuer name" - subject "the requester subject name as given in PKCS#10" -} -pkcsGetCertInitialEnvelope EnvelopedData ::= { - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the CA issuer name" - serialNumber "the CA certificate serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted by CA's public key" - } - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted getCertInital" - } -} -pkcsGetCertInitialSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - - - Liu/Madson/McGrew/Nourse [Page 24] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - content pkcsGetCertIntialEnvelope - } - certificate { -- the requester's self-signed certificate - version 3 - serialNumber "the transaction id associated with enrollment" - signature {pkcs-1 4} -- md5WithRSAEncryption - issuer " the requester's subject name" - validity { - notBefore "a UTC time" - notAfter "a UTC time" - } - subject "the requester's subject name" - subjectPublicKeyInfo { - algorithm {pkcs-1 1} - subjectPublicKey "DER encoding of requester's public key" - } - signatureAlgorithm {pkcs-1 4} - signature "the signature generated by using the requester's - private key corresponding to the public key in - this certificate." - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "requester's subject name" - serialNumber "the transaction id used in previous PKCSReq" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "an octet string"} - -- digest of getCertInitial - messageType {{id-attribute messageType(2)} "GetCertInitial"} - transaction-id {{id-attributes transId(7)} "printable - string"} - -- same transaction idused in previous PKCSReq - senderNonce {{id-attribute senderNonce(3)} 0x<16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticateAttributes" - } -} -GetCertInitial PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsGetCertInitialSigned -} - - - -5.2.2 GetCertInitial Response Message Format - -The response messages for GetCertInitial are the same as for PKCSReq. - - Liu/Madson/McGrew/Nourse [Page 25] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -5.3 Certificate Access - -The certificate query message defined in this section is an option when -the LDAP server is not available to provide the certificate query. A -requester should be able to query an issued certificate from the -certificate authority, as long as the issuer name and the issuer -assigned certificate serial number is known to the requesting end -entity. This transaction is not intended to provide the service as a -certificate directory service. A more complicated query mechanism would -have to be defined in order to allow a requester to query a certificate -using various different fields. - -This transaction consists of one GetCert message sent to the server by -a requester, and one CertRep message sent back from the server. - -PreCondition - The queried certificate have been issued by the certificate authority - and the issuer assigned serial number is known. - -PostCondition - Either the certificate is sent back or the request is rejected. - - -5.3.1 GetCert Message Format - -The queried certificate is identified by its issuer name and the issuer -assigned serial number. If this is a query for an arbitrary requester's -certificate, the requesting requester should includes its own CA issued -certificate in the signed envelope. If this is a query for its own -certificate (assume the requester lost the issued certificate, or does -not have enough non-volatile memory to save the certificate), then the -self-signed certificate has to be included in the signed envelope. - - pkcsGetCert issuerAndSerialNumber ::= { - issuer "the certificate issuer name" - serialNumber "the certificate serial number" - } - pkcsGetCertEnvelope EnvelopedData ::= { - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the CA [RA] issuer name" - serialNumber "the CA [RA] certificate serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted - by CA [RA] public key" - } - - - - - - Liu/Madson/McGrew/Nourse [Page 26] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted pkcsGetCert using the content - encryption key" - } - } - pkcsGetCertSigned SignedData ::= { - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - content pkcsGetCertEnvelope - } - certificates { - certificate "CA issued certificate" - or "self-signed certificate" - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the requester's subject name" - serialNumber "requester's certificate serial number" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "an octet string"} - -- digest of pkcsGetCertEnvelope - messageType {{id-attribute messageType(2)} "GetCert"} - transaction-id {{id-attributes transId(7)} "printable - string"} - senderNonce {{id-attribute senderNonce(3)} <16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticateAttributes" - } - } - GetCert PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsGetCertSigned - } - - - - - - - - - - Liu/Madson/McGrew/Nourse [Page 27] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -5.3.2 CertRep Message Format - -In this case, the CertRep from the server is same as the CertRep for the -PKCSReq, except that the server will only either grant the request or -reject the request. Also, the recipientInfo should use the CA issuer -name and CA assigned serial number to identify the requester's key pair -since at this time, the requester has received its own certificate. - -5.4 CRL Access - -The CRL query message defined in this section is an option when the LDAP -server is not available to provide the CRL query. In the PKI protocol -proposed here, only the requester can initiate the transaction to -download CRL. A requester sends GetCRL request to the server and the -server sends back CertRep whose information portion is a degenerated -PKCS#7 which contains only the most recent CRL. The size of CRL included -in the CertRep should be determined by the implementation. - -PreCondition - The certificate authority certificate has been downloaded to the end - entity. - -PostCondition - CRL sent back to the requester. - -5.4.1 GetCRL Message format - -The CRL is identified by using both CA's issuer name and the CA -certificate's serial number: - - pkcsGetCRL issuerAndSerialNumber { - issuer "the certificate authority issuer name" - serialNumber "certificate authority certificate's serial number" - } - -When the CRLDistributionPoint is supported, the pkcsGetCRL is defined as -the following: - - pkcsGetCRL SEQUENCE { - crlIssuer issuerAndSerialNumber - distributionPoint CE-CRLDistPoints - } - -where CE-CRLDisPoints is defined in X.509, but must contain only one -CRL distribution point. - - - - - - - - - - - Liu/Madson/McGrew/Nourse [Page 28] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - pkcsGetCRLEnvelope EnvelopedData ::= { - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the certificate authority (or RA) issuer name" - serialNumber "the CA (RA) certificate's serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted by CA (RA) public key" - } - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted pkcsGetCRL" - } - } - pkcsGetCRLSigned SignedData ::= { - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - content pkcsGetCRLEnvelope - } - certificates { - certificate "CA-issued or self-signed requester's certificate" - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the requester's issuer name" - serialNumber "the requester's certificate serial number" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} 0x<16/20 bytes>} - -- digest of pkcsGetCRLEnvelope - messageType {{id-attribute messageType(2)} "CertCRL"} - transaction-id {{id-attributes transId(7)} "printable - string"} - senderNonce {{id-attribute senderNonce(3)} <16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticateAttributes" - } - } - GetCRL PKIMessage ::= { - contentType {pkcs-7 2} - content pkcsGetCRLSigned - } - - Liu/Madson/McGrew/Nourse [Page 29] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -5.4.2 CertRep Message Format - -The CRL is sent back to the requester through CertRep message. The -information portion of this message is a degenerated PKCS#7 SignedData -which contains only a CRL. - - pkcsCertRep SignedData ::= { - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - } - crl { - signature {pkcs-1 4} - issuer "the certificate authority issuer name" - lastUpdate "UTC time" - nextUpdate "UTC time" - revokedCertificate { - -- the first entry - userCertificate "certificate serial number" - revocationData "UTC time" - .... - -- last entry - userCertificate "certificate serial number" - revocationData "UTC time" - } - } - pkcsCertRepEnvelope EnvelopedData ::= { - version 0 - recipientInfo { - version 0 - issuerAndSerialNumber { - issuer "the requester's issuer name" - serialNumber "the requester certificate serial number" - } - keyEncryptionAlgorithm {pkcs-1 1} - encryptedKey "content-encrypt key encrypted by requester's - public key " - } - encryptedContentInfo { - contentType {pkcs-7 1} -- data content - contentEncryptionAlgorithm "OID for DES encryption" - encryptedContent "encrypted pkcsCertRep using requester's - public key" - } - } - - - - - - - Liu/Madson/McGrew/Nourse [Page 30] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - - pkcsCertRepSigned SignedData ::= { -- PKCS#7 - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - contentInfo { - contentType {pkcs-7 1} - content pkcsCertRepEnvelope - } - signerInfo { - version 1 - issuerAndSerialNumber { - issuer "the certificate authority issuer name" - serialNumber "the CA certificate's serial number" - } - digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - authenticateAttributes { - contentType {{pkcs-9 3} {pkcs-7 1}} - messageDigest {{pkcs-9 4} "an octet string"} - -- digest of pkcsCertRepEnvelope - messageType {{id-attribute messageType(2)} "CertRep"} - transaction-id {{id-attributes transId(7)} "printable - string"} - -- same transaction id as given in PKCSReq - pkiStatus {{id-attributes pkiStatus(3) "SUCCESS"} - recipientNonce{{id-attribute recipientNonce(6)}<16 bytes>} - senderNonce {{id-attribute senderNonce (5) 0x<16 bytes>} - } - digestEncryptionAlgorithm {pkcs-1 1} - encryptedDigest "encrypted digest of authenticatedAttributes - using CA private key" - } - } - - -NOTE:The PKCS#7 EncryptedContent is specified as an octet string, but -SCEP entities must also accept a sequence of octet strings as a valid -alternate encoding. - -This alternate encoding must be accepted wherever PKCS #7 Enveloped -Data is specified in this document. - - - - - - - - - - - - Liu/Madson/McGrew/Nourse [Page 31] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -5.5 Get Certificate Authority Certificate - -Before any transaction begins, end entities have to get the CA (and -possibly RA) certificate(s) first. Since the requester may have no CA -certificates or CA public keys at all, this message can not be -encrypted and the response must be authenticated by out-of-band means. -These certs are obtained by means of an HTTP GET message. To get the -CA certificate, the requester does a "HTTP GET" with a URL that -identifies a CGI script on the server and an optional CA issuer -identifier as the parameter to the CGI script. The response is either -a single X.509 CA certificate ("CA mode"), or a PKCS7 message -containing the CA certificate and RA certificates ("RA mode"). The -client can determine which mode the CA operates in by which response -it gets. Once the CA certificate is received by the requester, a -fingerprint is generated using either the SHA-1 or the MD5 hash -algorithm on the whole CA certificate. If the requester does not have -a certificate path to a trusted CA certificate, this fingerprint may -be used to verify the certificate, by some positive out-of-band means, -such as a phone call. - -5.5.1 GetCACert HTTP Message Format - "GET" CGI-PATH CGI-PROG "?operation=GetCACert" "&message=" CA-IDENT - where: - CGI-PATH defines the actual CGI path to invoke the CGI program - which parses the request. - CGI-PROG is set to be the string "pkiclient.exe" and this is - expected to be the program that the CA will use to handle the - SCEP transactions. - CA-IDENT is any string which is understood by the CA. - For example, it could be a domain name like ietf.org. - If a certificate authority has multiple CA certificates - this field can be used to distinguish which is required. - Otherwise it may be ignored. - -5.5.2 Response - -The response for GetCACert is different between the case where the CA -directly communicated with the requester during the enrollment, and the -case where a RA exists and the requester communicates with the RA -during the enrollment. - -5.5.2.1 CA Certificate Only Response - -A binary X.509 CA certificate is sent back as a MIME object with a -Content-Type of application/x-x509-ca-cert. - -5.5.2.2 CA and RA Certificates Response - -When an RA exists, both CA and RA certificates must be sent back in -the response to the GetCACert request. The RA certificate(s) must be -signed by the CA. A certificates-only PKCS#7 SignedData is used to -carry the certificates to the requester, with a Content-Type of -application/x-x509-ca-ra-cert. - - Liu/Madson/McGrew/Nourse [Page 32] - -5.5.3 Get Next Certificate Authority Certificate - -5.5.3.1 GetNextCACert HTTP Message Format - "GET" CGI-PATH CGI-PROG "?operation=GetNextCACert" "&message=" CA-IDENT - -The response to this message is a PKCS#7 certificates-only message containing -a CA certificate (and possibly RA certificates) to be used when the current CA -certificate expires, signed with the current CA cert (or RA certificate, if -the CA is in RA mode. Note that a PKCS#7 is returned even in CA mode. - -5.5.3.2 GetCACaps HTTP Message Format - "GET" CGI-PATH CGI-PROG "?operation=GetCACaps" "&message=" CA-IDENT - -This message requests capabilities from CA. The response is a list of -text capabilities, as defined in Appendix F. Support for this message -is optional, but if it is not supported, the client should assume that -none of the capabilities in Appendix F are supported. - -5.6 Get Certificate Authority Certificate Chain - -GetCACertChain provides a way to get the entire certificate chain. - -5.6.1 GetCACertChain HTTP Message Format - - "GET" CGI-SCRIPT "?" "operation=GetCACertChain" "&" "message" CA-IDENT - where CGI-SCRIPT and CA-IDENT are as described for GetCACert. - -5.6.2 Response - -The response for GetCACertChain is a certificates-only PKCS#7 SignedData -to carry the certificates to the requester, with a Content-Type of -application/x-x509-ca-ra-cert-chain. - -5.6.3 Backwards Compatability - -Versions of SCEP prior to revision 3 do not support GetCACertChain. -Certificate Authorities written to these prior versions will not be -able to process the message and may return an HTML error. - -To avoid this, clients should send the GetCACert message first. If the -returned certificate is self-signed or is signed by a Certificate -Authority that is trusted by the client, then it is not necessary to -send the GetCACertChain message and it should not be sent. - -If a Certificate Authority is configured with a certificate that is -not either self-signed or has a self-signed issuer, then it should -support this message. In other words, it should be supported if the -CA hierarchy is more than two-deep. - -An old CA in a two-deep hierarchy might still get this message from -a client if the client did not trust either that CA or its issuer. -In that event, the certificate cannot be trusted anyway. In any case -the CA must not crash or hang upon the receipt of the message and the -client must be able to handle whatever error is returned by the CA, -including an HTML error or an ungraceful disconnect. - - Liu/Madson/McGrew/Nourse [Page 33] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -The following is the ASN.1 definition of Cert-Only PKCS#7: - - certOnly SignedData ::= { - version 1 - digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) - digestAlgorithm(2) 5} - -contentInfo { - contentType {pkcs-7 1} -- data content identifier - content -- NULL - } - certificates -- the RA and CA certificates. - } - - CARACerts PKIMessage ::= { -- special pki message sent in the clear - contentType {pkcs-7 2} - content certOnly - } - - -6.0 Security Considerations - -This entire document is about security. Common security considerations -such as keeping private keys truly private and using adequate lengths -for symmetric and asymmetric keys must be followed in order to maintain -the security of this protocol. - - -7.0 Intellectual Property - -This protcol includes the optional use of Certificate Revocation List -Distribution Point (CRLDP) technology, which is a patented technology -of Entrust Technologies, Inc. (Method for Efficient Management of -Certificate Revocation Lists and Update Information (U.S. Patent -5,699,431)). Please contact Entrust Technologies, Inc. -(www.entrust.com) for more information on licensing CRLDP technology. - - -8.0 References - -[PKCS7] Kaliski, B., "PKCS #7: Cryptographic Message Syntax Version -1.5", RFC 2315, March 1998. - -[PKCS10] Kaliski, B., "PKCS #10: Certification Request Syntax Version -1.5", RFC 2314, March 1998. - -[RFC2459] Housley, R., ec. al., "Internet X.509 Public Key -Infrastructure Certificate and CRL Profile", RFC 2459, January 1999. - - - - - - - Liu/Madson/McGrew/Nourse [Page 34] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Appendix A: Cisco Requester Subject Name Definition - -The ip address and the FQDN of a SCEP client should be included in the -V3 extension subjectAltName. When the subjectAltName extension attribute -is present, both the subjectAltName fields and the subjectName field could -have the IP address and the FQDN information. - -When the X.500 directory is used by the CA to define the name space, the -subject name defined above become a RDN which is part of DN binded to -the requester's public key in the certificate. - - -A sample of DN assigned by Entrust CA is given below (assume the same -ciscoRouterAlice is used as the requester defined subject name): - - OU = InteropTesting, O = Entrust Technologies, C = CA - RDN = {"alice.cisco.com", "172.21.114.67", "22334455"} - - - Liu/Madson/McGrew/Nourse [Page 35] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Appendix B: IPSEC Client Enrollment Certificate Request - -The following is the certificate enrollment request (PKCS#10) as created -by Cisco VPN Client: - ------END NEW CERTIFICATE REQUEST----- - 0 30 439: SEQUENCE { - 4 30 288: SEQUENCE { - 8 02 1: INTEGER 0 - 11 30 57: SEQUENCE { - 13 31 55: SET { - 15 30 53: SEQUENCE { - 17 06 3: OBJECT IDENTIFIER commonName (2 5 4 3) - 22 13 46: PrintableString - : 'For Xiaoyi, IPSEC attrs in alternate name - extn' - : } - : } - : } - 70 30 158: SEQUENCE { - 73 30 13: SEQUENCE { - 75 06 9: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 - 1 1) - 86 05 0: NULL - : } - 88 03 140: BIT STRING 0 unused bits - : 30 81 88 02 81 80 73 DB 1D D5 65 AA EF C7 D4 8E - : AA 6E EB 46 AC 91 2A 0F 50 51 17 AD 50 A2 2A F2 - : CE BE F1 E4 22 8C D7 61 A1 6C 87 61 62 92 CB A6 - : 80 EA B4 0F 09 9D 18 5F 39 A3 02 0E DB 38 4C E4 - : 8A 63 2E 72 8B DC BE 9E ED 6C 1A 47 DE 13 1B 0F - : 83 29 4D 3E 08 86 FF 08 2B 43 09 EF 67 A7 6B EA - : 77 62 30 35 4D A9 0F 0F DF CC 44 F5 4D 2C 2E 19 - : E8 63 94 AC 84 A4 D0 01 E1 E3 97 16 CD 86 64 18 - : [ Another 11 bytes skipped ] - : } - 231 A0 63: [0] { - 233 30 61: SEQUENCE { - 235 06 9: OBJECT IDENTIFIER extensionReq (1 2 840 113549 1 9 - 14) - 246 31 48: SET { - 248 30 46: SEQUENCE { - 250 30 44: SEQUENCE { - 252 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17) - 257 04 37: OCTET STRING - 30 23 87 04 01 02 03 04 81 0D 65 6D 61 69 - - - Liu/Madson/McGrew/Nourse [Page 36] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - 6C 40 69 72 65 2E 63 6F 6D 82 0C 66 71 64 - 6E 2E 69 72 65 2E 63 6F 6D - : } - : } - : } - : } - : } - : } - - 296 30 13: SEQUENCE { - 298 06 9: OBJECT IDENTIFIER md5withRSAEncryption (1 2 840 113549 - 1 1 4) - 309 05 0: NULL - : } - 311 03 129: BIT STRING 0 unused bits - : 19 60 55 45 7F 72 FD 4E E5 3F D2 66 B0 77 13 9A - : 87 86 75 6A E1 36 C6 B6 21 71 68 BD 96 F0 B4 60 - : 95 8F 12 F1 65 33 16 FD 46 8A 63 19 90 40 B4 B7 - : 2C B5 AC 63 17 50 28 F0 CD A4 F0 00 4E D2 DE 6D - : C3 4F F5 CB 03 4D C8 D8 31 5A 7C 01 47 D2 2B 91 - : B5 48 55 C8 A7 0B DD 45 D3 4A 8D 94 04 3A 6C B0 - : A7 1D 64 74 AB 8A F7 FF 82 C7 22 0A 2A 95 FB 24 - : 88 AA B6 27 83 C1 EC 5E A0 BA 0C BA 2E 6D 50 C7 - : } - - -Appendix C: Private OID Definitions - -The OIDs used in defining pkiStatus are VeriSign self-maintained -OIDs. Please note, work is in progress to replace the VeriSign owned -object identifiers with the standard object identifiers. Once the -standarlization is completed, this documentation will be updated. - -id-VeriSign OBJECT_IDENTIFIER ::= {2 16 US(840) 1 VeriSign(113733)} -id-pki OBJECT_IDENTIFIER ::= {id-VeriSign pki(1)} -id-attributes OBJECT_IDENTIFIER ::= {id-pki attributes(9)} -id-messageType OBJECT_IDENTIFIER ::= {id-attributes messageType(2)} -id-pkiStatus OBJECT_IDENTIFIER ::= {id-attributes pkiStatus(3)} -id-failInfo OBJECT_IDENTIFIER ::= {id-attributes failInfo(4)} -id-senderNonce OBJECT_IDENTIFIER ::= {id-attributes senderNonce(5)} -id-recipientNonce OBJECT_IDENTIFIER ::= {id-attributes recipientNonce(6)} -id-transId OBJECT_IDENTIFIER ::= {id-attributes transId(7)} -id-extensionReq OBJECT_IDENTIFIER ::= {id-attributes extensionReq(8)} - - - Liu/Madson/McGrew/Nourse [Page 37] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - Appendix D: CRL Query by means of LDAP - - In order to retrieve the CRL by means of LDAP, the client needs to know - where in the directory it is stored. The certificate must contain a - CRL Distribution Point extension encoded as a DN or as an LDAP URI. - -For example, the certificate issued by Entrust VPN contains -the following DN as the CRL distribution point: - - - -CN = CRL1, O = cisco, C = US. - - The asn.1 encoding of this distribution point is: - - 30 2C 31 0B 30 09 06 03 55 04 06 13 02 55 53 31 0E 30 0C 06 - 03 55 04 0A 13 05 63 69 73 63 6F 31 0D 30 0B 06 03 55 04 03 - 13 04 43 52 4C 31 - - -The ldap form would be: - -ldap://servername/CN=CRL1,O=cisco,C=US - - - -Appendix E: SCEP State Transitions - -SCEP state transitions are based on transaction identifier. The design -goal is to ensure the synchronization between the CA and the requester -under various error situations. - - -An identity is defined by the combination of FQDN, the IP address and -the client serial number. FQDN is the required name attribute. It is -important to notice that, a client named as Alice.cisco.com is different -from the client named as Alice.cisco.com plus IPAddress 117.96.1.219. - -Each enrollment transaction is uniquely associated with a transaction -identifier. Because the enrollment transaction could be interrupted by -various errors, including network connection errors or client reboot, -the SCEP client generates a transaction identifier by calculating a -hash on the public key value for which the enrollment is requested. This -retains the same transaction identifier throughout the enrollment -transaction, even if the client has rebooted or timed out, and issues a -new enrollment request for the same key pair. It also provides the way -for the CA to uniquely identify a transaction in its database. At the -requester side, it generates a transaction identifier which is included -in PKCSReq. If the CA returns a response of PENDING, the requester -will poll by periodically sending out GetCertInitial with the same -transaction identifier until either a response other than PENDING is -obtained, or the configured maximum time has elapsed. - -If the client times out or the client reboots, the client administrator -will start another enrollment transaction with the same key pair. The -second enrollment will have the transaction idenifier. At the server -side, instead of accepting the PKCSReq as a new enrollment request, it -should respond as if another GetCertInitial message had been sent with -that transaction ID. In another word, the second PKCSReq should be -taken as a resynchronization message to allow the enrollment resume as -the same transaction. - -It is important to keep the transaction id unique since SCEP requires the -same policy and same identity be applied to the same subject name and - - - Liu/Madson/McGrew/Nourse [Page 38] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -key pair binding. In the current implementation, an SCEP client can -only assume one identity. At any time, only one key pair, with a given -key usage, can be associated with the same identity. - -The following gives several examples of client to CA transactions. - -Client actions are indicated in the left column, CA actions are -indicated in the right column. A blank action signifies that no message -was received. Note that these examples assume that the CA enforces the -certificate-name uniqueness property defined in Section 2.1.1.1. - -The first transaction, for example, would read like this: - "Client Sends PKCSReq message with transaction ID 1 to the - CA. The CA signs the certificate and constructs a CertRep Message - containing the signed certificate with a transaction ID 1. The client - receives the message and installs the cert locally." - -Successful Enrollment Case: no manual authentication -PKCSReq (1) ----------> CA Signs Cert -Client Installs Cert <---------- CertRep (1) SIGNED CERT - - - -Successful Enrollment Case: manual authentication required -PKCSReq (10) ----------> Cert Request goes into Queue -Client Polls <---------- CertRep (10) PENDING -GetCertInitial (10) ----------> Still pending -Client Polls <---------- CertRep (10) PENDING -GetCertInitial (10) ----------> Still pending -Client Polls <---------- CertRep (10) PENDING -GetCertInitial (10) ----------> Still pending -Client Polls <---------- CertRep (10) PENDING -GetCertInitial (10) ----------> Cert has been signed -Client Installs Cert <---------- CertRep (10) SIGNED CERT - - - -Resync Case - CA Receive and Signs PKCSReq, Client Did not receive -CertRep: - -PKCSReq (3) ----------> Cert Request goes into queue - <---------- CertRep (3) PENDING -GetCertInitial (3) ----------> - <---------- CertRep (3) PENDING -GetCertInitial (3) -----------> - <----------- CA signed Cert and sent back - CertRep(3) -(Time Out) -PKCSReq (3) ----------> Cert already signed, sent back to - client -Client Installs Cert <---------- CertRep (3) SIGNED CERT - - - - Liu/Madson/McGrew/Nourse [Page 39] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - - -Case when NVRAM is lost and client has to generate a new key pair, there -is no change of name information: - -PKCSReq (4) ----------> CA Signs Cert -Client Installs Cert <---------- CertRep (4) SIGNED CERT -(Client looses Cert) -PKCSReq (5) ----------> There is already a valid cert with - this DN. -Client Admin Revokes <---------- CertRep (5) OVERLAPPING CERT ERROR -PKCSReq (5) ----------> CA Signs Cert -Client Installs Cert <---------- CertRep (5) SIGNED CERT - - -Case when client admin resync the enrollment using a different PKCS#10: -PKCSReq (6) ----------> CA Signs Cert - <---------- CertRep (6) SIGNED CERT -(Client timeout and admin starts another enrollment with a different - PKCS#10, but the same transaction id) -PKCSReq (6) with different PKCS#10 - ----------> There is already a valid cert with - this entity (by checking FQDN). - <---------- CertRep (6) INVALID PKCS#10 CERT - ERROR -Client admin either revokes the existing cert -or corrects the error by enrolling with -the same PKCS#10 as the first PKCSReq(6) -PKCSReq (6) ----------> CA find the existing Cert -Client Installs Cert <---------- CertRep (6) SIGNED CERT - - -Resync case when server is slow in response: -PKCSReq (13) ----------> Cert Request goes into Queue - <---------- CertRep (13) PENDING -GetCertInitial ----------> Still pending - <---------- CertRep (13) PENDING -GetCertInitial ----------> Still pending - <---------- CertRep (13) PENDING -GetCertInitial ----------> Still pending - <---------- CertRep (13) PENDING -GetCertInitial ----------> Still pending -(TimeOut) <---------- CertRep (13) PENDING -* Case 1 -PKCSReq (13) ----------> Still pending -Client polls <---------- CertRep (13) PENDING -CertCertInitial ----------> Cert has been signed -Client Installs Cert <---------- CertRep (13) SIGNED CERT -* Case 2 -PKCSReq (13) ----------> Cert has been signed -Client Installs Cert <---------- CertRep (13) SIGNED CERT - - - - - Liu/Madson/McGrew/Nourse [Page 40] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Appendix F. CA Capabilities - -The response for a GetCACaps message is a list of CA capabilities, in -plain text, separated by characters, as follows (quotation marks -are NOT sent): - -Keyword Description - -"GetNextCACert" CA Supports the GetNextCACert message. -"POSTPKIOperation" PKIOPeration messages may be sent via HTTP POST. -"SHA-1" CA Supports the SHA-1 hashing algorithm in - signatures and fingerprints. If present, the - client SHOULD use SHA-1. If absent, the client - MUST use MD5 to maintain backward compatability. -"Renewal" Clients may use current certificate and key to - authenticate an enrollment request for a new - certificate. - -A client must be able to accept and ignore any unknown keywords that -might be sent back by a CA that implements a future version of SCEP. - -Example: - -GET /cgi-bin/pkiclient.exe?operation=GetCACaps&message=myca - -returns: - -GetNextCACert -POSTPKIOperation - -This means that the CA supports the GetNextCACert message and allows -PKIOperation messages (PKCSreq, GetCert, GetCertInitial...) to be sent -using HTTP POST. - - - Liu/Madson/McGrew/Nourse [Page 41] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Appendix G. Certificate Renewal and CA Key Rollover - -To renew a client certificate, use the PKCSreq message and sign it with -the existing client certificate instead of a self-signed certificate. - -To obtain the new CA certificate prior to the expiration of the current -one, use the GetNextCACert message if the CA supports it. - -To obtain a new client certificate signed by the new CA certificate, -use the new CA or RA certificate in the message envelope. - - -Example: - -GetNextCACert ----------> - <---------- CertRep (3) New CA certificate - -PKCSReq* (1) ----------> CA Signs certificate with NEW key -Client Stores Cert <---------- CertRep (3) Certificate issued -for installation when from NEW CA certificate and keypair. -existing cert expires. - - -*enveloped for new CA or RA cert and keypair. The CA will use the -envelope to determine which key and certificate to use to issue the -client certificate. - - - Liu/Madson/McGrew/Nourse [Page 42] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Appendix H. PKIOperation via HTTP POST Message - -If the remote CA supports it, any of the PKCS#7-encoded SCEP messages -may be sent via HTTP POST instead of HTTP GET. This is allowed for -any SCEP message except GetCACert, GetCACertChain, GetNextCACert, -or GetCACaps. In this form of the message, Base 64 encoding is not -used. - -POST /cgi-bin/pkiclient.exe?operation=PKIOperation - - -The client can verify that the CA supports SCEP messages via POST by -looking for the "POSTPKIOperation" capability (See Appendix F). - - - - - - - Liu/Madson/McGrew/Nourse [Page 43] - -Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 - -Appendix Y. Author Contact Information - -Xiaoyi Liu Cheryl Madson -Cisco Cisco -510 McCarthy Drive 510 McCarthy Drive -Milpitas, CA Milpitas, CA. -xliu@cisco.com cmadson@cisco.com - - -David McGrew Andrew Nourse -Cisco Cisco -170 West Tasman Drive 510 McCarthy Drive -San Jose, CA 94134 Milpitas, CA. -mcgrew@cisco.com nourse@cisco.com - - - - -Appendix Z. Copyright Section - -Copyright (C) The Internet Society (2005). This document is subject -to the rights, licenses and restrictions contained in BCP 78, and -except as set forth therein, the authors retain all their rights. - -This document and the information contained herein are provided on an -"AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS -OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET -ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE -INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED -WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - -This draft expires 11 Aug 2005 - -[End of draft-nourse-scep-11.txt] - + +INTERNET DRAFT Xiaoyi Liu +draft-nourse-scep-11.txt Cheryl Madson +expires 11 Aug 2005 David McGrew +(revised 11 Feb 2005) Andrew Nourse + Cisco Systems + +Category: Informational 11 Feb 2005 + + +Cisco Systems' Simple Certificate Enrollment Protocol(SCEP): + +Status of this Memo + +This document is an Internet-Draft and is NOT offered in accordance +with Section 10 of RFC2026, and the author does not provide the IETF +with any rights other than to publish as an Internet-Draft + +Internet-Drafts are working documents of the Internet Engineering Task +Force (IETF), its areas, and its working groups. Note that other +groups may also distribute working documents as Internet-Drafts. + +Internet-Drafts are draft documents valid for a maximum of six months +and may be updated, replaced, or obsoleted by other documents at any +time. It is inappropriate to use Internet- Drafts as reference +material or to cite them other than as "work in progress." + +The list of current Internet-Drafts can be accessed at +http://www.ietf.org/ietf/1id-abstracts.txt + +The list of Internet-Draft Shadow Directories can be accessed at +http://www.ietf.org/shadow.html. + +This memo provides information for the Internet community. This memo +does not specify an Internet standard of any kind. Distribution of +this memo is unlimited. + +By submitting this Internet-Draft, I certify that any applicable patent +or other IPR claims of which I am aware have been disclosed, or will be +disclosed, and any of which I become aware will be disclosed, in accordance +with RFC 3668. + +Abstract + +This document specifies the Simple Certificate Enrollment Protocol, +a PKI communication protocol which leverages existing technology by +using PKCS#7 and PKCS#10. SCEP is the evolution of the enrollment +protocol developed by Verisign, Inc. for Cisco Systems, Inc. +It now enjoys wide support in both client and CA implementations. + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. The Goal of SCEP . . . . . . . . . . . . . . . . . . . . . 3 + 2.1 SCEP Entity types . . . . . . . . . . . . . . . . . . . . 3 + 2.2 SCEP Operations Overview . . . . . . . . . . . . . . . . . 7 + 2.3 PKI Operation Transactional Behavior . . . . . . . . . . . 10 + 2.4 Security . . . . . . . . . . . . . . . . . . . . . . . . . 12 + 3. Transport Protocol . . . . . . . . . . . . . . . . . . . . 13 + 4. Secure Transportation: PKCS #7 . . . . . . . . . . . . . . 14 + 4.1 SCEP Message Format . . . . . . . . . . . . . . . . . . . 14 + + Liu/Madson/McGrew/Nourse [Page 2] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + 4.2 Signed Transaction Attributes . . . . . . . . . . . . . . 15 + 5. SCEP Transaction Specification . . . . . . . . . . . . . . 16 + 5.1 Certificate Enrollment . . . . . . . . . . . . . . . . . . 16 + 5.2 Poll for Requester Initial Certificate . . . . . . . . . . 22 + 5.3 Certificate Access . . . . . . . . . . . . . . . . . . . . 26 + 5.4 CRL Access . . . . . . . . . . . . . . . . . . . . . . . 27 + 5.5 Get Certificate Authority Certificate . . . . . . . . . . 31 + 5.6 Get Certificate Authority Certificate Chain . . . . . . . 33 + 6. Security Considerations . . . . . . . . . . . . . . . . . 33 + 7. Intellectual Propoerty . . . . . . . . . . . . . . . . . . 33 + 8. References . . . . . . . . . . . . . . . . . . . . . . . . 33 + Appendix A. Cisco Requester Subject Name Definition . . . . . . 34 + Appendix B. IPSEC Client Enrollment Certificate Request . . . . 35 + Appendix C. Private OID Definitions . . . . . . . . . . . . . 36 + Appendix D. Obtaining CRL by LDAP Query . . . . . . . . . . . . 36 + Appendix E. SCEP State Transitions . . . . . . . . . . . . . . 37 + Appendix F. CA Capabilities . . . . . . . . . . . . . . . . . . 40 + Appendix G. Certificate Renewal and CA Key Rollover . . . . . . 41 + Appendix H. PKIOperation via HTTP POST Message. . . . . . . . . 42 + Appendix Y. Author Contact Information. . . . . . . . . . . . . 43 + Appendix Z. Copyright Section . . . . . . . . . . . . . . . . . 43 + +Section 1. Introduction + +Public key technology is becoming more widely deployed and is becoming +the basis for standards based security, such as the Internet Engineering +Task Force's IPSEC and IKE protocols. With the use of public key +certificates in network security protocols comes the need for a +certificate management protocol that Public Key Infrastructure (PKI) +clients and Certificate Authority servers can use to support certificate +life cycle operations such as certificate enrollment and revocation, and +certificate and CRL access. + +In the following, Section 2 gives an overview of the PKI operations, +and Section 2.4 describes the security goals of the protocol and the +mechanisms used to achieve them. The transport protocol and the +security protocol PKCS#7 are described at Section 3 and Section 4, +respectively. The last section, Section 5, specifies each PKI +operation in terms of the message formats and the data structures of +each operation. + +The appendices provide detailed specifications and examples. Requester +subject names are specified in Appendix A, attribute OIDs are +specified in Appendix C , and the SCEP state transitions are described +in Appendix E. An example of a certificate enrollment request is +provided in Appendix B, and an example LDAP query URL encoding is +provided in Appendix D. + +The authors would like to thank Peter William of ValiCert, Inc. +(formerly of Verisign, Inc) and Alex Deacon of Verisign, Inc. and +Christopher Welles of IRE, Inc. for their contributions to this protocol +and to this document. + + Liu/Madson/McGrew/Nourse [Page 3] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +2.0 The Goal of SCEP +The goal of SCEP is to support the secure issuance of certificates to +network devices in a scalable manner, using existing technology whenever +possible. The protocol supports the following operations: + + CA and RA public key distribution + Certificate enrollment + Certificate revocation + Certificate query + CRL query + +Certificate and CRL access can be achieved by using the LDAP protocol +(as specified in Appendix D), or by using the query messages defined in +SCEP. The use of HTTP certificate and CRL access, and the support of +CDP as specified in RFC2459, will be specified in a future version of +this document. In Section 2.1, we first define PKI entity types as well +as the properties of each entity type. In Section 2.2, the PKI +operations are described at functional level. Section 2.3 describes the +transaction behavior of each PKI operations. The complete PKI messages +are covered in Section 5. + +2.1 SCEP Entity types + +The entity types defined in SCEP are the "requester" type (i.e., IPSEC +clients), the Certificate Authority (CA) entity type, and the +Registration Authority entity type (RA). A requester is sometimes +called a "SCEP client" in the following. + +2.1.1 Requesters + +A requester is an entity whose name is defined in a certificate +subject name field and optionally, in SubjectAltName, a X.509 +certificate V3 extension. As a requester, a SCEP client is identified +by a subject name consisting of the following naming attributes: + + Fully qualified domain name, for example, router.cisco.com + IP address, Serial number, and/or x.500 distinguished name + +The fully qualified domain name is required for a requester that intends +to use the certificate for ISAKMP. The IP address, serial number, and +x.500 distinguished name are optional name attributes. In the +certificate enrollment request, the PKCS#10 subject field contains the +required and optional name attributes. The distinguished name, if any, +should be the subject name field, while any domain name, serial number, +or IP address supplied should be in the subjectAltName field. The +subject name field may be empty (if there is no distinguished name) +or the subjectAltName may be omitted, but not both. + +It is important to note that a client named as Alice.cisco.com is +different than a client named as Alice.cisco.com plus the IP address +name attribute 117.96.1.219. From CA point of view, the Distinguished +names assigned in these two cases are distinct names. + + + Liu/Madson/McGrew/Nourse [Page 4] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Entity names which are specified as in the IPSEC profile (i.e., FQDN, IP +address and User FQDN) must be presented in certificate's SubjectAltName +extension. Multiple IPSEC entity names, (if any) are encoded as multiple +values of a single SubjectAltName extension. The CA has the authority +to assign a distinguished name to a requester, whether or not one was +included in the request. The assigned DN should contain the SCEP client +names as the relative DN. + +The attribute identifiers and an example of SCEP client subject name are +specified in Appendix A. Appendix B has an example from Cisco VPN Client +enrollment request. + +2.1.1.1 Local Key/Certificate/CRL Storage and Certificate-name uniqueness + +A requester is required to generate asymmetric key pairs and to provide +storage to store its private keys. If the requester does not have enough +permanent memory to save its certificate, then it should be able to query +its own certificate from the CA or an LDAP server, once the certificate +has been issued. The public key pairs can be generated with a specific +key usage. The key usage is conveyed to the CA through the certificate +enrollment request. All current SCEP client implementations expect that +there will be only one pair of keys for a given subject name +and key usage combination and CA, at any time. This property is called +the certificate-name uniqueness property, and it implies that a CA that +implements SCEP will enforce the unique mapping between a SCEP client +subject name and its key pairs with a given key usage. At any time, if +the subject name is changed, or if the key is updated, the existing +certificate would have to be revoked before a new one could be issued. + +It is desirable that the CA enforce certificate-name uniqueness, but +it is not mandatory. However a CA that does not enforce uniqueness +must provide some other mechanism to prevent the re-transmission of an +enrollment request by a SCEP client from creating a second certificate +or certificate request, nor can the second request merely be rejected. +If a client times out from polling for a pending request it can +resynchronize by reissuing the original request with the original +subject name, key, and transaction ID. This should return the status of +the original transaction, including the certificate if it was granted. +It should not create a new transaction unless the original cert has been +revoked, or the transaction arrives more than halfway through the +validity time of the original certificate. + +An enrollment request that occurs more than halfway through the validity +time of an existing certificate for the same subject name and key usage +MAY be interpreted as a re-enrollment or renewal request and accepted. +A new certificate with new validity dates may be issued, even though +the old one is still valid, if the CA policy permits, as described in +2.1.1.3. See also appendix G. + +2.1.1.2 Requester authentication + +As with every protocol that uses public-key cryptography, the +association between the public keys used in the protocol and the +identities with which they are associated must be authenticated in a + Liu/Madson/McGrew/Nourse [Page 5] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +cryptographically secure manner. This requirement is needed to +prevent a "man in the middle" attack, in which an adversary that can +manipulate the data as it travels between the protocol participants +can subvert the security of the protocol. To satisfy this +requirement, SCEP provides two authentication methods: manual +authentication, and authentication based on pre-shared secret. In the +manual mode, the requester is required to wait until its identity can +be verified by the CA operator using any reliable out-of-band +method. To prevent a "man-in-the-middle" attack, a SHA-1 or MD5 +`fingerprint' generated on the PKCS#10 (before PKCS #7 enveloping and +signing) must be compared out-of-band between the server and the +requester. SCEP clients and CAs (or RAs, if appropriate) must display +this fingerprint to the operator to enable this verification if manual +mode is used. Failing to provide this information leaves the protocol +vulnerable to attack by sophisticated adversaries. When utilizing a +pre-shared secret scheme, the server should distribute a shared secret +to the requester which can uniquely associate the enrollment request +with the given end entity. The distribution of the secret must be +private: only the end entity should know this secret. The actual +binding mechanism between the requester and the secret is subject to +the server policy and implementation. When creating the enrollment +request, the requester is asked to provide a challenge password. When +using the pre-shared secret scheme, the requester must enter the +re-distributed secret as the password. In the manual authentication +case, the challenge password only used to authenticate a request for +the certificate's revokation. This challenge password is included as +a PKCS#10 attribute, and is sent to the server as encrypted data. The +PKCS#7 envelope protects the privacy of the challenge password with +DES encryption. + +2.1.1.3 Requester Uses Existing CA-Issued or Self-Signed Certificates + +In this protocol, the communication between the requester and the +certificate authority is secured by using PKCS#7 as the messaging +protocol. PKCS#7, however, is a protocol which assumes the +communicating entities already possess the peer's certificates and +requires both parties use the issuer names and issuer assigned +certificate serial numbers to identify the certificate in order to +verify the signature and decrypt the message. If the requesting +system already has a certificate issued by the CA, that certificate +may be presented as credentials for the renewal of that certificate if +the CA supports the "Renewal" capability and the CA policy permits the +certificate to be renewed. If the requester has no certificate issued +by the CA, or if the CA does not support and permit renewal, the +requestor must generate a self-signed certificate with the requester +subject name (the same name later used in the PKCS#10) as both issuer +and subject name. During the certificate enrollment, the requester +will first post itself as the signing authority by attaching the +self-signed certificate to the signed certificate request. When the +Certificate Authority makes the envelope on the issued certificate +using the public key included in the self-signed certificate, it +should use the same issuer name and serial number as conveyed in the +self-signed certificate to inform the end entity on which private key +should be used to open the envelope. + Liu/Madson/McGrew/Nourse [Page 6] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Note that when a client enrolls for separate encryption and signature +certificates, it may use the signature certificate to sign both +requests, and then expect its signature key to be used to encrypt +both responses. In any case, the recipientinfo on the envelope should +reflect the key used to encrypt the request. + +2.1.1.4 Trusted CA Store + +To support interoperability between IPSEC peers whose certificates are +issued by different CA, SCEP allows the users to configure multiple +trusted certificates. Trusted certificates are have been configured as +such in the client, based on some out-of-band means such as a "fingerprint". +These trusted certificates are used to verify certificate chains that end +in those certificates. + +2.1.2 Certificate Authority + +A Certificate Authority(CA) is an entity whose name is defined in the +certificate issuer name field. Before any PKI operations can begin, +the CA generates its own public key pair and creates a self-signed CA +certificate, or causes another CA to issue a certificate to it. +Associated with the CA certificate is a fingerprint which will be used +by the requester to authenticate the received CA certificate if it is +self-signed. The fingerprint is created by calculating a SHA-1 or MD5 +hash on the whole CA certificate. Before any requester can start its +enrollment, this CA certificate has to be configured at the entity +side securely. For IPSEC clients, the client certificates must have +SubjectAltName extension. To utilize LDAP as a CRL query protocol, +the certificates must have a CRL Distribution Point. Key usage is +optional. Without key usage, the public key is assumed as a general +purpose public key and it can be used for all the purposes. + +A Certificate Authority may enforce certain name policy. When using +X.500 directory name as the subject name, all the name attributes +specified in the PKCS#10 request should be included as Relative DN. All +the name attributes as defined in RFC2459 should be specified in the +SubjectAltName. An example is provided in Appendix A. + + If there is no LDAP query protocol support, the Certificate Authority +should answer certificate and CRL queries, and to this end it should be +online all the time. + +The updating of the CA's public key is addressed in Appendix G. + +2.1.3 Registration Authorities + +In an environment where an RA is present, a requester performs +enrollment through the RA. In order to setup a secure channel with an RA +using PKCS#7, the RA certificate(s) have to be obtained by the client +in addition to the CA certificate(s). + +In the following, the CA and RA are specified as one entity in the +context of PKI operation definitions. + Liu/Madson/McGrew/Nourse [Page 7] +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 +2.2 SCEP Operations Overview + +In this section, we give a high level overview of the PKI operations as +defined in SCEP. + +2.2.1 Requester Initialization + +The requester initialization includes the key pair generation and the +configuring of the required information to communicate with the +certificate authority. + +2.2.1.1 Key Pairs + +Before a requester can start PKI transaction, it must have at least one +asymmetric key pair, using the selected algorithm (the RSA algorithm is +required in SCEP, and is the only algorithm in current implementations). + +Key pairs may be intended for particular purposes, such as encryption only, +or signing only. The usage of any associated certificate can be restricted +by adding key usage and extended key usage attributes to the PKCS#10. + +2.2.1.2 Required Information + +A requester is required to have the following information configured +before starting any PKI operations: + +1. the certificate authority IP address or fully-qualified domain name, +2. the certificate authority HTTP CGI script path, and + the HTTP proxy information in case there is no direct Internet + connection to the server, +3. If CRLs are being published by the CA to an LDAP directory server, + and there is a CRL Distribution Point containing only an X.500 directory + name, then the client will need to know the LDAP server fully-qualified + domain name or IP address. CRL Distribution Points are discussed in + more detail in RFC 2459. + + +2.2.2 CA/RA Certificate Distribution + +Before any PKI operation can be started, the requester needs to get +the CA/RA certificates. At this time, since no public key has been + + Liu/Madson/McGrew/Nourse [Page 8] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +exchanged between the requester and the CA/RA, the message to get the +CA/RA certificate can not be secured using PKCS#7 protocol. Instead, the +CA/RA certificate distribution is implemented as a clear HTTP Get +operation. After the requester gets the CA certificate, it has to +authenticate the CA certificate by comparing the finger print with the +CA/RA operator. Since the RA certificates are signed by the CA, there is +no need to authenticate the RA certificates. + +This operation is defined as a transaction consisting of one HTTP Get +message and one HTTP Response message: + + REQUESTER CA SERVER + Get CA/RA Cert: HTTP Get message + -----------------------------> + CA/RA Cert download: HTTP Response message + <--------------------------------------- + Compute finger print and + call CA operator. + Receive call and check finger print + +If an RA is in use, a degenerated PKCS#7 with a certificate chain +consisting of both RA and CA certificates is sent back to the end +entity. Otherwise the CA certificate is directly sent back as the +HTTP response payload. + + +2.2.3 Certificate Enrollment + +A requester starts an enrollment transaction by creating a certificate +request using PKCS#10 and sends it to the CA/RA enveloped using the +PKCS#7. After the CA/RA receives the request, it will either +automatically approve the request and send the certificate back, or it +will require the requester to wait until the operator can manually +authenticate the identity of the requester. Two attributes are +included in the PKCS#10 certificate request - a Challenge Password +attribute and an optional ExtensionReq attribute which will be a +sequence of extensions the requester would like to be included in its +V3 certificate extensions. The Challenge Password may be used to +authenticate either the enrollment request itself, or a verbal +revocation request for the issued certificate in the event of key +compromise or other reason. + +In the automatic mode, the transaction consists of one PKCSReq PKI +Message, and one CertRep PKI message. In the manual mode, the requester +enters into polling mode by periodically sending a GetCertInitial PKI +message to the server, until the server operator completes the manual +authentication, after which the CA will respond to GetCertInitial by +returning the issued certificate. A CA MAY run in automatic mode for +preapproved requests, and manual mode for the rest. A request with a +non-null password is not necessarily a pre-approved request. It is up +to the CA server to decide. Polling mode is entered whenever the +server returns a PENDING response. + + Liu/Madson/McGrew/Nourse [Page 9] +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + +The transaction in automatic mode: + + REQUESTER CA SERVER + +PKCSReq: PKI cert. enrollment msg + --------------------------------> CertRep: pkiStatus = SUCCESS + certificate attached + <------------------------------ + Receive issued certificate. + +The transaction in manual mode: + + REQUESTER CA SERVER + PKCSReq: PKI cert. enrollment msg + --------------------------------> CertRep: pkiStatus = PENDING + <------------------------------ + GetCertInitial: polling msg + --------------------------------> CertRep: pkiStatus = PENDING + <------------------------------ + ................. CertRep: pkiStatus = SUCCESS + certificate attached + <------------------------------ + Receive issued certificate. + +2.2.4 Requester Certificate Revocation + +A requester should be able to revoke its own certificate. Currently +the revocation is implemented as a manual process. In order to revoke a +certificate, the requester makes a phone call to the CA server +operator. The operator will come back asking the ChallengePassword +(which has been sent to the server as an attribute of the PKCS#10 +certificate request). If the ChallengePassword matches, the certificate +is revoked. The reason of the revocation is documented by CA/RA. + +2.2.5 Certificate Access + +There are two methods to query certificates. The first method is to use +LDAP as a query protocol. Using LDAP to query assumes the client +understand the LDAP scheme supported by the CA. The SCEP client assumes +that the subject DN name in the certificate is used as the URL to query the +certificate. The standard attributes (userCertificate and caCertificate) +are used as filter. + +For the environment where LDAP is not available, a certificate query +message is defined to retrieve the certificates from the CA. + +To query a certificate from the certificate authority, a requester +sends a request consisting of the certificate's issuer name and the +serial number. This assumes that the requester has saved the issuer + + Liu/Madson/McGrew/Nourse [Page 10] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +name and the serial number of the issued certificate from the previous +enrollment transaction. The transaction to query a certificate consists +of one GetCert PKI message and one CertRep PKI message: + + REQUESTER CA SERVER + GetCert: PKI cert query msg + -------------------------------> CertRep: pkiStatus = SUCCESS + certificate +attached + <----------------------------- + Receive the certificate. + +2.2.6 CRL Distribution + +The CA/RA will not "push" the CRL to the end entities. The query of the +CRL can only be initialized by the requester. + +There are three methods to query CRL. + +The CRL may be retrieved by a simple HTTP GET. If the CA supports this +method, it should encode the URL into a CRL Distribution Point extension +in the certificates it issues. Support for this method should be +incorporated in new and updated clients, but may not be in older +versions. + +The second method is to query CRL using LDAP. This assumes the CA server +supports CRL LDAP publishing and issues the CRL Distribution Point in +the certificate. The CRL Distribution Point is encoded as a DN. Please +refer to Appendix D for the examples of CRL Distribution Point. + +The third method is implemented for the CA which does not support LDAP +CRL publishing or does not implement the CRL Distribution Point. In this +case, a CRL query is composed by creating a message consists of the CA +issuer name and the CA's certificate serial number. This method is +deprecated because it does not scale well and requires the CA to be a +high-availability service. + +The message is sent to the CA in the same way as the other SCEP +requests: The transaction to query CRL consists of one GetCRL PKI +message and one CertRep PKI message which have no certificates but CRL. + + REQUESTER CA SERVER + GetCRL: PKI CRL query msg + ----------------------------------> CertRep: CRL attached + <-------------------------------- + +2.3 PKI Operation Transactional Behavior + +As described before, a PKI operation is a transaction consisting of the +messages exchanged between a requester and the CA/RA. This section +will specify the transaction behavior on both the requester and the + + + Liu/Madson/McGrew/Nourse [Page 11] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +certificate authority server. Because the protocol is basically a two +way communication protocol without a confirmation message from the +initiating side, state and state resynchronization rules have to be +defined, in case any error happens at either side. Before the state +transition can be defined, the notion of transaction identifier has to +be defined first. + +2.3.1 Transaction Identifier + +A transaction identifier is a string generated by the entity when +starting a transaction. Since all the PKI operations defined in this +protocol are initiated by the requester, it is the responsibility of +the requester to generate a unique string as the transaction +identifier. All the PKI messages exchanged for a given PKI transaction +must carry the same transaction identifier. The transaction identifier +is generated as a SHA-1 or MD5 hash on the public key value for which the +enrollment request is made. This allows the SCEP client to reuse the +same transaction identifier if it is reissuing a request for the same +certificate (i.e. a certificate with the same subject, issuer, and key). +The SCEP protocol requires that transaction identifiers be unique, so +that queries can be matched up with transactions. For this reason, in +those cases in which separate signing and encryption certificates are +issued to the same requester, the keys must be different. + +2.3.2 State Transitions in Certificate Enrollment + +The requester state transitions during enrollment operation are +indicated in the diagram below: + +-<------+ + | | + GetCertInitial triggered by timeout or + | | manual authentication + | | + [CERT-NONEXISTANT] ------> [CERT-REQ-PENDING] ---> [CERT-ISSUED] + | PKCSReq | CertRep with SUCCESS + | | + | | + +--------<-------------------+ + request rejected, timeout, or error + +As described in the section 2.2.3, certificate enrollment starts at the +state CERT-NONEXISTANT. Sending PKCSReq changes the state to +CERT-REQ-PENDING. Receiving CertRep with SUCCESS status changes the +state to CERT-ISSUED. In the case the server sending back the response +with pending status, the requester will keep polling certificate +response by sending GetCertInitial to the server, until either a CertRep +with SUCCESS status is received, or the maximum polling number has been +exceeded. + +If an error or timeout occurs in the CERT-REQ-PENDING state, the end +entity will transition to the CERT-NONEXISTANT state. + + + Liu/Madson/McGrew/Nourse [Page 12] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + +The client administrator will, eventually, start up another enrollment +request. It is important to note that, as long as the requester does +not change its subject name or keys, the same transaction id will be +used in the "new" transaction. This is important because based on this +transaction id, the certificate authority server can recognize this as +an existing transaction instead of a new one. + + +2.3.3 Transaction Behavior of Certificate/CRL Access + +There is no state maintained during certificate access and CRL access +transaction. When using the certificate query and CRL query messages +defined in this protocol, the transaction identifier is still required +so that the requester can match the response message with the +upstanding request message. When using LDAP to query the certificate and +the CRL, the behavior is specified by the LDAP protocol. + +2.4 Security + +The security goals of SCEP are that no adversary can: + +o subvert the public key/identity binding from that intended, +o discover the identity information in the enrollment requests and + issued certificates, +o cause the revocation of certificates with any non-negligible + probability. + +Here an adversary is any entity other than the requester and the CA +(and optionally the RA) participating in the protocol that is +computationally limited, but that can manipulate data during +transmission (that is, a man-in-the-middle). The precise meaning of +'computationally limited' depends on the implementer's choice of +cryptographic hash functions and ciphers. The required algorithms are +RSA, DES, and either SHA-1 or MD5, depending on the "SHA-1" CA Capability. +[See Appendix F]. + +The first and second goals are met through the use of PKCS#7 and PKCS#10 +encryption and digital signatures using authenticated public keys. The +CA's public key is authenticated via the checking of the CA fingerprint, +as specified in Section 2.1.2, and the SCEP client's public key is +authenticated through the manual authentication or pre-shared secret +authentication, as specified in Section 2.1.1.2. The third goal is met +through the use of a Challenge Password for revocation, that is chosen +by the SCEP client and communicated to the CA protected by the PKCS#7 +encryption, as specified in Section 2.2.4. + +The motivation of the first security goal is straightforward. The +motivation for the second security goal is to protect the identity +information in the enrollment requests and certificates. For example, +two IPSEC hosts behind a firewall may need to exchange certificates, and +may need to enroll certificates with a CA that is outside of a firewall. +Most networks with firewalls seek to prevent IP addresses and DNS + + Liu/Madson/McGrew/Nourse [Page 13] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +information from the trusted network leaving that network. The second +goal enables the hosts in this example to enroll with a CA outside the +firewall without revealing this information. The motivation for the +third security goal is to protect the SCEP clients from denial of +service attacks. + +Section 3 Transport Protocol + +In the SCEP protocol, HTTP is used as the transport protocol for the PKI +messages. + +3.1 HTTP "GET" and "POST" Message Format + +The following is the syntax definition of a HTTP GET message sent from +a requester to a certificate authority server: + +Request = "GET " CGI-PATH CGI-PROG "?operation=" OPERATION "&message=" MESSAGE +where: + CGI-PATH defines the actual CGI path to invoke the CGI program which + parses the request. + CGI-PROG is set to be the string "pkiclient.exe". This is intended + to be the program that the CA will use to handle the SCEP transactions, + though the CA may ignore CGI-PROG and use only the CGI-PATH. + OPERATION is set to be the string "PKIOperation" when the GET message + carries a PKI message to request certificates or CRL; OPERATION is set + to be the string "GetCACaps", "GetCACert", "GetNextCACert" or + "GetCACertChain" when the GET operation is used to get CA capabilities, + CA/RA certificate, the replacement CA/RA certificates for when the + current ones expire, or the CA Cert chain (respectively). + + When OPERATION is "PKIOperation", MESSAGE is a base64-encoded PKI message, + When OPERATION is GetCACert, MESSAGE is a CRL distribution + point in URI format, otherwise, MESSAGE is a string which represents + the certificate authority issuer identifier. + +SCEP uses the HTTP "GET" and "POST" messages to request information from the CA. +Requests for CA certificates or capabilities are sent in the clear, using "GET", +with the OPERATION and MESSAGE fields identifying the requested data. +CRLs may also be requested in the clear if the CA supports it. + +Other types of requests are sent using the PKCS#7 secure protocol. +These may be issued by means of a GET operation with +OPERATION and MESSAGE parameters in the Request-URL. OPERATION +identifies the type of GET operation, and MESSAGE is actually the PKCS#7 +message Base64-Encoded. + +For example. a requester may submit a message via HTTP to the server +as follows: + +GET /cgi-bin/pkiclient.exe?operation=PKIOperation&message=MIAGCSqGSIb3D +QEHA6CAMIACAQAxgDCBzAIBADB2MGIxETAPBgNVBAcTCE ......AAAAAA== + Liu/Madson/McGrew/Nourse [Page 13a] + +If supported by the CA, the message may also be sent via HTTP POST: + +POST /cgi-bin/pkiclient.exe?operation=PKIOperation + +This is further described in Appendix H. +To determine if the CA supports POST, use the GetCACaps message described +in Appendix F. + + +3.2 Response Message Format + +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. The following is an +example of the response: + +"Content-Type:application/x-pki-message\n\n" + +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. the body of the response is a DER encoded +binary X.509 certificate. For example: + +"Content-Type:application/x-x509-ca-cert\n\n" + +If there is an RA, the RA certificates are sent back together with the +CA certificates, a certificate-only PKCS#7 SignedData is sent back in +the response where the SignerInfo is empty. Section 5 has the detailed +definition of the message format in this case. The content type is +application/x-x509-ca-ra-cert. + +The response to GetNextCACert is always a certificates-only PKCS#7 +SignedData with a content type of application/x-x509-ca-ra-cert. +If there is an RA, The signer is the current RA certificate. Otherwise, +the signer is the current CA certificate. + +If the CA supports it, PKIOperation may also be done via an HTTP POST. +This is described in Appendix H. + + Liu/Madson/McGrew/Nourse [Page 14] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Section 4 Secure Transportation: PKCS#7 + +PKCS#7 is a general enveloping mechanism that enables both signed and +encrypted transmission of arbitrary data. It is widely implemented and +included in the RSA tool kit. In this section, the general PKCS#7 +enveloped PKI message format is specified. The complete PKCS#7 message +format for each PKI transaction will be covered in Section 5. + +4.1 SCEP Message Format + +As a transaction message, a SCEP message has a set of transaction +specific attributes and an information portion. Employing PKCS#7 +protocol, the transaction specific attributes are encoded as a set of +authenticated attributes of the SignedData. The information portion will +first be encrypted to become Enveloped Data, and then the digest of the +enveloped information portion is included as one of the message digest +attributes and being signed together with the other transaction specific +attributes. + +By applying both enveloping and signing transformations, a SCEP message +is protected both for the integrity of its end-end-transition +information and the confidentiality of its information portion. The +advantage of this technique over the conventional transaction message +format is that, the signed transaction type information and the status +of the transaction can be determined prior to invoke security handling +procedures specific to the information portion being processed. + +The following is an example of a SCEP message with its enveloped and +signed data portion represented by pkcsPKISigned and +pkcsPKIEnveloped. The out-most of any PKI message is a blob of +ContentInfo, with its content type set to SignedData and the actual +signed data as the content. + + Liu/Madson/McGrew/Nourse [Page 15] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + pkiMessage ContentInfo ::= { + contentType {pkcs-7 signedData(2)} + content pkcsPKISigned + } + pkcsPKISigned SignedData ::= { + version 1 + digestAlgorithm { iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} -- data content identifier + content pkcsPKIEnvelope -- enveloped information portion + } + certificates -- signer certificate chain + signerInfo -- including signed transaction info and the digest + -- of the enveloped information portion as the + -- authenticated attributes + } + pkcsPKIEnveloped EnvelopedData ::= { + version 0 + recipientInfos -- information required to open the envelop + encryptedContentInfo { + contentType {pkcs-7 1} -- data content identifier + contentEncryptionAlgorithm + encryptedContent -- encrypted information portion + } + } + +4.2 Signed Transaction Attributes + +The following transaction attributes are encoded as authenticated +attributes. Please refer to Appendix B for the OID definitions. + +transactionID PrintableString -- Decimal value as a string + messageType PrintableString -- Decimal value as a string + pkiStatus PrintableString -- Decimal value as a string + failinfo PrintableString -- Decimal value as a string + senderNonce Octet String + recipientNonce Octet String + +where: + + The transactionID is an attribute which uniquely identify a + transaction. This attribute is required in all PKI messages. + + The messageType attribute specify the type of operation performed by the + transaction. This attribute is required in all PKI + messages. Currently, the following message types are defined: + + PKCSReq (19) -- Permits use of PKCS#10 certificate request + CertRep (3) -- Response to certificate or CRL request + GetCertInitial (20) -- Certificate polling in manual enrollment + GetCert (21) -- Retrieve a certificate + GetCRL (22) -- Retrieve a CRL + + Liu/Madson/McGrew/Nourse [Page 16] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + + All response message will include transaction status information which + is defined as pkiStatus attribute: + + SUCCESS (0) -- request granted + FAILURE (2) -- request rejected + PENDING (3) -- request pending for manual approval. + + If the status in the response is FAILURE, the failinfo attribute will + contain one of the following failure reasons: + + badAlg (0) -- Unrecognized or unsupported algorithm ident + badMessageCheck (1) -- integrity check failed + badRequest (2) -- transaction not permitted or supported + badTime (3) -- Message time field was not sufficiently close + to the system time + badCertId (4) -- No certificate could be identified matching + the provided criteria + + The attributes of senderNonce and recipientNonce are the 16 byte + random numbers generated for each transaction to prevent the replay + attack. + +When a requester sends a PKI message to the server, a senderNonce is +included in the message. After the server processes the request, it will +send back the requester senderNonce as the recipientNonce and generates +another nonce as the senderNonce in the response message. Because the +proposed pki protocol is a two-way communication protocol, it is clear +that the nonce can only be used by the requester to prevent the +replay. The server has to employ extra state related information to +prevent a replay attack. + +Section 5. SCEP Transaction Specification + +In this section each SCEP transaction is specified in terms of the +complete messages exchanged during the transaction. + +5.1 Certificate Enrollment + +The certificate enrollment transaction consists of one PKCSReq message +sent to the certificate authority from a requester, and one CertRep +message sent back from the server. The pkiStatus returned in the +response message is either SUCCESS, or FAILURE, or PENDING. The +information portion of a PKCSReq message is a PKCS#10 certificate +request, which contains the subject Distinguished Name, the subject +public key, and two attributes, a ChallengePassword attribute to be used +for revocation, and an optional ExtensionReq attribute which will be a +sequence of extensions the requester expects to be included in its V3 +certificate extensions. One of the extension attribute specifies the key +usage. If the request is granted, the pkiStatus is set to SUCCESS, and +the certificate is returned in CertRep; if the request is rejected, the + + + Liu/Madson/McGrew/Nourse [Page 17] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +pkiStatus is set to FAILURE; if the server requires manual approval of +the request, the pkiStatus is set to PENDING. The messages exchanged +in the manual authentication mode is further specified in Section 5.2. + +Precondition: + Both the requester and the certificate authority have completed their + initialization process. The requester has already been configured + with the CA/RA certificate. + +Postcondition: + Either the certificate is received by the requester, or the end + entity is notified to do the manual authentication, or the request + is rejected. + +5.1.1 PKCSReq Message Format + +A PKCSReq message is created by following the steps defined below: + +1. Create a PKCS#10 certificate request which is signed by the end + entity's private key, corresponding to the public key included in + the PKCS#10 certificate request. This constitutes the information + portion of PKCSReq. + +2. Encrypt the PKCS#10 certificate request using a randomly generated + content-encryption key. This content-encryption key is then + encrypted by the CA's* public key and included in the recipientInfo. + This step completes the "envelope" for the PKCS#10 certificate + request. + +3. Generate a unique string as the transaction id. + +4. Generate a 16 byte random number as senderNonce. + +5. Generate message digest on the enveloped PKCS#10 certificate request + using the selected digest algorithm. + +6. Create SignedData by adding the requester's self- or CA-certificate + as the signer's public key certificate. Include the message type, + transaction id, the senderNonce and the message digest as the + authenticated attributes and sign the attributes using the end + entity's private key. This completes the SignedData. + +7. The SignedData is prepended with the ContenInfo blob which indicates + a SignedData object. This final step completes the create of a + complete PKCSReq PKI message. + +In the following, the PKCSReq message is defined following the ASN.1 +notation. + +For readability, the values of a field is either represented by a quoted +string which specifies the intended value, or a constant when the value +is known. + + + Liu/Madson/McGrew/Nourse [Page 18] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + -- PKCSReq information portion + pkcsCertReq CertificationRequest ::= { -- PKCS#10 + version 0 + subject "the requester's subject name" + subjectPublicKeyInfo { + algorithm {pkcs-1 1} -- rsa encryption + subjectPublicKey "DER encoding of the requester's public key" + } + attributes { + challengePassword {{pkcs-9 7} "password string" } + extensions + } + signatureAlgorithm {pkcs-1 4} -- MD5WithRSAEncryption + signature "bit string which is created by signing inner content + of the defined pkcsCertReq using requester's private + key, corresponding to the public key included in + subjectPublicKeyInfo." + } + -- Enveloped information portion + pkcsCertReqEnvelope EnvelopeData ::= { -- PKCS#7 + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the CA issuer name" + serialNumber "the CA certificate serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} -- rsa encryption + encryptedKey "content-encryption key + encrypted by CA public key" + } + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "object identifier + for DES encryption" + encryptedContent "encrypted pkcsCertReq using the content- + encryption key" + } + } + -- Signed PKCSReq + pkcsCertReqSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} -- data content identifier + content pkcsCertReqEnvelope + } + certificate { -- requester self-signed or CA-issued certificate + version 3 + serialNumber "the transaction id associated with enrollment" + signature {pkcs-1 4} -- md5WithRSAEncryption + + + Liu/Madson/McGrew/Nourse [Page 19] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + issuer " the requester's subject name" + validity { + notBefore "a UTC time" + notAfter "a UTC time" + } + subject "the requester's subject name" + subjectPublicKeyInfo { + algorithm {pkcs-1 1} + subjectPublicKey "DER encoding of requester's public key" + } + signatureAlgorithm {pkcs-1 4} + signature "the signature generated by using the requester's + private key corresponding to the public key in + this certificate." + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the requester's subject name" + serialNumber "the transaction id associated + with the enrollment" + } + digestAlgorithm {iso(0) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "an octet string"} + transaction-id {{id-attributes transId(7)} "printable + string"} + -- this transaction id will be used + -- together with the subject name as + -- the identifier of the requester's key + -- pair during enrollment + messageType {{id-attributes messageType(2)} "PKCSReq"} + senderNonce {{id-attributes senderNonce(5)} + "a random number encoded as a string"} + } + digestEncryptionAlgorithm {pkcs-1 1} -- rsa encryption + encryptedDigest "encrypted digest of the authenticated + attributes using requester's private key" + } + } + pkcsReq PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsCertRepSigned + } + + + + + + + + + Liu/Madson/McGrew/Nourse [Page 20] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +5.1.2 CertRep Message Format + +The response to an SCEP enrollment request is a CertRep message. + +5.1.2.1 PENDING Response + +When the CA is configured to manually authenticate the requester, +the CertRep is returned with the attribute pkiStatus set to PENDING. +The data portion for this message is null. Only the transaction +required attributes are sent back. + +CertRepSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo {contentType {pkcs-7 1} -- empty content + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "name of CA that issued the CA [RA] cert" + serialNumber "the serial number of the CA [RA] cert" + } + digestAlgorithm (iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} NULL} + messageType {{id-attribute messageType(0)} "CertRep"} + transaction-id {{id-attributes transid(7)} "printablestring"} + --- same transaction id used in PKCSReq + pkiStatus {{id-attributes pkiStatus(3)} "PENDING"} + recipientNonce {{id-attributes recipientNonce(6)}<16 bytes>} + senderNonce {{id-attributes senderNonce(5)} <16 bytes>} + } + digestEncrytionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted message digest of the authenticated + attributes using the CA's [RA's] private key" + } +} +CertRep PKIMessage ::= { + contentType {pkcs-7 2} + content CertRepSigned +} + +5.1.2.2 Failure Response + +In this case, the CertRep sent back to the requester is same as in +the PENDING case, except that the pkiStatus attribute is set to FAILURE, +and the failInfo attribute should be included: + + pkistatus {{id-attributes pkiStatus(3)} "FAILURE"} + failInfo {{id-attributes failInfo(4)} "the reason to reject"} + + Liu/Madson/McGrew/Nourse [Page 21] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +5.1.2.3 SUCCESS response + +In this case, the information portion of CertRep will be a degenerated +PKCS#7 which contains the requester's certificate. It is then enveloped +and signed as below: + +pkcsCertRep SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { -- empty content since this is degenerated PKCS#7 + contentType {pkcs-7 1} + } + certificates { + certificate { -- issued requester's certificate // must be first + version 3 + serialNumber "issued requester's certificate serial number" + signature {pkcs-1 4} -- md5WithRSAEncryption + issuer "the certificate authority issuer name" + validity { + notBefore "UTC time" + notAfter "UTC time" + } + subject "the requester subject name as given in PKCS#10" + subjectPublicKeyInfo { + algorithm {pkcs-1 1} + subjectPublicKey "a DER encoding of requester public + key as given in PKCS#10" + } + extensions " the extensions as given in PKCS#10" + signatureAlgorithm {pkcs-1 4} + signature " the certificate authority signature" + } + certificate "the certificate authority certificate" (optional) + certificate "the registration authority certificate(s)" (optional) + } +} +pkcsCertRepEnvelope EnvelopedData ::= { -- PKCS#7 + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { -- use issuer name and serial number as + -- conveyed in requester's self-signed + -- certificate, included in the PKCSReq + issuer "the requester's subject name" + serialNumber "the serial number defined by the requester in + its self-signed certificate" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted by the requester's + public key which is same key as authenticated in + the requester's certificate" + } + + + Liu/Madson/McGrew/Nourse [Page 22] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + encryptedContentInfo { + contentType {pkcs-7 1} -- data content identifier + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted pkcsCertRep using content encryption + key" + } +} +pkcsCertRepSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + content pkcsCertRepEnvelope + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the certificate authority issuer name" + serialNumber "the CA certificate's serial number" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "a octet string"} + messageType {{id-attribute messageType(2)} "CertRep"} + transaction-id {{id-attributes transId(7)} "printable + string"} + -- same transaction id as given in PKCSReq + pkiStatus {{id-attributes pkiStatus(3) "SUCCESS"} + recipientNonce {{id-attribute recipientNonce(6)}<16 bytes>} + senderNonce {{ id-attributes senderNonce(5) <16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticate attributes + using CA's private key " + } +} +CertRep PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsCertRepSigned +} + +5.2 Poll for Requester Initial Certificate + +Either triggered by the PENDING status received from the CertRep, or by +the non-response timeout for the previous PKCSReq, a requester will +enter the polling state by periodically sending GetCertInitial to the +server, until either the request is granted and the certificate is sent +back, or the request is rejected, or the configured time limit for +polling is exceeded. + + + Liu/Madson/McGrew/Nourse [Page 23] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + +Since GetCertInitial is part of the enrollment, the messages exchanged +during the polling period should carry the same transaction identifier +as the previous PKCSReq. + +PreCondition + Either the requester has received a CertRep with pkiStatus set to be + PENDING, or the previous PKCSReq has timed out. + +PostContition + The requester has either received the certificate, or be rejected of + its request, or the polling period ended as a failure. + +5.2.1 GetCertInitial Message Format + +Since at this time the certificate has not been issued, the requester +can only use the requester's subject name, combined with the +transaction identifier, to identify the polled certificate request. + +The certificate authority server must be able to uniquely identify the +polled certificate request. A subject name can have more than one +outstanding certificate request (with different key usage attributes). + +-- Information portion + +pkcsGetCertInitial issuerAndSubject ::= { + issuer "the certificate authority issuer name" + subject "the requester subject name as given in PKCS#10" +} +pkcsGetCertInitialEnvelope EnvelopedData ::= { + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the CA issuer name" + serialNumber "the CA certificate serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted by CA's public key" + } + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted getCertInital" + } +} +pkcsGetCertInitialSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + + + Liu/Madson/McGrew/Nourse [Page 24] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + content pkcsGetCertIntialEnvelope + } + certificate { -- the requester's self-signed certificate + version 3 + serialNumber "the transaction id associated with enrollment" + signature {pkcs-1 4} -- md5WithRSAEncryption + issuer " the requester's subject name" + validity { + notBefore "a UTC time" + notAfter "a UTC time" + } + subject "the requester's subject name" + subjectPublicKeyInfo { + algorithm {pkcs-1 1} + subjectPublicKey "DER encoding of requester's public key" + } + signatureAlgorithm {pkcs-1 4} + signature "the signature generated by using the requester's + private key corresponding to the public key in + this certificate." + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "requester's subject name" + serialNumber "the transaction id used in previous PKCSReq" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "an octet string"} + -- digest of getCertInitial + messageType {{id-attribute messageType(2)} "GetCertInitial"} + transaction-id {{id-attributes transId(7)} "printable + string"} + -- same transaction idused in previous PKCSReq + senderNonce {{id-attribute senderNonce(3)} 0x<16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticateAttributes" + } +} +GetCertInitial PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsGetCertInitialSigned +} + + + +5.2.2 GetCertInitial Response Message Format + +The response messages for GetCertInitial are the same as for PKCSReq. + + Liu/Madson/McGrew/Nourse [Page 25] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +5.3 Certificate Access + +The certificate query message defined in this section is an option when +the LDAP server is not available to provide the certificate query. A +requester should be able to query an issued certificate from the +certificate authority, as long as the issuer name and the issuer +assigned certificate serial number is known to the requesting end +entity. This transaction is not intended to provide the service as a +certificate directory service. A more complicated query mechanism would +have to be defined in order to allow a requester to query a certificate +using various different fields. + +This transaction consists of one GetCert message sent to the server by +a requester, and one CertRep message sent back from the server. + +PreCondition + The queried certificate have been issued by the certificate authority + and the issuer assigned serial number is known. + +PostCondition + Either the certificate is sent back or the request is rejected. + + +5.3.1 GetCert Message Format + +The queried certificate is identified by its issuer name and the issuer +assigned serial number. If this is a query for an arbitrary requester's +certificate, the requesting requester should includes its own CA issued +certificate in the signed envelope. If this is a query for its own +certificate (assume the requester lost the issued certificate, or does +not have enough non-volatile memory to save the certificate), then the +self-signed certificate has to be included in the signed envelope. + + pkcsGetCert issuerAndSerialNumber ::= { + issuer "the certificate issuer name" + serialNumber "the certificate serial number" + } + pkcsGetCertEnvelope EnvelopedData ::= { + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the CA [RA] issuer name" + serialNumber "the CA [RA] certificate serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted + by CA [RA] public key" + } + + + + + + Liu/Madson/McGrew/Nourse [Page 26] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted pkcsGetCert using the content + encryption key" + } + } + pkcsGetCertSigned SignedData ::= { + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + content pkcsGetCertEnvelope + } + certificates { + certificate "CA issued certificate" + or "self-signed certificate" + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the requester's subject name" + serialNumber "requester's certificate serial number" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "an octet string"} + -- digest of pkcsGetCertEnvelope + messageType {{id-attribute messageType(2)} "GetCert"} + transaction-id {{id-attributes transId(7)} "printable + string"} + senderNonce {{id-attribute senderNonce(3)} <16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticateAttributes" + } + } + GetCert PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsGetCertSigned + } + + + + + + + + + + Liu/Madson/McGrew/Nourse [Page 27] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + +5.3.2 CertRep Message Format + +In this case, the CertRep from the server is same as the CertRep for the +PKCSReq, except that the server will only either grant the request or +reject the request. Also, the recipientInfo should use the CA issuer +name and CA assigned serial number to identify the requester's key pair +since at this time, the requester has received its own certificate. + +5.4 CRL Access + +The CRL query message defined in this section is an option when the LDAP +server is not available to provide the CRL query. In the PKI protocol +proposed here, only the requester can initiate the transaction to +download CRL. A requester sends GetCRL request to the server and the +server sends back CertRep whose information portion is a degenerated +PKCS#7 which contains only the most recent CRL. The size of CRL included +in the CertRep should be determined by the implementation. + +PreCondition + The certificate authority certificate has been downloaded to the end + entity. + +PostCondition + CRL sent back to the requester. + +5.4.1 GetCRL Message format + +The CRL is identified by using both CA's issuer name and the CA +certificate's serial number: + + pkcsGetCRL issuerAndSerialNumber { + issuer "the certificate authority issuer name" + serialNumber "certificate authority certificate's serial number" + } + +When the CRLDistributionPoint is supported, the pkcsGetCRL is defined as +the following: + + pkcsGetCRL SEQUENCE { + crlIssuer issuerAndSerialNumber + distributionPoint CE-CRLDistPoints + } + +where CE-CRLDisPoints is defined in X.509, but must contain only one +CRL distribution point. + + + + + + + + + + + Liu/Madson/McGrew/Nourse [Page 28] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + pkcsGetCRLEnvelope EnvelopedData ::= { + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the certificate authority (or RA) issuer name" + serialNumber "the CA (RA) certificate's serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted by CA (RA) public key" + } + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted pkcsGetCRL" + } + } + pkcsGetCRLSigned SignedData ::= { + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + content pkcsGetCRLEnvelope + } + certificates { + certificate "CA-issued or self-signed requester's certificate" + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the requester's issuer name" + serialNumber "the requester's certificate serial number" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} 0x<16/20 bytes>} + -- digest of pkcsGetCRLEnvelope + messageType {{id-attribute messageType(2)} "CertCRL"} + transaction-id {{id-attributes transId(7)} "printable + string"} + senderNonce {{id-attribute senderNonce(3)} <16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticateAttributes" + } + } + GetCRL PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsGetCRLSigned + } + + Liu/Madson/McGrew/Nourse [Page 29] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + +5.4.2 CertRep Message Format + +The CRL is sent back to the requester through CertRep message. The +information portion of this message is a degenerated PKCS#7 SignedData +which contains only a CRL. + + pkcsCertRep SignedData ::= { + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + } + crl { + signature {pkcs-1 4} + issuer "the certificate authority issuer name" + lastUpdate "UTC time" + nextUpdate "UTC time" + revokedCertificate { + -- the first entry + userCertificate "certificate serial number" + revocationData "UTC time" + .... + -- last entry + userCertificate "certificate serial number" + revocationData "UTC time" + } + } + pkcsCertRepEnvelope EnvelopedData ::= { + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the requester's issuer name" + serialNumber "the requester certificate serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted by requester's + public key " + } + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted pkcsCertRep using requester's + public key" + } + } + + + + + + + Liu/Madson/McGrew/Nourse [Page 30] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + + pkcsCertRepSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + content pkcsCertRepEnvelope + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the certificate authority issuer name" + serialNumber "the CA certificate's serial number" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "an octet string"} + -- digest of pkcsCertRepEnvelope + messageType {{id-attribute messageType(2)} "CertRep"} + transaction-id {{id-attributes transId(7)} "printable + string"} + -- same transaction id as given in PKCSReq + pkiStatus {{id-attributes pkiStatus(3) "SUCCESS"} + recipientNonce{{id-attribute recipientNonce(6)}<16 bytes>} + senderNonce {{id-attribute senderNonce (5) 0x<16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticatedAttributes + using CA private key" + } + } + + +NOTE:The PKCS#7 EncryptedContent is specified as an octet string, but +SCEP entities must also accept a sequence of octet strings as a valid +alternate encoding. + +This alternate encoding must be accepted wherever PKCS #7 Enveloped +Data is specified in this document. + + + + + + + + + + + + Liu/Madson/McGrew/Nourse [Page 31] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +5.5 Get Certificate Authority Certificate + +Before any transaction begins, end entities have to get the CA (and +possibly RA) certificate(s) first. Since the requester may have no CA +certificates or CA public keys at all, this message can not be +encrypted and the response must be authenticated by out-of-band means. +These certs are obtained by means of an HTTP GET message. To get the +CA certificate, the requester does a "HTTP GET" with a URL that +identifies a CGI script on the server and an optional CA issuer +identifier as the parameter to the CGI script. The response is either +a single X.509 CA certificate ("CA mode"), or a PKCS7 message +containing the CA certificate and RA certificates ("RA mode"). The +client can determine which mode the CA operates in by which response +it gets. Once the CA certificate is received by the requester, a +fingerprint is generated using either the SHA-1 or the MD5 hash +algorithm on the whole CA certificate. If the requester does not have +a certificate path to a trusted CA certificate, this fingerprint may +be used to verify the certificate, by some positive out-of-band means, +such as a phone call. + +5.5.1 GetCACert HTTP Message Format + "GET" CGI-PATH CGI-PROG "?operation=GetCACert" "&message=" CA-IDENT + where: + CGI-PATH defines the actual CGI path to invoke the CGI program + which parses the request. + CGI-PROG is set to be the string "pkiclient.exe" and this is + expected to be the program that the CA will use to handle the + SCEP transactions. + CA-IDENT is any string which is understood by the CA. + For example, it could be a domain name like ietf.org. + If a certificate authority has multiple CA certificates + this field can be used to distinguish which is required. + Otherwise it may be ignored. + +5.5.2 Response + +The response for GetCACert is different between the case where the CA +directly communicated with the requester during the enrollment, and the +case where a RA exists and the requester communicates with the RA +during the enrollment. + +5.5.2.1 CA Certificate Only Response + +A binary X.509 CA certificate is sent back as a MIME object with a +Content-Type of application/x-x509-ca-cert. + +5.5.2.2 CA and RA Certificates Response + +When an RA exists, both CA and RA certificates must be sent back in +the response to the GetCACert request. The RA certificate(s) must be +signed by the CA. A certificates-only PKCS#7 SignedData is used to +carry the certificates to the requester, with a Content-Type of +application/x-x509-ca-ra-cert. + + Liu/Madson/McGrew/Nourse [Page 32] + +5.5.3 Get Next Certificate Authority Certificate + +5.5.3.1 GetNextCACert HTTP Message Format + "GET" CGI-PATH CGI-PROG "?operation=GetNextCACert" "&message=" CA-IDENT + +The response to this message is a PKCS#7 certificates-only message containing +a CA certificate (and possibly RA certificates) to be used when the current CA +certificate expires, signed with the current CA cert (or RA certificate, if +the CA is in RA mode. Note that a PKCS#7 is returned even in CA mode. + +5.5.3.2 GetCACaps HTTP Message Format + "GET" CGI-PATH CGI-PROG "?operation=GetCACaps" "&message=" CA-IDENT + +This message requests capabilities from CA. The response is a list of +text capabilities, as defined in Appendix F. Support for this message +is optional, but if it is not supported, the client should assume that +none of the capabilities in Appendix F are supported. + +5.6 Get Certificate Authority Certificate Chain + +GetCACertChain provides a way to get the entire certificate chain. + +5.6.1 GetCACertChain HTTP Message Format + + "GET" CGI-SCRIPT "?" "operation=GetCACertChain" "&" "message" CA-IDENT + where CGI-SCRIPT and CA-IDENT are as described for GetCACert. + +5.6.2 Response + +The response for GetCACertChain is a certificates-only PKCS#7 SignedData +to carry the certificates to the requester, with a Content-Type of +application/x-x509-ca-ra-cert-chain. + +5.6.3 Backwards Compatability + +Versions of SCEP prior to revision 3 do not support GetCACertChain. +Certificate Authorities written to these prior versions will not be +able to process the message and may return an HTML error. + +To avoid this, clients should send the GetCACert message first. If the +returned certificate is self-signed or is signed by a Certificate +Authority that is trusted by the client, then it is not necessary to +send the GetCACertChain message and it should not be sent. + +If a Certificate Authority is configured with a certificate that is +not either self-signed or has a self-signed issuer, then it should +support this message. In other words, it should be supported if the +CA hierarchy is more than two-deep. + +An old CA in a two-deep hierarchy might still get this message from +a client if the client did not trust either that CA or its issuer. +In that event, the certificate cannot be trusted anyway. In any case +the CA must not crash or hang upon the receipt of the message and the +client must be able to handle whatever error is returned by the CA, +including an HTML error or an ungraceful disconnect. + + Liu/Madson/McGrew/Nourse [Page 33] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +The following is the ASN.1 definition of Cert-Only PKCS#7: + + certOnly SignedData ::= { + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + +contentInfo { + contentType {pkcs-7 1} -- data content identifier + content -- NULL + } + certificates -- the RA and CA certificates. + } + + CARACerts PKIMessage ::= { -- special pki message sent in the clear + contentType {pkcs-7 2} + content certOnly + } + + +6.0 Security Considerations + +This entire document is about security. Common security considerations +such as keeping private keys truly private and using adequate lengths +for symmetric and asymmetric keys must be followed in order to maintain +the security of this protocol. + + +7.0 Intellectual Property + +This protcol includes the optional use of Certificate Revocation List +Distribution Point (CRLDP) technology, which is a patented technology +of Entrust Technologies, Inc. (Method for Efficient Management of +Certificate Revocation Lists and Update Information (U.S. Patent +5,699,431)). Please contact Entrust Technologies, Inc. +(www.entrust.com) for more information on licensing CRLDP technology. + + +8.0 References + +[PKCS7] Kaliski, B., "PKCS #7: Cryptographic Message Syntax Version +1.5", RFC 2315, March 1998. + +[PKCS10] Kaliski, B., "PKCS #10: Certification Request Syntax Version +1.5", RFC 2314, March 1998. + +[RFC2459] Housley, R., ec. al., "Internet X.509 Public Key +Infrastructure Certificate and CRL Profile", RFC 2459, January 1999. + + + + + + + Liu/Madson/McGrew/Nourse [Page 34] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Appendix A: Cisco Requester Subject Name Definition + +The ip address and the FQDN of a SCEP client should be included in the +V3 extension subjectAltName. When the subjectAltName extension attribute +is present, both the subjectAltName fields and the subjectName field could +have the IP address and the FQDN information. + +When the X.500 directory is used by the CA to define the name space, the +subject name defined above become a RDN which is part of DN binded to +the requester's public key in the certificate. + + +A sample of DN assigned by Entrust CA is given below (assume the same +ciscoRouterAlice is used as the requester defined subject name): + + OU = InteropTesting, O = Entrust Technologies, C = CA + RDN = {"alice.cisco.com", "172.21.114.67", "22334455"} + + + Liu/Madson/McGrew/Nourse [Page 35] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Appendix B: IPSEC Client Enrollment Certificate Request + +The following is the certificate enrollment request (PKCS#10) as created +by Cisco VPN Client: + +-----END NEW CERTIFICATE REQUEST----- + 0 30 439: SEQUENCE { + 4 30 288: SEQUENCE { + 8 02 1: INTEGER 0 + 11 30 57: SEQUENCE { + 13 31 55: SET { + 15 30 53: SEQUENCE { + 17 06 3: OBJECT IDENTIFIER commonName (2 5 4 3) + 22 13 46: PrintableString + : 'For Xiaoyi, IPSEC attrs in alternate name + extn' + : } + : } + : } + 70 30 158: SEQUENCE { + 73 30 13: SEQUENCE { + 75 06 9: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 + 1 1) + 86 05 0: NULL + : } + 88 03 140: BIT STRING 0 unused bits + : 30 81 88 02 81 80 73 DB 1D D5 65 AA EF C7 D4 8E + : AA 6E EB 46 AC 91 2A 0F 50 51 17 AD 50 A2 2A F2 + : CE BE F1 E4 22 8C D7 61 A1 6C 87 61 62 92 CB A6 + : 80 EA B4 0F 09 9D 18 5F 39 A3 02 0E DB 38 4C E4 + : 8A 63 2E 72 8B DC BE 9E ED 6C 1A 47 DE 13 1B 0F + : 83 29 4D 3E 08 86 FF 08 2B 43 09 EF 67 A7 6B EA + : 77 62 30 35 4D A9 0F 0F DF CC 44 F5 4D 2C 2E 19 + : E8 63 94 AC 84 A4 D0 01 E1 E3 97 16 CD 86 64 18 + : [ Another 11 bytes skipped ] + : } + 231 A0 63: [0] { + 233 30 61: SEQUENCE { + 235 06 9: OBJECT IDENTIFIER extensionReq (1 2 840 113549 1 9 + 14) + 246 31 48: SET { + 248 30 46: SEQUENCE { + 250 30 44: SEQUENCE { + 252 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17) + 257 04 37: OCTET STRING + 30 23 87 04 01 02 03 04 81 0D 65 6D 61 69 + + + Liu/Madson/McGrew/Nourse [Page 36] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + 6C 40 69 72 65 2E 63 6F 6D 82 0C 66 71 64 + 6E 2E 69 72 65 2E 63 6F 6D + : } + : } + : } + : } + : } + : } + + 296 30 13: SEQUENCE { + 298 06 9: OBJECT IDENTIFIER md5withRSAEncryption (1 2 840 113549 + 1 1 4) + 309 05 0: NULL + : } + 311 03 129: BIT STRING 0 unused bits + : 19 60 55 45 7F 72 FD 4E E5 3F D2 66 B0 77 13 9A + : 87 86 75 6A E1 36 C6 B6 21 71 68 BD 96 F0 B4 60 + : 95 8F 12 F1 65 33 16 FD 46 8A 63 19 90 40 B4 B7 + : 2C B5 AC 63 17 50 28 F0 CD A4 F0 00 4E D2 DE 6D + : C3 4F F5 CB 03 4D C8 D8 31 5A 7C 01 47 D2 2B 91 + : B5 48 55 C8 A7 0B DD 45 D3 4A 8D 94 04 3A 6C B0 + : A7 1D 64 74 AB 8A F7 FF 82 C7 22 0A 2A 95 FB 24 + : 88 AA B6 27 83 C1 EC 5E A0 BA 0C BA 2E 6D 50 C7 + : } + + +Appendix C: Private OID Definitions + +The OIDs used in defining pkiStatus are VeriSign self-maintained +OIDs. Please note, work is in progress to replace the VeriSign owned +object identifiers with the standard object identifiers. Once the +standarlization is completed, this documentation will be updated. + +id-VeriSign OBJECT_IDENTIFIER ::= {2 16 US(840) 1 VeriSign(113733)} +id-pki OBJECT_IDENTIFIER ::= {id-VeriSign pki(1)} +id-attributes OBJECT_IDENTIFIER ::= {id-pki attributes(9)} +id-messageType OBJECT_IDENTIFIER ::= {id-attributes messageType(2)} +id-pkiStatus OBJECT_IDENTIFIER ::= {id-attributes pkiStatus(3)} +id-failInfo OBJECT_IDENTIFIER ::= {id-attributes failInfo(4)} +id-senderNonce OBJECT_IDENTIFIER ::= {id-attributes senderNonce(5)} +id-recipientNonce OBJECT_IDENTIFIER ::= {id-attributes recipientNonce(6)} +id-transId OBJECT_IDENTIFIER ::= {id-attributes transId(7)} +id-extensionReq OBJECT_IDENTIFIER ::= {id-attributes extensionReq(8)} + + + Liu/Madson/McGrew/Nourse [Page 37] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + Appendix D: CRL Query by means of LDAP + + In order to retrieve the CRL by means of LDAP, the client needs to know + where in the directory it is stored. The certificate must contain a + CRL Distribution Point extension encoded as a DN or as an LDAP URI. + +For example, the certificate issued by Entrust VPN contains +the following DN as the CRL distribution point: + + + +CN = CRL1, O = cisco, C = US. + + The asn.1 encoding of this distribution point is: + + 30 2C 31 0B 30 09 06 03 55 04 06 13 02 55 53 31 0E 30 0C 06 + 03 55 04 0A 13 05 63 69 73 63 6F 31 0D 30 0B 06 03 55 04 03 + 13 04 43 52 4C 31 + + +The ldap form would be: + +ldap://servername/CN=CRL1,O=cisco,C=US + + + +Appendix E: SCEP State Transitions + +SCEP state transitions are based on transaction identifier. The design +goal is to ensure the synchronization between the CA and the requester +under various error situations. + + +An identity is defined by the combination of FQDN, the IP address and +the client serial number. FQDN is the required name attribute. It is +important to notice that, a client named as Alice.cisco.com is different +from the client named as Alice.cisco.com plus IPAddress 117.96.1.219. + +Each enrollment transaction is uniquely associated with a transaction +identifier. Because the enrollment transaction could be interrupted by +various errors, including network connection errors or client reboot, +the SCEP client generates a transaction identifier by calculating a +hash on the public key value for which the enrollment is requested. This +retains the same transaction identifier throughout the enrollment +transaction, even if the client has rebooted or timed out, and issues a +new enrollment request for the same key pair. It also provides the way +for the CA to uniquely identify a transaction in its database. At the +requester side, it generates a transaction identifier which is included +in PKCSReq. If the CA returns a response of PENDING, the requester +will poll by periodically sending out GetCertInitial with the same +transaction identifier until either a response other than PENDING is +obtained, or the configured maximum time has elapsed. + +If the client times out or the client reboots, the client administrator +will start another enrollment transaction with the same key pair. The +second enrollment will have the transaction idenifier. At the server +side, instead of accepting the PKCSReq as a new enrollment request, it +should respond as if another GetCertInitial message had been sent with +that transaction ID. In another word, the second PKCSReq should be +taken as a resynchronization message to allow the enrollment resume as +the same transaction. + +It is important to keep the transaction id unique since SCEP requires the +same policy and same identity be applied to the same subject name and + + + Liu/Madson/McGrew/Nourse [Page 38] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +key pair binding. In the current implementation, an SCEP client can +only assume one identity. At any time, only one key pair, with a given +key usage, can be associated with the same identity. + +The following gives several examples of client to CA transactions. + +Client actions are indicated in the left column, CA actions are +indicated in the right column. A blank action signifies that no message +was received. Note that these examples assume that the CA enforces the +certificate-name uniqueness property defined in Section 2.1.1.1. + +The first transaction, for example, would read like this: + "Client Sends PKCSReq message with transaction ID 1 to the + CA. The CA signs the certificate and constructs a CertRep Message + containing the signed certificate with a transaction ID 1. The client + receives the message and installs the cert locally." + +Successful Enrollment Case: no manual authentication +PKCSReq (1) ----------> CA Signs Cert +Client Installs Cert <---------- CertRep (1) SIGNED CERT + + + +Successful Enrollment Case: manual authentication required +PKCSReq (10) ----------> Cert Request goes into Queue +Client Polls <---------- CertRep (10) PENDING +GetCertInitial (10) ----------> Still pending +Client Polls <---------- CertRep (10) PENDING +GetCertInitial (10) ----------> Still pending +Client Polls <---------- CertRep (10) PENDING +GetCertInitial (10) ----------> Still pending +Client Polls <---------- CertRep (10) PENDING +GetCertInitial (10) ----------> Cert has been signed +Client Installs Cert <---------- CertRep (10) SIGNED CERT + + + +Resync Case - CA Receive and Signs PKCSReq, Client Did not receive +CertRep: + +PKCSReq (3) ----------> Cert Request goes into queue + <---------- CertRep (3) PENDING +GetCertInitial (3) ----------> + <---------- CertRep (3) PENDING +GetCertInitial (3) -----------> + <----------- CA signed Cert and sent back + CertRep(3) +(Time Out) +PKCSReq (3) ----------> Cert already signed, sent back to + client +Client Installs Cert <---------- CertRep (3) SIGNED CERT + + + + Liu/Madson/McGrew/Nourse [Page 39] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + +Case when NVRAM is lost and client has to generate a new key pair, there +is no change of name information: + +PKCSReq (4) ----------> CA Signs Cert +Client Installs Cert <---------- CertRep (4) SIGNED CERT +(Client looses Cert) +PKCSReq (5) ----------> There is already a valid cert with + this DN. +Client Admin Revokes <---------- CertRep (5) OVERLAPPING CERT ERROR +PKCSReq (5) ----------> CA Signs Cert +Client Installs Cert <---------- CertRep (5) SIGNED CERT + + +Case when client admin resync the enrollment using a different PKCS#10: +PKCSReq (6) ----------> CA Signs Cert + <---------- CertRep (6) SIGNED CERT +(Client timeout and admin starts another enrollment with a different + PKCS#10, but the same transaction id) +PKCSReq (6) with different PKCS#10 + ----------> There is already a valid cert with + this entity (by checking FQDN). + <---------- CertRep (6) INVALID PKCS#10 CERT + ERROR +Client admin either revokes the existing cert +or corrects the error by enrolling with +the same PKCS#10 as the first PKCSReq(6) +PKCSReq (6) ----------> CA find the existing Cert +Client Installs Cert <---------- CertRep (6) SIGNED CERT + + +Resync case when server is slow in response: +PKCSReq (13) ----------> Cert Request goes into Queue + <---------- CertRep (13) PENDING +GetCertInitial ----------> Still pending + <---------- CertRep (13) PENDING +GetCertInitial ----------> Still pending + <---------- CertRep (13) PENDING +GetCertInitial ----------> Still pending + <---------- CertRep (13) PENDING +GetCertInitial ----------> Still pending +(TimeOut) <---------- CertRep (13) PENDING +* Case 1 +PKCSReq (13) ----------> Still pending +Client polls <---------- CertRep (13) PENDING +CertCertInitial ----------> Cert has been signed +Client Installs Cert <---------- CertRep (13) SIGNED CERT +* Case 2 +PKCSReq (13) ----------> Cert has been signed +Client Installs Cert <---------- CertRep (13) SIGNED CERT + + + + + Liu/Madson/McGrew/Nourse [Page 40] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Appendix F. CA Capabilities + +The response for a GetCACaps message is a list of CA capabilities, in +plain text, separated by characters, as follows (quotation marks +are NOT sent): + +Keyword Description + +"GetNextCACert" CA Supports the GetNextCACert message. +"POSTPKIOperation" PKIOPeration messages may be sent via HTTP POST. +"SHA-1" CA Supports the SHA-1 hashing algorithm in + signatures and fingerprints. If present, the + client SHOULD use SHA-1. If absent, the client + MUST use MD5 to maintain backward compatability. +"Renewal" Clients may use current certificate and key to + authenticate an enrollment request for a new + certificate. + +A client must be able to accept and ignore any unknown keywords that +might be sent back by a CA that implements a future version of SCEP. + +Example: + +GET /cgi-bin/pkiclient.exe?operation=GetCACaps&message=myca + +returns: + +GetNextCACert +POSTPKIOperation + +This means that the CA supports the GetNextCACert message and allows +PKIOperation messages (PKCSreq, GetCert, GetCertInitial...) to be sent +using HTTP POST. + + + Liu/Madson/McGrew/Nourse [Page 41] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Appendix G. Certificate Renewal and CA Key Rollover + +To renew a client certificate, use the PKCSreq message and sign it with +the existing client certificate instead of a self-signed certificate. + +To obtain the new CA certificate prior to the expiration of the current +one, use the GetNextCACert message if the CA supports it. + +To obtain a new client certificate signed by the new CA certificate, +use the new CA or RA certificate in the message envelope. + + +Example: + +GetNextCACert ----------> + <---------- CertRep (3) New CA certificate + +PKCSReq* (1) ----------> CA Signs certificate with NEW key +Client Stores Cert <---------- CertRep (3) Certificate issued +for installation when from NEW CA certificate and keypair. +existing cert expires. + + +*enveloped for new CA or RA cert and keypair. The CA will use the +envelope to determine which key and certificate to use to issue the +client certificate. + + + Liu/Madson/McGrew/Nourse [Page 42] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Appendix H. PKIOperation via HTTP POST Message + +If the remote CA supports it, any of the PKCS#7-encoded SCEP messages +may be sent via HTTP POST instead of HTTP GET. This is allowed for +any SCEP message except GetCACert, GetCACertChain, GetNextCACert, +or GetCACaps. In this form of the message, Base 64 encoding is not +used. + +POST /cgi-bin/pkiclient.exe?operation=PKIOperation + + +The client can verify that the CA supports SCEP messages via POST by +looking for the "POSTPKIOperation" capability (See Appendix F). + + + + + + + Liu/Madson/McGrew/Nourse [Page 43] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Appendix Y. Author Contact Information + +Xiaoyi Liu Cheryl Madson +Cisco Cisco +510 McCarthy Drive 510 McCarthy Drive +Milpitas, CA Milpitas, CA. +xliu@cisco.com cmadson@cisco.com + + +David McGrew Andrew Nourse +Cisco Cisco +170 West Tasman Drive 510 McCarthy Drive +San Jose, CA 94134 Milpitas, CA. +mcgrew@cisco.com nourse@cisco.com + + + + +Appendix Z. Copyright Section + +Copyright (C) The Internet Society (2005). This document is subject +to the rights, licenses and restrictions contained in BCP 78, and +except as set forth therein, the authors retain all their rights. + +This document and the information contained herein are provided on an +"AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS +OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET +ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE +INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + + + +This draft expires 11 Aug 2005 + +[End of draft-nourse-scep-11.txt] + + +INTERNET DRAFT Xiaoyi Liu +draft-nourse-scep-11.txt Cheryl Madson +expires 11 Aug 2005 David McGrew +(revised 11 Feb 2005) Andrew Nourse + Cisco Systems + +Category: Informational 11 Feb 2005 + + +Cisco Systems' Simple Certificate Enrollment Protocol(SCEP): + +Status of this Memo + +This document is an Internet-Draft and is NOT offered in accordance +with Section 10 of RFC2026, and the author does not provide the IETF +with any rights other than to publish as an Internet-Draft + +Internet-Drafts are working documents of the Internet Engineering Task +Force (IETF), its areas, and its working groups. Note that other +groups may also distribute working documents as Internet-Drafts. + +Internet-Drafts are draft documents valid for a maximum of six months +and may be updated, replaced, or obsoleted by other documents at any +time. It is inappropriate to use Internet- Drafts as reference +material or to cite them other than as "work in progress." + +The list of current Internet-Drafts can be accessed at +http://www.ietf.org/ietf/1id-abstracts.txt + +The list of Internet-Draft Shadow Directories can be accessed at +http://www.ietf.org/shadow.html. + +This memo provides information for the Internet community. This memo +does not specify an Internet standard of any kind. Distribution of +this memo is unlimited. + +By submitting this Internet-Draft, I certify that any applicable patent +or other IPR claims of which I am aware have been disclosed, or will be +disclosed, and any of which I become aware will be disclosed, in accordance +with RFC 3668. + +Abstract + +This document specifies the Simple Certificate Enrollment Protocol, +a PKI communication protocol which leverages existing technology by +using PKCS#7 and PKCS#10. SCEP is the evolution of the enrollment +protocol developed by Verisign, Inc. for Cisco Systems, Inc. +It now enjoys wide support in both client and CA implementations. + + +Table of Contents + + 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . 2 + 2. The Goal of SCEP . . . . . . . . . . . . . . . . . . . . . 3 + 2.1 SCEP Entity types . . . . . . . . . . . . . . . . . . . . 3 + 2.2 SCEP Operations Overview . . . . . . . . . . . . . . . . . 7 + 2.3 PKI Operation Transactional Behavior . . . . . . . . . . . 10 + 2.4 Security . . . . . . . . . . . . . . . . . . . . . . . . . 12 + 3. Transport Protocol . . . . . . . . . . . . . . . . . . . . 13 + 4. Secure Transportation: PKCS #7 . . . . . . . . . . . . . . 14 + 4.1 SCEP Message Format . . . . . . . . . . . . . . . . . . . 14 + + Liu/Madson/McGrew/Nourse [Page 2] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + 4.2 Signed Transaction Attributes . . . . . . . . . . . . . . 15 + 5. SCEP Transaction Specification . . . . . . . . . . . . . . 16 + 5.1 Certificate Enrollment . . . . . . . . . . . . . . . . . . 16 + 5.2 Poll for Requester Initial Certificate . . . . . . . . . . 22 + 5.3 Certificate Access . . . . . . . . . . . . . . . . . . . . 26 + 5.4 CRL Access . . . . . . . . . . . . . . . . . . . . . . . 27 + 5.5 Get Certificate Authority Certificate . . . . . . . . . . 31 + 5.6 Get Certificate Authority Certificate Chain . . . . . . . 33 + 6. Security Considerations . . . . . . . . . . . . . . . . . 33 + 7. Intellectual Propoerty . . . . . . . . . . . . . . . . . . 33 + 8. References . . . . . . . . . . . . . . . . . . . . . . . . 33 + Appendix A. Cisco Requester Subject Name Definition . . . . . . 34 + Appendix B. IPSEC Client Enrollment Certificate Request . . . . 35 + Appendix C. Private OID Definitions . . . . . . . . . . . . . 36 + Appendix D. Obtaining CRL by LDAP Query . . . . . . . . . . . . 36 + Appendix E. SCEP State Transitions . . . . . . . . . . . . . . 37 + Appendix F. CA Capabilities . . . . . . . . . . . . . . . . . . 40 + Appendix G. Certificate Renewal and CA Key Rollover . . . . . . 41 + Appendix H. PKIOperation via HTTP POST Message. . . . . . . . . 42 + Appendix Y. Author Contact Information. . . . . . . . . . . . . 43 + Appendix Z. Copyright Section . . . . . . . . . . . . . . . . . 43 + +Section 1. Introduction + +Public key technology is becoming more widely deployed and is becoming +the basis for standards based security, such as the Internet Engineering +Task Force's IPSEC and IKE protocols. With the use of public key +certificates in network security protocols comes the need for a +certificate management protocol that Public Key Infrastructure (PKI) +clients and Certificate Authority servers can use to support certificate +life cycle operations such as certificate enrollment and revocation, and +certificate and CRL access. + +In the following, Section 2 gives an overview of the PKI operations, +and Section 2.4 describes the security goals of the protocol and the +mechanisms used to achieve them. The transport protocol and the +security protocol PKCS#7 are described at Section 3 and Section 4, +respectively. The last section, Section 5, specifies each PKI +operation in terms of the message formats and the data structures of +each operation. + +The appendices provide detailed specifications and examples. Requester +subject names are specified in Appendix A, attribute OIDs are +specified in Appendix C , and the SCEP state transitions are described +in Appendix E. An example of a certificate enrollment request is +provided in Appendix B, and an example LDAP query URL encoding is +provided in Appendix D. + +The authors would like to thank Peter William of ValiCert, Inc. +(formerly of Verisign, Inc) and Alex Deacon of Verisign, Inc. and +Christopher Welles of IRE, Inc. for their contributions to this protocol +and to this document. + + Liu/Madson/McGrew/Nourse [Page 3] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +2.0 The Goal of SCEP +The goal of SCEP is to support the secure issuance of certificates to +network devices in a scalable manner, using existing technology whenever +possible. The protocol supports the following operations: + + CA and RA public key distribution + Certificate enrollment + Certificate revocation + Certificate query + CRL query + +Certificate and CRL access can be achieved by using the LDAP protocol +(as specified in Appendix D), or by using the query messages defined in +SCEP. The use of HTTP certificate and CRL access, and the support of +CDP as specified in RFC2459, will be specified in a future version of +this document. In Section 2.1, we first define PKI entity types as well +as the properties of each entity type. In Section 2.2, the PKI +operations are described at functional level. Section 2.3 describes the +transaction behavior of each PKI operations. The complete PKI messages +are covered in Section 5. + +2.1 SCEP Entity types + +The entity types defined in SCEP are the "requester" type (i.e., IPSEC +clients), the Certificate Authority (CA) entity type, and the +Registration Authority entity type (RA). A requester is sometimes +called a "SCEP client" in the following. + +2.1.1 Requesters + +A requester is an entity whose name is defined in a certificate +subject name field and optionally, in SubjectAltName, a X.509 +certificate V3 extension. As a requester, a SCEP client is identified +by a subject name consisting of the following naming attributes: + + Fully qualified domain name, for example, router.cisco.com + IP address, Serial number, and/or x.500 distinguished name + +The fully qualified domain name is required for a requester that intends +to use the certificate for ISAKMP. The IP address, serial number, and +x.500 distinguished name are optional name attributes. In the +certificate enrollment request, the PKCS#10 subject field contains the +required and optional name attributes. The distinguished name, if any, +should be the subject name field, while any domain name, serial number, +or IP address supplied should be in the subjectAltName field. The +subject name field may be empty (if there is no distinguished name) +or the subjectAltName may be omitted, but not both. + +It is important to note that a client named as Alice.cisco.com is +different than a client named as Alice.cisco.com plus the IP address +name attribute 117.96.1.219. From CA point of view, the Distinguished +names assigned in these two cases are distinct names. + + + Liu/Madson/McGrew/Nourse [Page 4] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Entity names which are specified as in the IPSEC profile (i.e., FQDN, IP +address and User FQDN) must be presented in certificate's SubjectAltName +extension. Multiple IPSEC entity names, (if any) are encoded as multiple +values of a single SubjectAltName extension. The CA has the authority +to assign a distinguished name to a requester, whether or not one was +included in the request. The assigned DN should contain the SCEP client +names as the relative DN. + +The attribute identifiers and an example of SCEP client subject name are +specified in Appendix A. Appendix B has an example from Cisco VPN Client +enrollment request. + +2.1.1.1 Local Key/Certificate/CRL Storage and Certificate-name uniqueness + +A requester is required to generate asymmetric key pairs and to provide +storage to store its private keys. If the requester does not have enough +permanent memory to save its certificate, then it should be able to query +its own certificate from the CA or an LDAP server, once the certificate +has been issued. The public key pairs can be generated with a specific +key usage. The key usage is conveyed to the CA through the certificate +enrollment request. All current SCEP client implementations expect that +there will be only one pair of keys for a given subject name +and key usage combination and CA, at any time. This property is called +the certificate-name uniqueness property, and it implies that a CA that +implements SCEP will enforce the unique mapping between a SCEP client +subject name and its key pairs with a given key usage. At any time, if +the subject name is changed, or if the key is updated, the existing +certificate would have to be revoked before a new one could be issued. + +It is desirable that the CA enforce certificate-name uniqueness, but +it is not mandatory. However a CA that does not enforce uniqueness +must provide some other mechanism to prevent the re-transmission of an +enrollment request by a SCEP client from creating a second certificate +or certificate request, nor can the second request merely be rejected. +If a client times out from polling for a pending request it can +resynchronize by reissuing the original request with the original +subject name, key, and transaction ID. This should return the status of +the original transaction, including the certificate if it was granted. +It should not create a new transaction unless the original cert has been +revoked, or the transaction arrives more than halfway through the +validity time of the original certificate. + +An enrollment request that occurs more than halfway through the validity +time of an existing certificate for the same subject name and key usage +MAY be interpreted as a re-enrollment or renewal request and accepted. +A new certificate with new validity dates may be issued, even though +the old one is still valid, if the CA policy permits, as described in +2.1.1.3. See also appendix G. + +2.1.1.2 Requester authentication + +As with every protocol that uses public-key cryptography, the +association between the public keys used in the protocol and the +identities with which they are associated must be authenticated in a + Liu/Madson/McGrew/Nourse [Page 5] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +cryptographically secure manner. This requirement is needed to +prevent a "man in the middle" attack, in which an adversary that can +manipulate the data as it travels between the protocol participants +can subvert the security of the protocol. To satisfy this +requirement, SCEP provides two authentication methods: manual +authentication, and authentication based on pre-shared secret. In the +manual mode, the requester is required to wait until its identity can +be verified by the CA operator using any reliable out-of-band +method. To prevent a "man-in-the-middle" attack, a SHA-1 or MD5 +`fingerprint' generated on the PKCS#10 (before PKCS #7 enveloping and +signing) must be compared out-of-band between the server and the +requester. SCEP clients and CAs (or RAs, if appropriate) must display +this fingerprint to the operator to enable this verification if manual +mode is used. Failing to provide this information leaves the protocol +vulnerable to attack by sophisticated adversaries. When utilizing a +pre-shared secret scheme, the server should distribute a shared secret +to the requester which can uniquely associate the enrollment request +with the given end entity. The distribution of the secret must be +private: only the end entity should know this secret. The actual +binding mechanism between the requester and the secret is subject to +the server policy and implementation. When creating the enrollment +request, the requester is asked to provide a challenge password. When +using the pre-shared secret scheme, the requester must enter the +re-distributed secret as the password. In the manual authentication +case, the challenge password only used to authenticate a request for +the certificate's revokation. This challenge password is included as +a PKCS#10 attribute, and is sent to the server as encrypted data. The +PKCS#7 envelope protects the privacy of the challenge password with +DES encryption. + +2.1.1.3 Requester Uses Existing CA-Issued or Self-Signed Certificates + +In this protocol, the communication between the requester and the +certificate authority is secured by using PKCS#7 as the messaging +protocol. PKCS#7, however, is a protocol which assumes the +communicating entities already possess the peer's certificates and +requires both parties use the issuer names and issuer assigned +certificate serial numbers to identify the certificate in order to +verify the signature and decrypt the message. If the requesting +system already has a certificate issued by the CA, that certificate +may be presented as credentials for the renewal of that certificate if +the CA supports the "Renewal" capability and the CA policy permits the +certificate to be renewed. If the requester has no certificate issued +by the CA, or if the CA does not support and permit renewal, the +requestor must generate a self-signed certificate with the requester +subject name (the same name later used in the PKCS#10) as both issuer +and subject name. During the certificate enrollment, the requester +will first post itself as the signing authority by attaching the +self-signed certificate to the signed certificate request. When the +Certificate Authority makes the envelope on the issued certificate +using the public key included in the self-signed certificate, it +should use the same issuer name and serial number as conveyed in the +self-signed certificate to inform the end entity on which private key +should be used to open the envelope. + Liu/Madson/McGrew/Nourse [Page 6] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Note that when a client enrolls for separate encryption and signature +certificates, it may use the signature certificate to sign both +requests, and then expect its signature key to be used to encrypt +both responses. In any case, the recipientinfo on the envelope should +reflect the key used to encrypt the request. + +2.1.1.4 Trusted CA Store + +To support interoperability between IPSEC peers whose certificates are +issued by different CA, SCEP allows the users to configure multiple +trusted certificates. Trusted certificates are have been configured as +such in the client, based on some out-of-band means such as a "fingerprint". +These trusted certificates are used to verify certificate chains that end +in those certificates. + +2.1.2 Certificate Authority + +A Certificate Authority(CA) is an entity whose name is defined in the +certificate issuer name field. Before any PKI operations can begin, +the CA generates its own public key pair and creates a self-signed CA +certificate, or causes another CA to issue a certificate to it. +Associated with the CA certificate is a fingerprint which will be used +by the requester to authenticate the received CA certificate if it is +self-signed. The fingerprint is created by calculating a SHA-1 or MD5 +hash on the whole CA certificate. Before any requester can start its +enrollment, this CA certificate has to be configured at the entity +side securely. For IPSEC clients, the client certificates must have +SubjectAltName extension. To utilize LDAP as a CRL query protocol, +the certificates must have a CRL Distribution Point. Key usage is +optional. Without key usage, the public key is assumed as a general +purpose public key and it can be used for all the purposes. + +A Certificate Authority may enforce certain name policy. When using +X.500 directory name as the subject name, all the name attributes +specified in the PKCS#10 request should be included as Relative DN. All +the name attributes as defined in RFC2459 should be specified in the +SubjectAltName. An example is provided in Appendix A. + + If there is no LDAP query protocol support, the Certificate Authority +should answer certificate and CRL queries, and to this end it should be +online all the time. + +The updating of the CA's public key is addressed in Appendix G. + +2.1.3 Registration Authorities + +In an environment where an RA is present, a requester performs +enrollment through the RA. In order to setup a secure channel with an RA +using PKCS#7, the RA certificate(s) have to be obtained by the client +in addition to the CA certificate(s). + +In the following, the CA and RA are specified as one entity in the +context of PKI operation definitions. + Liu/Madson/McGrew/Nourse [Page 7] +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 +2.2 SCEP Operations Overview + +In this section, we give a high level overview of the PKI operations as +defined in SCEP. + +2.2.1 Requester Initialization + +The requester initialization includes the key pair generation and the +configuring of the required information to communicate with the +certificate authority. + +2.2.1.1 Key Pairs + +Before a requester can start PKI transaction, it must have at least one +asymmetric key pair, using the selected algorithm (the RSA algorithm is +required in SCEP, and is the only algorithm in current implementations). + +Key pairs may be intended for particular purposes, such as encryption only, +or signing only. The usage of any associated certificate can be restricted +by adding key usage and extended key usage attributes to the PKCS#10. + +2.2.1.2 Required Information + +A requester is required to have the following information configured +before starting any PKI operations: + +1. the certificate authority IP address or fully-qualified domain name, +2. the certificate authority HTTP CGI script path, and + the HTTP proxy information in case there is no direct Internet + connection to the server, +3. If CRLs are being published by the CA to an LDAP directory server, + and there is a CRL Distribution Point containing only an X.500 directory + name, then the client will need to know the LDAP server fully-qualified + domain name or IP address. CRL Distribution Points are discussed in + more detail in RFC 2459. + + +2.2.2 CA/RA Certificate Distribution + +Before any PKI operation can be started, the requester needs to get +the CA/RA certificates. At this time, since no public key has been + + Liu/Madson/McGrew/Nourse [Page 8] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +exchanged between the requester and the CA/RA, the message to get the +CA/RA certificate can not be secured using PKCS#7 protocol. Instead, the +CA/RA certificate distribution is implemented as a clear HTTP Get +operation. After the requester gets the CA certificate, it has to +authenticate the CA certificate by comparing the finger print with the +CA/RA operator. Since the RA certificates are signed by the CA, there is +no need to authenticate the RA certificates. + +This operation is defined as a transaction consisting of one HTTP Get +message and one HTTP Response message: + + REQUESTER CA SERVER + Get CA/RA Cert: HTTP Get message + -----------------------------> + CA/RA Cert download: HTTP Response message + <--------------------------------------- + Compute finger print and + call CA operator. + Receive call and check finger print + +If an RA is in use, a degenerated PKCS#7 with a certificate chain +consisting of both RA and CA certificates is sent back to the end +entity. Otherwise the CA certificate is directly sent back as the +HTTP response payload. + + +2.2.3 Certificate Enrollment + +A requester starts an enrollment transaction by creating a certificate +request using PKCS#10 and sends it to the CA/RA enveloped using the +PKCS#7. After the CA/RA receives the request, it will either +automatically approve the request and send the certificate back, or it +will require the requester to wait until the operator can manually +authenticate the identity of the requester. Two attributes are +included in the PKCS#10 certificate request - a Challenge Password +attribute and an optional ExtensionReq attribute which will be a +sequence of extensions the requester would like to be included in its +V3 certificate extensions. The Challenge Password may be used to +authenticate either the enrollment request itself, or a verbal +revocation request for the issued certificate in the event of key +compromise or other reason. + +In the automatic mode, the transaction consists of one PKCSReq PKI +Message, and one CertRep PKI message. In the manual mode, the requester +enters into polling mode by periodically sending a GetCertInitial PKI +message to the server, until the server operator completes the manual +authentication, after which the CA will respond to GetCertInitial by +returning the issued certificate. A CA MAY run in automatic mode for +preapproved requests, and manual mode for the rest. A request with a +non-null password is not necessarily a pre-approved request. It is up +to the CA server to decide. Polling mode is entered whenever the +server returns a PENDING response. + + Liu/Madson/McGrew/Nourse [Page 9] +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + +The transaction in automatic mode: + + REQUESTER CA SERVER + +PKCSReq: PKI cert. enrollment msg + --------------------------------> CertRep: pkiStatus = SUCCESS + certificate attached + <------------------------------ + Receive issued certificate. + +The transaction in manual mode: + + REQUESTER CA SERVER + PKCSReq: PKI cert. enrollment msg + --------------------------------> CertRep: pkiStatus = PENDING + <------------------------------ + GetCertInitial: polling msg + --------------------------------> CertRep: pkiStatus = PENDING + <------------------------------ + ................. CertRep: pkiStatus = SUCCESS + certificate attached + <------------------------------ + Receive issued certificate. + +2.2.4 Requester Certificate Revocation + +A requester should be able to revoke its own certificate. Currently +the revocation is implemented as a manual process. In order to revoke a +certificate, the requester makes a phone call to the CA server +operator. The operator will come back asking the ChallengePassword +(which has been sent to the server as an attribute of the PKCS#10 +certificate request). If the ChallengePassword matches, the certificate +is revoked. The reason of the revocation is documented by CA/RA. + +2.2.5 Certificate Access + +There are two methods to query certificates. The first method is to use +LDAP as a query protocol. Using LDAP to query assumes the client +understand the LDAP scheme supported by the CA. The SCEP client assumes +that the subject DN name in the certificate is used as the URL to query the +certificate. The standard attributes (userCertificate and caCertificate) +are used as filter. + +For the environment where LDAP is not available, a certificate query +message is defined to retrieve the certificates from the CA. + +To query a certificate from the certificate authority, a requester +sends a request consisting of the certificate's issuer name and the +serial number. This assumes that the requester has saved the issuer + + Liu/Madson/McGrew/Nourse [Page 10] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +name and the serial number of the issued certificate from the previous +enrollment transaction. The transaction to query a certificate consists +of one GetCert PKI message and one CertRep PKI message: + + REQUESTER CA SERVER + GetCert: PKI cert query msg + -------------------------------> CertRep: pkiStatus = SUCCESS + certificate +attached + <----------------------------- + Receive the certificate. + +2.2.6 CRL Distribution + +The CA/RA will not "push" the CRL to the end entities. The query of the +CRL can only be initialized by the requester. + +There are three methods to query CRL. + +The CRL may be retrieved by a simple HTTP GET. If the CA supports this +method, it should encode the URL into a CRL Distribution Point extension +in the certificates it issues. Support for this method should be +incorporated in new and updated clients, but may not be in older +versions. + +The second method is to query CRL using LDAP. This assumes the CA server +supports CRL LDAP publishing and issues the CRL Distribution Point in +the certificate. The CRL Distribution Point is encoded as a DN. Please +refer to Appendix D for the examples of CRL Distribution Point. + +The third method is implemented for the CA which does not support LDAP +CRL publishing or does not implement the CRL Distribution Point. In this +case, a CRL query is composed by creating a message consists of the CA +issuer name and the CA's certificate serial number. This method is +deprecated because it does not scale well and requires the CA to be a +high-availability service. + +The message is sent to the CA in the same way as the other SCEP +requests: The transaction to query CRL consists of one GetCRL PKI +message and one CertRep PKI message which have no certificates but CRL. + + REQUESTER CA SERVER + GetCRL: PKI CRL query msg + ----------------------------------> CertRep: CRL attached + <-------------------------------- + +2.3 PKI Operation Transactional Behavior + +As described before, a PKI operation is a transaction consisting of the +messages exchanged between a requester and the CA/RA. This section +will specify the transaction behavior on both the requester and the + + + Liu/Madson/McGrew/Nourse [Page 11] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +certificate authority server. Because the protocol is basically a two +way communication protocol without a confirmation message from the +initiating side, state and state resynchronization rules have to be +defined, in case any error happens at either side. Before the state +transition can be defined, the notion of transaction identifier has to +be defined first. + +2.3.1 Transaction Identifier + +A transaction identifier is a string generated by the entity when +starting a transaction. Since all the PKI operations defined in this +protocol are initiated by the requester, it is the responsibility of +the requester to generate a unique string as the transaction +identifier. All the PKI messages exchanged for a given PKI transaction +must carry the same transaction identifier. The transaction identifier +is generated as a SHA-1 or MD5 hash on the public key value for which the +enrollment request is made. This allows the SCEP client to reuse the +same transaction identifier if it is reissuing a request for the same +certificate (i.e. a certificate with the same subject, issuer, and key). +The SCEP protocol requires that transaction identifiers be unique, so +that queries can be matched up with transactions. For this reason, in +those cases in which separate signing and encryption certificates are +issued to the same requester, the keys must be different. + +2.3.2 State Transitions in Certificate Enrollment + +The requester state transitions during enrollment operation are +indicated in the diagram below: + +-<------+ + | | + GetCertInitial triggered by timeout or + | | manual authentication + | | + [CERT-NONEXISTANT] ------> [CERT-REQ-PENDING] ---> [CERT-ISSUED] + | PKCSReq | CertRep with SUCCESS + | | + | | + +--------<-------------------+ + request rejected, timeout, or error + +As described in the section 2.2.3, certificate enrollment starts at the +state CERT-NONEXISTANT. Sending PKCSReq changes the state to +CERT-REQ-PENDING. Receiving CertRep with SUCCESS status changes the +state to CERT-ISSUED. In the case the server sending back the response +with pending status, the requester will keep polling certificate +response by sending GetCertInitial to the server, until either a CertRep +with SUCCESS status is received, or the maximum polling number has been +exceeded. + +If an error or timeout occurs in the CERT-REQ-PENDING state, the end +entity will transition to the CERT-NONEXISTANT state. + + + Liu/Madson/McGrew/Nourse [Page 12] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + +The client administrator will, eventually, start up another enrollment +request. It is important to note that, as long as the requester does +not change its subject name or keys, the same transaction id will be +used in the "new" transaction. This is important because based on this +transaction id, the certificate authority server can recognize this as +an existing transaction instead of a new one. + + +2.3.3 Transaction Behavior of Certificate/CRL Access + +There is no state maintained during certificate access and CRL access +transaction. When using the certificate query and CRL query messages +defined in this protocol, the transaction identifier is still required +so that the requester can match the response message with the +upstanding request message. When using LDAP to query the certificate and +the CRL, the behavior is specified by the LDAP protocol. + +2.4 Security + +The security goals of SCEP are that no adversary can: + +o subvert the public key/identity binding from that intended, +o discover the identity information in the enrollment requests and + issued certificates, +o cause the revocation of certificates with any non-negligible + probability. + +Here an adversary is any entity other than the requester and the CA +(and optionally the RA) participating in the protocol that is +computationally limited, but that can manipulate data during +transmission (that is, a man-in-the-middle). The precise meaning of +'computationally limited' depends on the implementer's choice of +cryptographic hash functions and ciphers. The required algorithms are +RSA, DES, and either SHA-1 or MD5, depending on the "SHA-1" CA Capability. +[See Appendix F]. + +The first and second goals are met through the use of PKCS#7 and PKCS#10 +encryption and digital signatures using authenticated public keys. The +CA's public key is authenticated via the checking of the CA fingerprint, +as specified in Section 2.1.2, and the SCEP client's public key is +authenticated through the manual authentication or pre-shared secret +authentication, as specified in Section 2.1.1.2. The third goal is met +through the use of a Challenge Password for revocation, that is chosen +by the SCEP client and communicated to the CA protected by the PKCS#7 +encryption, as specified in Section 2.2.4. + +The motivation of the first security goal is straightforward. The +motivation for the second security goal is to protect the identity +information in the enrollment requests and certificates. For example, +two IPSEC hosts behind a firewall may need to exchange certificates, and +may need to enroll certificates with a CA that is outside of a firewall. +Most networks with firewalls seek to prevent IP addresses and DNS + + Liu/Madson/McGrew/Nourse [Page 13] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +information from the trusted network leaving that network. The second +goal enables the hosts in this example to enroll with a CA outside the +firewall without revealing this information. The motivation for the +third security goal is to protect the SCEP clients from denial of +service attacks. + +Section 3 Transport Protocol + +In the SCEP protocol, HTTP is used as the transport protocol for the PKI +messages. + +3.1 HTTP "GET" and "POST" Message Format + +The following is the syntax definition of a HTTP GET message sent from +a requester to a certificate authority server: + +Request = "GET " CGI-PATH CGI-PROG "?operation=" OPERATION "&message=" MESSAGE +where: + CGI-PATH defines the actual CGI path to invoke the CGI program which + parses the request. + CGI-PROG is set to be the string "pkiclient.exe". This is intended + to be the program that the CA will use to handle the SCEP transactions, + though the CA may ignore CGI-PROG and use only the CGI-PATH. + OPERATION is set to be the string "PKIOperation" when the GET message + carries a PKI message to request certificates or CRL; OPERATION is set + to be the string "GetCACaps", "GetCACert", "GetNextCACert" or + "GetCACertChain" when the GET operation is used to get CA capabilities, + CA/RA certificate, the replacement CA/RA certificates for when the + current ones expire, or the CA Cert chain (respectively). + + When OPERATION is "PKIOperation", MESSAGE is a base64-encoded PKI message, + When OPERATION is GetCACert, MESSAGE is a CRL distribution + point in URI format, otherwise, MESSAGE is a string which represents + the certificate authority issuer identifier. + +SCEP uses the HTTP "GET" and "POST" messages to request information from the CA. +Requests for CA certificates or capabilities are sent in the clear, using "GET", +with the OPERATION and MESSAGE fields identifying the requested data. +CRLs may also be requested in the clear if the CA supports it. + +Other types of requests are sent using the PKCS#7 secure protocol. +These may be issued by means of a GET operation with +OPERATION and MESSAGE parameters in the Request-URL. OPERATION +identifies the type of GET operation, and MESSAGE is actually the PKCS#7 +message Base64-Encoded. + +For example. a requester may submit a message via HTTP to the server +as follows: + +GET /cgi-bin/pkiclient.exe?operation=PKIOperation&message=MIAGCSqGSIb3D +QEHA6CAMIACAQAxgDCBzAIBADB2MGIxETAPBgNVBAcTCE ......AAAAAA== + Liu/Madson/McGrew/Nourse [Page 13a] + +If supported by the CA, the message may also be sent via HTTP POST: + +POST /cgi-bin/pkiclient.exe?operation=PKIOperation + +This is further described in Appendix H. +To determine if the CA supports POST, use the GetCACaps message described +in Appendix F. + + +3.2 Response Message Format + +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. The following is an +example of the response: + +"Content-Type:application/x-pki-message\n\n" + +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. the body of the response is a DER encoded +binary X.509 certificate. For example: + +"Content-Type:application/x-x509-ca-cert\n\n" + +If there is an RA, the RA certificates are sent back together with the +CA certificates, a certificate-only PKCS#7 SignedData is sent back in +the response where the SignerInfo is empty. Section 5 has the detailed +definition of the message format in this case. The content type is +application/x-x509-ca-ra-cert. + +The response to GetNextCACert is always a certificates-only PKCS#7 +SignedData with a content type of application/x-x509-ca-ra-cert. +If there is an RA, The signer is the current RA certificate. Otherwise, +the signer is the current CA certificate. + +If the CA supports it, PKIOperation may also be done via an HTTP POST. +This is described in Appendix H. + + Liu/Madson/McGrew/Nourse [Page 14] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Section 4 Secure Transportation: PKCS#7 + +PKCS#7 is a general enveloping mechanism that enables both signed and +encrypted transmission of arbitrary data. It is widely implemented and +included in the RSA tool kit. In this section, the general PKCS#7 +enveloped PKI message format is specified. The complete PKCS#7 message +format for each PKI transaction will be covered in Section 5. + +4.1 SCEP Message Format + +As a transaction message, a SCEP message has a set of transaction +specific attributes and an information portion. Employing PKCS#7 +protocol, the transaction specific attributes are encoded as a set of +authenticated attributes of the SignedData. The information portion will +first be encrypted to become Enveloped Data, and then the digest of the +enveloped information portion is included as one of the message digest +attributes and being signed together with the other transaction specific +attributes. + +By applying both enveloping and signing transformations, a SCEP message +is protected both for the integrity of its end-end-transition +information and the confidentiality of its information portion. The +advantage of this technique over the conventional transaction message +format is that, the signed transaction type information and the status +of the transaction can be determined prior to invoke security handling +procedures specific to the information portion being processed. + +The following is an example of a SCEP message with its enveloped and +signed data portion represented by pkcsPKISigned and +pkcsPKIEnveloped. The out-most of any PKI message is a blob of +ContentInfo, with its content type set to SignedData and the actual +signed data as the content. + + Liu/Madson/McGrew/Nourse [Page 15] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + pkiMessage ContentInfo ::= { + contentType {pkcs-7 signedData(2)} + content pkcsPKISigned + } + pkcsPKISigned SignedData ::= { + version 1 + digestAlgorithm { iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} -- data content identifier + content pkcsPKIEnvelope -- enveloped information portion + } + certificates -- signer certificate chain + signerInfo -- including signed transaction info and the digest + -- of the enveloped information portion as the + -- authenticated attributes + } + pkcsPKIEnveloped EnvelopedData ::= { + version 0 + recipientInfos -- information required to open the envelop + encryptedContentInfo { + contentType {pkcs-7 1} -- data content identifier + contentEncryptionAlgorithm + encryptedContent -- encrypted information portion + } + } + +4.2 Signed Transaction Attributes + +The following transaction attributes are encoded as authenticated +attributes. Please refer to Appendix B for the OID definitions. + +transactionID PrintableString -- Decimal value as a string + messageType PrintableString -- Decimal value as a string + pkiStatus PrintableString -- Decimal value as a string + failinfo PrintableString -- Decimal value as a string + senderNonce Octet String + recipientNonce Octet String + +where: + + The transactionID is an attribute which uniquely identify a + transaction. This attribute is required in all PKI messages. + + The messageType attribute specify the type of operation performed by the + transaction. This attribute is required in all PKI + messages. Currently, the following message types are defined: + + PKCSReq (19) -- Permits use of PKCS#10 certificate request + CertRep (3) -- Response to certificate or CRL request + GetCertInitial (20) -- Certificate polling in manual enrollment + GetCert (21) -- Retrieve a certificate + GetCRL (22) -- Retrieve a CRL + + Liu/Madson/McGrew/Nourse [Page 16] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + + All response message will include transaction status information which + is defined as pkiStatus attribute: + + SUCCESS (0) -- request granted + FAILURE (2) -- request rejected + PENDING (3) -- request pending for manual approval. + + If the status in the response is FAILURE, the failinfo attribute will + contain one of the following failure reasons: + + badAlg (0) -- Unrecognized or unsupported algorithm ident + badMessageCheck (1) -- integrity check failed + badRequest (2) -- transaction not permitted or supported + badTime (3) -- Message time field was not sufficiently close + to the system time + badCertId (4) -- No certificate could be identified matching + the provided criteria + + The attributes of senderNonce and recipientNonce are the 16 byte + random numbers generated for each transaction to prevent the replay + attack. + +When a requester sends a PKI message to the server, a senderNonce is +included in the message. After the server processes the request, it will +send back the requester senderNonce as the recipientNonce and generates +another nonce as the senderNonce in the response message. Because the +proposed pki protocol is a two-way communication protocol, it is clear +that the nonce can only be used by the requester to prevent the +replay. The server has to employ extra state related information to +prevent a replay attack. + +Section 5. SCEP Transaction Specification + +In this section each SCEP transaction is specified in terms of the +complete messages exchanged during the transaction. + +5.1 Certificate Enrollment + +The certificate enrollment transaction consists of one PKCSReq message +sent to the certificate authority from a requester, and one CertRep +message sent back from the server. The pkiStatus returned in the +response message is either SUCCESS, or FAILURE, or PENDING. The +information portion of a PKCSReq message is a PKCS#10 certificate +request, which contains the subject Distinguished Name, the subject +public key, and two attributes, a ChallengePassword attribute to be used +for revocation, and an optional ExtensionReq attribute which will be a +sequence of extensions the requester expects to be included in its V3 +certificate extensions. One of the extension attribute specifies the key +usage. If the request is granted, the pkiStatus is set to SUCCESS, and +the certificate is returned in CertRep; if the request is rejected, the + + + Liu/Madson/McGrew/Nourse [Page 17] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +pkiStatus is set to FAILURE; if the server requires manual approval of +the request, the pkiStatus is set to PENDING. The messages exchanged +in the manual authentication mode is further specified in Section 5.2. + +Precondition: + Both the requester and the certificate authority have completed their + initialization process. The requester has already been configured + with the CA/RA certificate. + +Postcondition: + Either the certificate is received by the requester, or the end + entity is notified to do the manual authentication, or the request + is rejected. + +5.1.1 PKCSReq Message Format + +A PKCSReq message is created by following the steps defined below: + +1. Create a PKCS#10 certificate request which is signed by the end + entity's private key, corresponding to the public key included in + the PKCS#10 certificate request. This constitutes the information + portion of PKCSReq. + +2. Encrypt the PKCS#10 certificate request using a randomly generated + content-encryption key. This content-encryption key is then + encrypted by the CA's* public key and included in the recipientInfo. + This step completes the "envelope" for the PKCS#10 certificate + request. + +3. Generate a unique string as the transaction id. + +4. Generate a 16 byte random number as senderNonce. + +5. Generate message digest on the enveloped PKCS#10 certificate request + using the selected digest algorithm. + +6. Create SignedData by adding the requester's self- or CA-certificate + as the signer's public key certificate. Include the message type, + transaction id, the senderNonce and the message digest as the + authenticated attributes and sign the attributes using the end + entity's private key. This completes the SignedData. + +7. The SignedData is prepended with the ContenInfo blob which indicates + a SignedData object. This final step completes the create of a + complete PKCSReq PKI message. + +In the following, the PKCSReq message is defined following the ASN.1 +notation. + +For readability, the values of a field is either represented by a quoted +string which specifies the intended value, or a constant when the value +is known. + + + Liu/Madson/McGrew/Nourse [Page 18] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + -- PKCSReq information portion + pkcsCertReq CertificationRequest ::= { -- PKCS#10 + version 0 + subject "the requester's subject name" + subjectPublicKeyInfo { + algorithm {pkcs-1 1} -- rsa encryption + subjectPublicKey "DER encoding of the requester's public key" + } + attributes { + challengePassword {{pkcs-9 7} "password string" } + extensions + } + signatureAlgorithm {pkcs-1 4} -- MD5WithRSAEncryption + signature "bit string which is created by signing inner content + of the defined pkcsCertReq using requester's private + key, corresponding to the public key included in + subjectPublicKeyInfo." + } + -- Enveloped information portion + pkcsCertReqEnvelope EnvelopeData ::= { -- PKCS#7 + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the CA issuer name" + serialNumber "the CA certificate serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} -- rsa encryption + encryptedKey "content-encryption key + encrypted by CA public key" + } + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "object identifier + for DES encryption" + encryptedContent "encrypted pkcsCertReq using the content- + encryption key" + } + } + -- Signed PKCSReq + pkcsCertReqSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} -- data content identifier + content pkcsCertReqEnvelope + } + certificate { -- requester self-signed or CA-issued certificate + version 3 + serialNumber "the transaction id associated with enrollment" + signature {pkcs-1 4} -- md5WithRSAEncryption + + + Liu/Madson/McGrew/Nourse [Page 19] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + issuer " the requester's subject name" + validity { + notBefore "a UTC time" + notAfter "a UTC time" + } + subject "the requester's subject name" + subjectPublicKeyInfo { + algorithm {pkcs-1 1} + subjectPublicKey "DER encoding of requester's public key" + } + signatureAlgorithm {pkcs-1 4} + signature "the signature generated by using the requester's + private key corresponding to the public key in + this certificate." + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the requester's subject name" + serialNumber "the transaction id associated + with the enrollment" + } + digestAlgorithm {iso(0) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "an octet string"} + transaction-id {{id-attributes transId(7)} "printable + string"} + -- this transaction id will be used + -- together with the subject name as + -- the identifier of the requester's key + -- pair during enrollment + messageType {{id-attributes messageType(2)} "PKCSReq"} + senderNonce {{id-attributes senderNonce(5)} + "a random number encoded as a string"} + } + digestEncryptionAlgorithm {pkcs-1 1} -- rsa encryption + encryptedDigest "encrypted digest of the authenticated + attributes using requester's private key" + } + } + pkcsReq PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsCertRepSigned + } + + + + + + + + + Liu/Madson/McGrew/Nourse [Page 20] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +5.1.2 CertRep Message Format + +The response to an SCEP enrollment request is a CertRep message. + +5.1.2.1 PENDING Response + +When the CA is configured to manually authenticate the requester, +the CertRep is returned with the attribute pkiStatus set to PENDING. +The data portion for this message is null. Only the transaction +required attributes are sent back. + +CertRepSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo {contentType {pkcs-7 1} -- empty content + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "name of CA that issued the CA [RA] cert" + serialNumber "the serial number of the CA [RA] cert" + } + digestAlgorithm (iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} NULL} + messageType {{id-attribute messageType(0)} "CertRep"} + transaction-id {{id-attributes transid(7)} "printablestring"} + --- same transaction id used in PKCSReq + pkiStatus {{id-attributes pkiStatus(3)} "PENDING"} + recipientNonce {{id-attributes recipientNonce(6)}<16 bytes>} + senderNonce {{id-attributes senderNonce(5)} <16 bytes>} + } + digestEncrytionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted message digest of the authenticated + attributes using the CA's [RA's] private key" + } +} +CertRep PKIMessage ::= { + contentType {pkcs-7 2} + content CertRepSigned +} + +5.1.2.2 Failure Response + +In this case, the CertRep sent back to the requester is same as in +the PENDING case, except that the pkiStatus attribute is set to FAILURE, +and the failInfo attribute should be included: + + pkistatus {{id-attributes pkiStatus(3)} "FAILURE"} + failInfo {{id-attributes failInfo(4)} "the reason to reject"} + + Liu/Madson/McGrew/Nourse [Page 21] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +5.1.2.3 SUCCESS response + +In this case, the information portion of CertRep will be a degenerated +PKCS#7 which contains the requester's certificate. It is then enveloped +and signed as below: + +pkcsCertRep SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { -- empty content since this is degenerated PKCS#7 + contentType {pkcs-7 1} + } + certificates { + certificate { -- issued requester's certificate // must be first + version 3 + serialNumber "issued requester's certificate serial number" + signature {pkcs-1 4} -- md5WithRSAEncryption + issuer "the certificate authority issuer name" + validity { + notBefore "UTC time" + notAfter "UTC time" + } + subject "the requester subject name as given in PKCS#10" + subjectPublicKeyInfo { + algorithm {pkcs-1 1} + subjectPublicKey "a DER encoding of requester public + key as given in PKCS#10" + } + extensions " the extensions as given in PKCS#10" + signatureAlgorithm {pkcs-1 4} + signature " the certificate authority signature" + } + certificate "the certificate authority certificate" (optional) + certificate "the registration authority certificate(s)" (optional) + } +} +pkcsCertRepEnvelope EnvelopedData ::= { -- PKCS#7 + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { -- use issuer name and serial number as + -- conveyed in requester's self-signed + -- certificate, included in the PKCSReq + issuer "the requester's subject name" + serialNumber "the serial number defined by the requester in + its self-signed certificate" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted by the requester's + public key which is same key as authenticated in + the requester's certificate" + } + + + Liu/Madson/McGrew/Nourse [Page 22] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + encryptedContentInfo { + contentType {pkcs-7 1} -- data content identifier + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted pkcsCertRep using content encryption + key" + } +} +pkcsCertRepSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + content pkcsCertRepEnvelope + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the certificate authority issuer name" + serialNumber "the CA certificate's serial number" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "a octet string"} + messageType {{id-attribute messageType(2)} "CertRep"} + transaction-id {{id-attributes transId(7)} "printable + string"} + -- same transaction id as given in PKCSReq + pkiStatus {{id-attributes pkiStatus(3) "SUCCESS"} + recipientNonce {{id-attribute recipientNonce(6)}<16 bytes>} + senderNonce {{ id-attributes senderNonce(5) <16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticate attributes + using CA's private key " + } +} +CertRep PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsCertRepSigned +} + +5.2 Poll for Requester Initial Certificate + +Either triggered by the PENDING status received from the CertRep, or by +the non-response timeout for the previous PKCSReq, a requester will +enter the polling state by periodically sending GetCertInitial to the +server, until either the request is granted and the certificate is sent +back, or the request is rejected, or the configured time limit for +polling is exceeded. + + + Liu/Madson/McGrew/Nourse [Page 23] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + +Since GetCertInitial is part of the enrollment, the messages exchanged +during the polling period should carry the same transaction identifier +as the previous PKCSReq. + +PreCondition + Either the requester has received a CertRep with pkiStatus set to be + PENDING, or the previous PKCSReq has timed out. + +PostContition + The requester has either received the certificate, or be rejected of + its request, or the polling period ended as a failure. + +5.2.1 GetCertInitial Message Format + +Since at this time the certificate has not been issued, the requester +can only use the requester's subject name, combined with the +transaction identifier, to identify the polled certificate request. + +The certificate authority server must be able to uniquely identify the +polled certificate request. A subject name can have more than one +outstanding certificate request (with different key usage attributes). + +-- Information portion + +pkcsGetCertInitial issuerAndSubject ::= { + issuer "the certificate authority issuer name" + subject "the requester subject name as given in PKCS#10" +} +pkcsGetCertInitialEnvelope EnvelopedData ::= { + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the CA issuer name" + serialNumber "the CA certificate serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted by CA's public key" + } + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted getCertInital" + } +} +pkcsGetCertInitialSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + + + Liu/Madson/McGrew/Nourse [Page 24] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + content pkcsGetCertIntialEnvelope + } + certificate { -- the requester's self-signed certificate + version 3 + serialNumber "the transaction id associated with enrollment" + signature {pkcs-1 4} -- md5WithRSAEncryption + issuer " the requester's subject name" + validity { + notBefore "a UTC time" + notAfter "a UTC time" + } + subject "the requester's subject name" + subjectPublicKeyInfo { + algorithm {pkcs-1 1} + subjectPublicKey "DER encoding of requester's public key" + } + signatureAlgorithm {pkcs-1 4} + signature "the signature generated by using the requester's + private key corresponding to the public key in + this certificate." + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "requester's subject name" + serialNumber "the transaction id used in previous PKCSReq" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "an octet string"} + -- digest of getCertInitial + messageType {{id-attribute messageType(2)} "GetCertInitial"} + transaction-id {{id-attributes transId(7)} "printable + string"} + -- same transaction idused in previous PKCSReq + senderNonce {{id-attribute senderNonce(3)} 0x<16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticateAttributes" + } +} +GetCertInitial PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsGetCertInitialSigned +} + + + +5.2.2 GetCertInitial Response Message Format + +The response messages for GetCertInitial are the same as for PKCSReq. + + Liu/Madson/McGrew/Nourse [Page 25] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +5.3 Certificate Access + +The certificate query message defined in this section is an option when +the LDAP server is not available to provide the certificate query. A +requester should be able to query an issued certificate from the +certificate authority, as long as the issuer name and the issuer +assigned certificate serial number is known to the requesting end +entity. This transaction is not intended to provide the service as a +certificate directory service. A more complicated query mechanism would +have to be defined in order to allow a requester to query a certificate +using various different fields. + +This transaction consists of one GetCert message sent to the server by +a requester, and one CertRep message sent back from the server. + +PreCondition + The queried certificate have been issued by the certificate authority + and the issuer assigned serial number is known. + +PostCondition + Either the certificate is sent back or the request is rejected. + + +5.3.1 GetCert Message Format + +The queried certificate is identified by its issuer name and the issuer +assigned serial number. If this is a query for an arbitrary requester's +certificate, the requesting requester should includes its own CA issued +certificate in the signed envelope. If this is a query for its own +certificate (assume the requester lost the issued certificate, or does +not have enough non-volatile memory to save the certificate), then the +self-signed certificate has to be included in the signed envelope. + + pkcsGetCert issuerAndSerialNumber ::= { + issuer "the certificate issuer name" + serialNumber "the certificate serial number" + } + pkcsGetCertEnvelope EnvelopedData ::= { + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the CA [RA] issuer name" + serialNumber "the CA [RA] certificate serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted + by CA [RA] public key" + } + + + + + + Liu/Madson/McGrew/Nourse [Page 26] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted pkcsGetCert using the content + encryption key" + } + } + pkcsGetCertSigned SignedData ::= { + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + content pkcsGetCertEnvelope + } + certificates { + certificate "CA issued certificate" + or "self-signed certificate" + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the requester's subject name" + serialNumber "requester's certificate serial number" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "an octet string"} + -- digest of pkcsGetCertEnvelope + messageType {{id-attribute messageType(2)} "GetCert"} + transaction-id {{id-attributes transId(7)} "printable + string"} + senderNonce {{id-attribute senderNonce(3)} <16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticateAttributes" + } + } + GetCert PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsGetCertSigned + } + + + + + + + + + + Liu/Madson/McGrew/Nourse [Page 27] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + +5.3.2 CertRep Message Format + +In this case, the CertRep from the server is same as the CertRep for the +PKCSReq, except that the server will only either grant the request or +reject the request. Also, the recipientInfo should use the CA issuer +name and CA assigned serial number to identify the requester's key pair +since at this time, the requester has received its own certificate. + +5.4 CRL Access + +The CRL query message defined in this section is an option when the LDAP +server is not available to provide the CRL query. In the PKI protocol +proposed here, only the requester can initiate the transaction to +download CRL. A requester sends GetCRL request to the server and the +server sends back CertRep whose information portion is a degenerated +PKCS#7 which contains only the most recent CRL. The size of CRL included +in the CertRep should be determined by the implementation. + +PreCondition + The certificate authority certificate has been downloaded to the end + entity. + +PostCondition + CRL sent back to the requester. + +5.4.1 GetCRL Message format + +The CRL is identified by using both CA's issuer name and the CA +certificate's serial number: + + pkcsGetCRL issuerAndSerialNumber { + issuer "the certificate authority issuer name" + serialNumber "certificate authority certificate's serial number" + } + +When the CRLDistributionPoint is supported, the pkcsGetCRL is defined as +the following: + + pkcsGetCRL SEQUENCE { + crlIssuer issuerAndSerialNumber + distributionPoint CE-CRLDistPoints + } + +where CE-CRLDisPoints is defined in X.509, but must contain only one +CRL distribution point. + + + + + + + + + + + Liu/Madson/McGrew/Nourse [Page 28] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + pkcsGetCRLEnvelope EnvelopedData ::= { + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the certificate authority (or RA) issuer name" + serialNumber "the CA (RA) certificate's serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted by CA (RA) public key" + } + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted pkcsGetCRL" + } + } + pkcsGetCRLSigned SignedData ::= { + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + content pkcsGetCRLEnvelope + } + certificates { + certificate "CA-issued or self-signed requester's certificate" + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the requester's issuer name" + serialNumber "the requester's certificate serial number" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} 0x<16/20 bytes>} + -- digest of pkcsGetCRLEnvelope + messageType {{id-attribute messageType(2)} "CertCRL"} + transaction-id {{id-attributes transId(7)} "printable + string"} + senderNonce {{id-attribute senderNonce(3)} <16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticateAttributes" + } + } + GetCRL PKIMessage ::= { + contentType {pkcs-7 2} + content pkcsGetCRLSigned + } + + Liu/Madson/McGrew/Nourse [Page 29] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + +5.4.2 CertRep Message Format + +The CRL is sent back to the requester through CertRep message. The +information portion of this message is a degenerated PKCS#7 SignedData +which contains only a CRL. + + pkcsCertRep SignedData ::= { + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + } + crl { + signature {pkcs-1 4} + issuer "the certificate authority issuer name" + lastUpdate "UTC time" + nextUpdate "UTC time" + revokedCertificate { + -- the first entry + userCertificate "certificate serial number" + revocationData "UTC time" + .... + -- last entry + userCertificate "certificate serial number" + revocationData "UTC time" + } + } + pkcsCertRepEnvelope EnvelopedData ::= { + version 0 + recipientInfo { + version 0 + issuerAndSerialNumber { + issuer "the requester's issuer name" + serialNumber "the requester certificate serial number" + } + keyEncryptionAlgorithm {pkcs-1 1} + encryptedKey "content-encrypt key encrypted by requester's + public key " + } + encryptedContentInfo { + contentType {pkcs-7 1} -- data content + contentEncryptionAlgorithm "OID for DES encryption" + encryptedContent "encrypted pkcsCertRep using requester's + public key" + } + } + + + + + + + Liu/Madson/McGrew/Nourse [Page 30] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + + pkcsCertRepSigned SignedData ::= { -- PKCS#7 + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + contentInfo { + contentType {pkcs-7 1} + content pkcsCertRepEnvelope + } + signerInfo { + version 1 + issuerAndSerialNumber { + issuer "the certificate authority issuer name" + serialNumber "the CA certificate's serial number" + } + digestAlgorithm {iso(1), member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + authenticateAttributes { + contentType {{pkcs-9 3} {pkcs-7 1}} + messageDigest {{pkcs-9 4} "an octet string"} + -- digest of pkcsCertRepEnvelope + messageType {{id-attribute messageType(2)} "CertRep"} + transaction-id {{id-attributes transId(7)} "printable + string"} + -- same transaction id as given in PKCSReq + pkiStatus {{id-attributes pkiStatus(3) "SUCCESS"} + recipientNonce{{id-attribute recipientNonce(6)}<16 bytes>} + senderNonce {{id-attribute senderNonce (5) 0x<16 bytes>} + } + digestEncryptionAlgorithm {pkcs-1 1} + encryptedDigest "encrypted digest of authenticatedAttributes + using CA private key" + } + } + + +NOTE:The PKCS#7 EncryptedContent is specified as an octet string, but +SCEP entities must also accept a sequence of octet strings as a valid +alternate encoding. + +This alternate encoding must be accepted wherever PKCS #7 Enveloped +Data is specified in this document. + + + + + + + + + + + + Liu/Madson/McGrew/Nourse [Page 31] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +5.5 Get Certificate Authority Certificate + +Before any transaction begins, end entities have to get the CA (and +possibly RA) certificate(s) first. Since the requester may have no CA +certificates or CA public keys at all, this message can not be +encrypted and the response must be authenticated by out-of-band means. +These certs are obtained by means of an HTTP GET message. To get the +CA certificate, the requester does a "HTTP GET" with a URL that +identifies a CGI script on the server and an optional CA issuer +identifier as the parameter to the CGI script. The response is either +a single X.509 CA certificate ("CA mode"), or a PKCS7 message +containing the CA certificate and RA certificates ("RA mode"). The +client can determine which mode the CA operates in by which response +it gets. Once the CA certificate is received by the requester, a +fingerprint is generated using either the SHA-1 or the MD5 hash +algorithm on the whole CA certificate. If the requester does not have +a certificate path to a trusted CA certificate, this fingerprint may +be used to verify the certificate, by some positive out-of-band means, +such as a phone call. + +5.5.1 GetCACert HTTP Message Format + "GET" CGI-PATH CGI-PROG "?operation=GetCACert" "&message=" CA-IDENT + where: + CGI-PATH defines the actual CGI path to invoke the CGI program + which parses the request. + CGI-PROG is set to be the string "pkiclient.exe" and this is + expected to be the program that the CA will use to handle the + SCEP transactions. + CA-IDENT is any string which is understood by the CA. + For example, it could be a domain name like ietf.org. + If a certificate authority has multiple CA certificates + this field can be used to distinguish which is required. + Otherwise it may be ignored. + +5.5.2 Response + +The response for GetCACert is different between the case where the CA +directly communicated with the requester during the enrollment, and the +case where a RA exists and the requester communicates with the RA +during the enrollment. + +5.5.2.1 CA Certificate Only Response + +A binary X.509 CA certificate is sent back as a MIME object with a +Content-Type of application/x-x509-ca-cert. + +5.5.2.2 CA and RA Certificates Response + +When an RA exists, both CA and RA certificates must be sent back in +the response to the GetCACert request. The RA certificate(s) must be +signed by the CA. A certificates-only PKCS#7 SignedData is used to +carry the certificates to the requester, with a Content-Type of +application/x-x509-ca-ra-cert. + + Liu/Madson/McGrew/Nourse [Page 32] + +5.5.3 Get Next Certificate Authority Certificate + +5.5.3.1 GetNextCACert HTTP Message Format + "GET" CGI-PATH CGI-PROG "?operation=GetNextCACert" "&message=" CA-IDENT + +The response to this message is a PKCS#7 certificates-only message containing +a CA certificate (and possibly RA certificates) to be used when the current CA +certificate expires, signed with the current CA cert (or RA certificate, if +the CA is in RA mode. Note that a PKCS#7 is returned even in CA mode. + +5.5.3.2 GetCACaps HTTP Message Format + "GET" CGI-PATH CGI-PROG "?operation=GetCACaps" "&message=" CA-IDENT + +This message requests capabilities from CA. The response is a list of +text capabilities, as defined in Appendix F. Support for this message +is optional, but if it is not supported, the client should assume that +none of the capabilities in Appendix F are supported. + +5.6 Get Certificate Authority Certificate Chain + +GetCACertChain provides a way to get the entire certificate chain. + +5.6.1 GetCACertChain HTTP Message Format + + "GET" CGI-SCRIPT "?" "operation=GetCACertChain" "&" "message" CA-IDENT + where CGI-SCRIPT and CA-IDENT are as described for GetCACert. + +5.6.2 Response + +The response for GetCACertChain is a certificates-only PKCS#7 SignedData +to carry the certificates to the requester, with a Content-Type of +application/x-x509-ca-ra-cert-chain. + +5.6.3 Backwards Compatability + +Versions of SCEP prior to revision 3 do not support GetCACertChain. +Certificate Authorities written to these prior versions will not be +able to process the message and may return an HTML error. + +To avoid this, clients should send the GetCACert message first. If the +returned certificate is self-signed or is signed by a Certificate +Authority that is trusted by the client, then it is not necessary to +send the GetCACertChain message and it should not be sent. + +If a Certificate Authority is configured with a certificate that is +not either self-signed or has a self-signed issuer, then it should +support this message. In other words, it should be supported if the +CA hierarchy is more than two-deep. + +An old CA in a two-deep hierarchy might still get this message from +a client if the client did not trust either that CA or its issuer. +In that event, the certificate cannot be trusted anyway. In any case +the CA must not crash or hang upon the receipt of the message and the +client must be able to handle whatever error is returned by the CA, +including an HTML error or an ungraceful disconnect. + + Liu/Madson/McGrew/Nourse [Page 33] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +The following is the ASN.1 definition of Cert-Only PKCS#7: + + certOnly SignedData ::= { + version 1 + digestAlgorithm {iso(1) member-body(2) US(840) rsadsi(113549) + digestAlgorithm(2) 5} + +contentInfo { + contentType {pkcs-7 1} -- data content identifier + content -- NULL + } + certificates -- the RA and CA certificates. + } + + CARACerts PKIMessage ::= { -- special pki message sent in the clear + contentType {pkcs-7 2} + content certOnly + } + + +6.0 Security Considerations + +This entire document is about security. Common security considerations +such as keeping private keys truly private and using adequate lengths +for symmetric and asymmetric keys must be followed in order to maintain +the security of this protocol. + + +7.0 Intellectual Property + +This protcol includes the optional use of Certificate Revocation List +Distribution Point (CRLDP) technology, which is a patented technology +of Entrust Technologies, Inc. (Method for Efficient Management of +Certificate Revocation Lists and Update Information (U.S. Patent +5,699,431)). Please contact Entrust Technologies, Inc. +(www.entrust.com) for more information on licensing CRLDP technology. + + +8.0 References + +[PKCS7] Kaliski, B., "PKCS #7: Cryptographic Message Syntax Version +1.5", RFC 2315, March 1998. + +[PKCS10] Kaliski, B., "PKCS #10: Certification Request Syntax Version +1.5", RFC 2314, March 1998. + +[RFC2459] Housley, R., ec. al., "Internet X.509 Public Key +Infrastructure Certificate and CRL Profile", RFC 2459, January 1999. + + + + + + + Liu/Madson/McGrew/Nourse [Page 34] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Appendix A: Cisco Requester Subject Name Definition + +The ip address and the FQDN of a SCEP client should be included in the +V3 extension subjectAltName. When the subjectAltName extension attribute +is present, both the subjectAltName fields and the subjectName field could +have the IP address and the FQDN information. + +When the X.500 directory is used by the CA to define the name space, the +subject name defined above become a RDN which is part of DN binded to +the requester's public key in the certificate. + + +A sample of DN assigned by Entrust CA is given below (assume the same +ciscoRouterAlice is used as the requester defined subject name): + + OU = InteropTesting, O = Entrust Technologies, C = CA + RDN = {"alice.cisco.com", "172.21.114.67", "22334455"} + + + Liu/Madson/McGrew/Nourse [Page 35] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Appendix B: IPSEC Client Enrollment Certificate Request + +The following is the certificate enrollment request (PKCS#10) as created +by Cisco VPN Client: + +-----END NEW CERTIFICATE REQUEST----- + 0 30 439: SEQUENCE { + 4 30 288: SEQUENCE { + 8 02 1: INTEGER 0 + 11 30 57: SEQUENCE { + 13 31 55: SET { + 15 30 53: SEQUENCE { + 17 06 3: OBJECT IDENTIFIER commonName (2 5 4 3) + 22 13 46: PrintableString + : 'For Xiaoyi, IPSEC attrs in alternate name + extn' + : } + : } + : } + 70 30 158: SEQUENCE { + 73 30 13: SEQUENCE { + 75 06 9: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 + 1 1) + 86 05 0: NULL + : } + 88 03 140: BIT STRING 0 unused bits + : 30 81 88 02 81 80 73 DB 1D D5 65 AA EF C7 D4 8E + : AA 6E EB 46 AC 91 2A 0F 50 51 17 AD 50 A2 2A F2 + : CE BE F1 E4 22 8C D7 61 A1 6C 87 61 62 92 CB A6 + : 80 EA B4 0F 09 9D 18 5F 39 A3 02 0E DB 38 4C E4 + : 8A 63 2E 72 8B DC BE 9E ED 6C 1A 47 DE 13 1B 0F + : 83 29 4D 3E 08 86 FF 08 2B 43 09 EF 67 A7 6B EA + : 77 62 30 35 4D A9 0F 0F DF CC 44 F5 4D 2C 2E 19 + : E8 63 94 AC 84 A4 D0 01 E1 E3 97 16 CD 86 64 18 + : [ Another 11 bytes skipped ] + : } + 231 A0 63: [0] { + 233 30 61: SEQUENCE { + 235 06 9: OBJECT IDENTIFIER extensionReq (1 2 840 113549 1 9 + 14) + 246 31 48: SET { + 248 30 46: SEQUENCE { + 250 30 44: SEQUENCE { + 252 06 3: OBJECT IDENTIFIER subjectAltName (2 5 29 17) + 257 04 37: OCTET STRING + 30 23 87 04 01 02 03 04 81 0D 65 6D 61 69 + + + Liu/Madson/McGrew/Nourse [Page 36] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + 6C 40 69 72 65 2E 63 6F 6D 82 0C 66 71 64 + 6E 2E 69 72 65 2E 63 6F 6D + : } + : } + : } + : } + : } + : } + + 296 30 13: SEQUENCE { + 298 06 9: OBJECT IDENTIFIER md5withRSAEncryption (1 2 840 113549 + 1 1 4) + 309 05 0: NULL + : } + 311 03 129: BIT STRING 0 unused bits + : 19 60 55 45 7F 72 FD 4E E5 3F D2 66 B0 77 13 9A + : 87 86 75 6A E1 36 C6 B6 21 71 68 BD 96 F0 B4 60 + : 95 8F 12 F1 65 33 16 FD 46 8A 63 19 90 40 B4 B7 + : 2C B5 AC 63 17 50 28 F0 CD A4 F0 00 4E D2 DE 6D + : C3 4F F5 CB 03 4D C8 D8 31 5A 7C 01 47 D2 2B 91 + : B5 48 55 C8 A7 0B DD 45 D3 4A 8D 94 04 3A 6C B0 + : A7 1D 64 74 AB 8A F7 FF 82 C7 22 0A 2A 95 FB 24 + : 88 AA B6 27 83 C1 EC 5E A0 BA 0C BA 2E 6D 50 C7 + : } + + +Appendix C: Private OID Definitions + +The OIDs used in defining pkiStatus are VeriSign self-maintained +OIDs. Please note, work is in progress to replace the VeriSign owned +object identifiers with the standard object identifiers. Once the +standarlization is completed, this documentation will be updated. + +id-VeriSign OBJECT_IDENTIFIER ::= {2 16 US(840) 1 VeriSign(113733)} +id-pki OBJECT_IDENTIFIER ::= {id-VeriSign pki(1)} +id-attributes OBJECT_IDENTIFIER ::= {id-pki attributes(9)} +id-messageType OBJECT_IDENTIFIER ::= {id-attributes messageType(2)} +id-pkiStatus OBJECT_IDENTIFIER ::= {id-attributes pkiStatus(3)} +id-failInfo OBJECT_IDENTIFIER ::= {id-attributes failInfo(4)} +id-senderNonce OBJECT_IDENTIFIER ::= {id-attributes senderNonce(5)} +id-recipientNonce OBJECT_IDENTIFIER ::= {id-attributes recipientNonce(6)} +id-transId OBJECT_IDENTIFIER ::= {id-attributes transId(7)} +id-extensionReq OBJECT_IDENTIFIER ::= {id-attributes extensionReq(8)} + + + Liu/Madson/McGrew/Nourse [Page 37] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + Appendix D: CRL Query by means of LDAP + + In order to retrieve the CRL by means of LDAP, the client needs to know + where in the directory it is stored. The certificate must contain a + CRL Distribution Point extension encoded as a DN or as an LDAP URI. + +For example, the certificate issued by Entrust VPN contains +the following DN as the CRL distribution point: + + + +CN = CRL1, O = cisco, C = US. + + The asn.1 encoding of this distribution point is: + + 30 2C 31 0B 30 09 06 03 55 04 06 13 02 55 53 31 0E 30 0C 06 + 03 55 04 0A 13 05 63 69 73 63 6F 31 0D 30 0B 06 03 55 04 03 + 13 04 43 52 4C 31 + + +The ldap form would be: + +ldap://servername/CN=CRL1,O=cisco,C=US + + + +Appendix E: SCEP State Transitions + +SCEP state transitions are based on transaction identifier. The design +goal is to ensure the synchronization between the CA and the requester +under various error situations. + + +An identity is defined by the combination of FQDN, the IP address and +the client serial number. FQDN is the required name attribute. It is +important to notice that, a client named as Alice.cisco.com is different +from the client named as Alice.cisco.com plus IPAddress 117.96.1.219. + +Each enrollment transaction is uniquely associated with a transaction +identifier. Because the enrollment transaction could be interrupted by +various errors, including network connection errors or client reboot, +the SCEP client generates a transaction identifier by calculating a +hash on the public key value for which the enrollment is requested. This +retains the same transaction identifier throughout the enrollment +transaction, even if the client has rebooted or timed out, and issues a +new enrollment request for the same key pair. It also provides the way +for the CA to uniquely identify a transaction in its database. At the +requester side, it generates a transaction identifier which is included +in PKCSReq. If the CA returns a response of PENDING, the requester +will poll by periodically sending out GetCertInitial with the same +transaction identifier until either a response other than PENDING is +obtained, or the configured maximum time has elapsed. + +If the client times out or the client reboots, the client administrator +will start another enrollment transaction with the same key pair. The +second enrollment will have the transaction idenifier. At the server +side, instead of accepting the PKCSReq as a new enrollment request, it +should respond as if another GetCertInitial message had been sent with +that transaction ID. In another word, the second PKCSReq should be +taken as a resynchronization message to allow the enrollment resume as +the same transaction. + +It is important to keep the transaction id unique since SCEP requires the +same policy and same identity be applied to the same subject name and + + + Liu/Madson/McGrew/Nourse [Page 38] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +key pair binding. In the current implementation, an SCEP client can +only assume one identity. At any time, only one key pair, with a given +key usage, can be associated with the same identity. + +The following gives several examples of client to CA transactions. + +Client actions are indicated in the left column, CA actions are +indicated in the right column. A blank action signifies that no message +was received. Note that these examples assume that the CA enforces the +certificate-name uniqueness property defined in Section 2.1.1.1. + +The first transaction, for example, would read like this: + "Client Sends PKCSReq message with transaction ID 1 to the + CA. The CA signs the certificate and constructs a CertRep Message + containing the signed certificate with a transaction ID 1. The client + receives the message and installs the cert locally." + +Successful Enrollment Case: no manual authentication +PKCSReq (1) ----------> CA Signs Cert +Client Installs Cert <---------- CertRep (1) SIGNED CERT + + + +Successful Enrollment Case: manual authentication required +PKCSReq (10) ----------> Cert Request goes into Queue +Client Polls <---------- CertRep (10) PENDING +GetCertInitial (10) ----------> Still pending +Client Polls <---------- CertRep (10) PENDING +GetCertInitial (10) ----------> Still pending +Client Polls <---------- CertRep (10) PENDING +GetCertInitial (10) ----------> Still pending +Client Polls <---------- CertRep (10) PENDING +GetCertInitial (10) ----------> Cert has been signed +Client Installs Cert <---------- CertRep (10) SIGNED CERT + + + +Resync Case - CA Receive and Signs PKCSReq, Client Did not receive +CertRep: + +PKCSReq (3) ----------> Cert Request goes into queue + <---------- CertRep (3) PENDING +GetCertInitial (3) ----------> + <---------- CertRep (3) PENDING +GetCertInitial (3) -----------> + <----------- CA signed Cert and sent back + CertRep(3) +(Time Out) +PKCSReq (3) ----------> Cert already signed, sent back to + client +Client Installs Cert <---------- CertRep (3) SIGNED CERT + + + + Liu/Madson/McGrew/Nourse [Page 39] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + + +Case when NVRAM is lost and client has to generate a new key pair, there +is no change of name information: + +PKCSReq (4) ----------> CA Signs Cert +Client Installs Cert <---------- CertRep (4) SIGNED CERT +(Client looses Cert) +PKCSReq (5) ----------> There is already a valid cert with + this DN. +Client Admin Revokes <---------- CertRep (5) OVERLAPPING CERT ERROR +PKCSReq (5) ----------> CA Signs Cert +Client Installs Cert <---------- CertRep (5) SIGNED CERT + + +Case when client admin resync the enrollment using a different PKCS#10: +PKCSReq (6) ----------> CA Signs Cert + <---------- CertRep (6) SIGNED CERT +(Client timeout and admin starts another enrollment with a different + PKCS#10, but the same transaction id) +PKCSReq (6) with different PKCS#10 + ----------> There is already a valid cert with + this entity (by checking FQDN). + <---------- CertRep (6) INVALID PKCS#10 CERT + ERROR +Client admin either revokes the existing cert +or corrects the error by enrolling with +the same PKCS#10 as the first PKCSReq(6) +PKCSReq (6) ----------> CA find the existing Cert +Client Installs Cert <---------- CertRep (6) SIGNED CERT + + +Resync case when server is slow in response: +PKCSReq (13) ----------> Cert Request goes into Queue + <---------- CertRep (13) PENDING +GetCertInitial ----------> Still pending + <---------- CertRep (13) PENDING +GetCertInitial ----------> Still pending + <---------- CertRep (13) PENDING +GetCertInitial ----------> Still pending + <---------- CertRep (13) PENDING +GetCertInitial ----------> Still pending +(TimeOut) <---------- CertRep (13) PENDING +* Case 1 +PKCSReq (13) ----------> Still pending +Client polls <---------- CertRep (13) PENDING +CertCertInitial ----------> Cert has been signed +Client Installs Cert <---------- CertRep (13) SIGNED CERT +* Case 2 +PKCSReq (13) ----------> Cert has been signed +Client Installs Cert <---------- CertRep (13) SIGNED CERT + + + + + Liu/Madson/McGrew/Nourse [Page 40] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Appendix F. CA Capabilities + +The response for a GetCACaps message is a list of CA capabilities, in +plain text, separated by characters, as follows (quotation marks +are NOT sent): + +Keyword Description + +"GetNextCACert" CA Supports the GetNextCACert message. +"POSTPKIOperation" PKIOPeration messages may be sent via HTTP POST. +"SHA-1" CA Supports the SHA-1 hashing algorithm in + signatures and fingerprints. If present, the + client SHOULD use SHA-1. If absent, the client + MUST use MD5 to maintain backward compatability. +"Renewal" Clients may use current certificate and key to + authenticate an enrollment request for a new + certificate. + +A client must be able to accept and ignore any unknown keywords that +might be sent back by a CA that implements a future version of SCEP. + +Example: + +GET /cgi-bin/pkiclient.exe?operation=GetCACaps&message=myca + +returns: + +GetNextCACert +POSTPKIOperation + +This means that the CA supports the GetNextCACert message and allows +PKIOperation messages (PKCSreq, GetCert, GetCertInitial...) to be sent +using HTTP POST. + + + Liu/Madson/McGrew/Nourse [Page 41] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Appendix G. Certificate Renewal and CA Key Rollover + +To renew a client certificate, use the PKCSreq message and sign it with +the existing client certificate instead of a self-signed certificate. + +To obtain the new CA certificate prior to the expiration of the current +one, use the GetNextCACert message if the CA supports it. + +To obtain a new client certificate signed by the new CA certificate, +use the new CA or RA certificate in the message envelope. + + +Example: + +GetNextCACert ----------> + <---------- CertRep (3) New CA certificate + +PKCSReq* (1) ----------> CA Signs certificate with NEW key +Client Stores Cert <---------- CertRep (3) Certificate issued +for installation when from NEW CA certificate and keypair. +existing cert expires. + + +*enveloped for new CA or RA cert and keypair. The CA will use the +envelope to determine which key and certificate to use to issue the +client certificate. + + + Liu/Madson/McGrew/Nourse [Page 42] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Appendix H. PKIOperation via HTTP POST Message + +If the remote CA supports it, any of the PKCS#7-encoded SCEP messages +may be sent via HTTP POST instead of HTTP GET. This is allowed for +any SCEP message except GetCACert, GetCACertChain, GetNextCACert, +or GetCACaps. In this form of the message, Base 64 encoding is not +used. + +POST /cgi-bin/pkiclient.exe?operation=PKIOperation + + +The client can verify that the CA supports SCEP messages via POST by +looking for the "POSTPKIOperation" capability (See Appendix F). + + + + + + + Liu/Madson/McGrew/Nourse [Page 43] + +Cisco Systems' Simple Certificate Enrollment Protocol Feb 2005 + +Appendix Y. Author Contact Information + +Xiaoyi Liu Cheryl Madson +Cisco Cisco +510 McCarthy Drive 510 McCarthy Drive +Milpitas, CA Milpitas, CA. +xliu@cisco.com cmadson@cisco.com + + +David McGrew Andrew Nourse +Cisco Cisco +170 West Tasman Drive 510 McCarthy Drive +San Jose, CA 94134 Milpitas, CA. +mcgrew@cisco.com nourse@cisco.com + + + + +Appendix Z. Copyright Section + +Copyright (C) The Internet Society (2005). This document is subject +to the rights, licenses and restrictions contained in BCP 78, and +except as set forth therein, the authors retain all their rights. + +This document and the information contained herein are provided on an +"AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS +OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET +ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE +INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + + + + +This draft expires 11 Aug 2005 + +[End of draft-nourse-scep-11.txt] + diff --git a/fileutils.c b/fileutils.c index 558550c..da14756 100644 --- a/fileutils.c +++ b/fileutils.c @@ -8,6 +8,7 @@ /* Misc. cert/crl manipulation routines */ +#include #include "sscep.h" /* Open the inner, decrypted PKCS7 and try to write CRL. */ @@ -30,7 +31,12 @@ write_crl(struct scep *s) { } /* Write PEM-formatted file: */ - if (!(fp = fopen(w_char, "w"))) { +#ifdef WIN32 + if ((fopen_s(&fp, w_char, "w"))) +#else + if (!(fp = fopen(w_char, "w"))) +#endif + { fprintf(stderr, "%s: cannot open CRL file for writing\n", pname); exit (SCEP_PKISTATUS_FILE); @@ -52,8 +58,14 @@ write_crl(struct scep *s) { static int compare_subject(X509 * cert) { + char buffer[1024]; int rc = X509_NAME_cmp(X509_get_subject_name(cert), X509_REQ_get_subject_name(request)); - + if(d_flag) { + fprintf(stderr, "Subject of the returned certificate: %s\n", X509_get_subject_name(cert)); + fprintf(stderr, "Subject of the request: %s\n", + X509_NAME_oneline(X509_REQ_get_subject_name(request), buffer, sizeof(buffer)) + ); + } if (rc) { /* X509_NAME_cmp should return 0 when X509_get_subject_name() @@ -115,14 +127,17 @@ write_local_cert(struct scep *s) { if (v_flag) printf ("CN's of request and certificate matched!\n"); - - /* The subject cannot be the issuer (selfsigned) */ - if (X509_NAME_cmp(X509_get_subject_name(cert), - X509_get_issuer_name(cert))) { - localcert = cert; - break; - } - } + } else { + fprintf(stderr, "%s: Subject of our request does not match that of the returned Certificate!\n", pname); + //exit (SCEP_PKISTATUS_FILE); + } + + /* The subject cannot be the issuer (selfsigned) */ + if (X509_NAME_cmp(X509_get_subject_name(cert), + X509_get_issuer_name(cert))) { + localcert = cert; + break; + } } if (localcert == NULL) { fprintf(stderr, "%s: cannot find requested certificate\n", @@ -131,7 +146,12 @@ write_local_cert(struct scep *s) { } /* Write PEM-formatted file: */ - if (!(fp = fopen(l_char, "w"))) { +#ifdef WIN32 + if ((fopen_s(&fp, l_char, "w"))) +#else + if (!(fp = fopen(l_char, "w"))) +#endif + { fprintf(stderr, "%s: cannot open cert file for writing\n", pname); exit (SCEP_PKISTATUS_FILE); @@ -192,7 +212,12 @@ write_other_cert(struct scep *s) { } /* Write PEM-formatted file: */ - if (!(fp = fopen(w_char, "w"))) { +#ifdef WIN32 + if ((fopen_s(&fp, w_char, "w"))) +#else + if (!(fp = fopen(w_char, "w"))) +#endif + { fprintf(stderr, "%s: cannot open cert file for writing\n", pname); exit (SCEP_PKISTATUS_FILE); @@ -297,7 +322,12 @@ write_ca_ra(struct http_reply *s) { } /* Write PEM-formatted file: */ - if (!(fp = fopen(name, "w"))) { +#ifdef WIN32 + if ((fopen_s(&fp, name, "w"))) +#else + if (!(fp = fopen(name, "w"))) +#endif + { fprintf(stderr, "%s: cannot open cert file for " "writing\n", pname); exit (SCEP_PKISTATUS_FILE); @@ -323,7 +353,14 @@ write_ca_ra(struct http_reply *s) { void read_ca_cert(void) { /* Read CA cert file */ - if (!c_flag || !(cafile = fopen(c_char, "r"))) { + if (!c_flag || +#ifdef WIN32 + (fopen_s(&cafile, c_char, "r")) +#else + !(cafile = fopen(c_char, "r")) +#endif + ) + { fprintf(stderr, "%s: cannot open CA cert file\n", pname); exit (SCEP_PKISTATUS_FILE); } @@ -336,7 +373,12 @@ read_ca_cert(void) { /* Read enc CA cert */ if (e_flag) { - if (!(cafile = fopen(e_char, "r"))) { +#ifdef WIN32 + if ((fopen_s(&cafile, e_char, "r"))) +#else + if (!(cafile = fopen(e_char, "r"))) +#endif + { fprintf(stderr, "%s: cannot open enc CA cert file\n", pname); exit (SCEP_PKISTATUS_FILE); @@ -356,7 +398,12 @@ read_ca_cert(void) { void read_cert(X509** cert, char* filename) { FILE *file; - if (!(file = fopen(filename, "r"))) { +#ifdef WIN32 + if ((fopen_s(&file, filename, "r"))) +#else + if (!(file = fopen(filename, "r"))) +#endif + { fprintf(stderr, "%s: cannot open cert file %s\n", pname, filename); exit (SCEP_PKISTATUS_FILE); } @@ -367,6 +414,62 @@ read_cert(X509** cert, char* filename) { } fclose(file); } +/* +void read_cert_Engine(X509** cert, char* id, ENGINE *e, char* filename) +{ + BIO *bio, *b64; + PCCERT_CONTEXT ctx = NULL; + int ret; + HCERTSTORE store; + DWORD cbSize; + LPTSTR pszName; + LPSTR str; + FILE *certfile; + + store = CertOpenSystemStore(0, L"MY"); + + ctx = CertFindCertificateInStore(store, MY_ENCODING_TYPE, 0, CERT_FIND_SUBJECT_STR, (LPCSTR) id, NULL); + if(!ctx) { + while(ctx = CertEnumCertificatesInStore(store, ctx)) + { + cbSize = CertGetNameString(ctx, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0); + pszName = (LPTSTR)malloc(cbSize * sizeof(TCHAR)); + CertGetNameString(ctx, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszName, cbSize); + cbSize = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS | WC_COMPOSITECHECK | WC_DEFAULTCHAR, (LPCWSTR) pszName, -1, NULL, 0, NULL, NULL); + str = (LPSTR)malloc(cbSize * sizeof(LPSTR)); + WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS | WC_COMPOSITECHECK | WC_DEFAULTCHAR, (LPCWSTR) pszName, -1, str, cbSize, NULL, NULL); + if(strstr(str, id)) { + ret = 0; + break; + } else { + ret = 127; + } + } + } + if(!ctx || ret != 0) + { + fprintf(stderr, "%s: cannot find Certificate with subject %s in store\n", pname, id); + exit(SCEP_PKISTATUS_FILE); + } + + certfile = fopen(filename, "w"); + fputs("-----BEGIN CERTIFICATE-----\n", certfile); + fclose(certfile); + + b64 = BIO_new(BIO_f_base64()); + bio = BIO_new_file(filename, "a"); + bio = BIO_push(b64, bio); + ret = BIO_write(bio, ctx->pbCertEncoded, ctx->cbCertEncoded); + ret = BIO_flush(bio); + BIO_free_all(bio); + + certfile = fopen(filename, "a"); + fputs("-----END CERTIFICATE-----", certfile); + fclose(certfile); + + read_cert(cert, filename); +}*/ + /* Read private key */ @@ -374,7 +477,12 @@ void read_key(EVP_PKEY** key, char* filename) { FILE *file; /* Read private key file */ - if (!(file = fopen(filename, "r"))) { +#ifdef WIN32 + if ((fopen_s(&file, filename, "r"))) +#else + if (!(file = fopen(filename, "r"))) +#endif + { fprintf(stderr, "%s: cannot open private key file %s\n", pname, filename); exit (SCEP_PKISTATUS_FILE); } @@ -386,12 +494,29 @@ read_key(EVP_PKEY** key, char* filename) { fclose(file); } +/* Read private key with hwcrhk id */ +//idea from: http://blog.burghardt.pl/2010/03/ncipher-hsm-with-openssl/ +void +read_key_Engine(EVP_PKEY** key, char* id, ENGINE *e) { + *key = ENGINE_load_private_key(e, id, NULL, NULL); + if(*key == 0) { + printf("Could not load private key!\n"); + exit(SCEP_PKISTATUS_FILE); + } +} + /* Read PKCS#10 request */ void read_request(void) { /* Read certificate request file */ - if (!r_flag || !(reqfile = fopen(r_char, "r"))) { + if (!r_flag || +#ifdef WIN32BLA + (fopen_s(&reqfile, r_char, "r"))) +#else + !(reqfile = fopen(r_char, "r"))) +#endif + { fprintf(stderr, "%s: cannot open certificate request\n", pname); exit (SCEP_PKISTATUS_FILE); } diff --git a/getopt.c b/getopt.c new file mode 100644 index 0000000..fd9c2b5 --- /dev/null +++ b/getopt.c @@ -0,0 +1,1058 @@ +/* Getopt for GNU. + NOTE: getopt is now part of the C library, so if you don't know what + "Keep this file name-space clean" means, talk to drepper@gnu.org + before changing it! + + Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98 + Free Software Foundation, Inc. + + NOTE: This source is derived from an old version taken from the GNU C + Library (glibc). + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +/* This tells Alpha OSF/1 not to define a getopt prototype in . + Ditto for AIX 3.2 and . */ +#ifndef _NO_PROTO +# define _NO_PROTO +#endif + +#include + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if !defined __STDC__ || !__STDC__ +/* This is a separate conditional since some stdc systems + reject `defined (const)'. */ +# ifndef const +# define const +# endif +#endif + +#include + +/* Comment out all this code if we are using the GNU C Library, and are not + actually compiling the library itself. This code is part of the GNU C + Library, but also included in many other GNU distributions. Compiling + and linking in this code is a waste when using the GNU C library + (especially if it is a shared library). Rather than having every GNU + program understand `configure --with-gnu-libc' and omit the object files, + it is simpler to just do this in the source for each such file. */ + +#define GETOPT_INTERFACE_VERSION 2 +#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 +# include +# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION +# define ELIDE_CODE +# endif +#endif + +#ifndef ELIDE_CODE + + +/* This needs to come after some library #include + to get __GNU_LIBRARY__ defined. */ +#ifdef __GNU_LIBRARY__ +/* Don't include stdlib.h for non-GNU C libraries because some of them + contain conflicting prototypes for getopt. */ +# include +# include +#endif /* GNU C library. */ + +#ifdef VMS +# include +# if HAVE_STRING_H - 0 +# include +# endif +#endif + +#ifndef _ +/* This is for other GNU distributions with internationalized messages. + When compiling libc, the _ macro is predefined. */ +# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC +# include +# define _(msgid) gettext (msgid) +# else +# define _(msgid) (msgid) +# endif +#endif + +/* This version of `getopt' appears to the caller like standard Unix `getopt' + but it behaves differently for the user, since it allows the user + to intersperse the options with the other arguments. + + As `getopt' works, it permutes the elements of ARGV so that, + when it is done, all the options precede everything else. Thus + all application programs are extended to handle flexible argument order. + + Setting the environment variable POSIXLY_CORRECT disables permutation. + Then the behavior is completely standard. + + GNU application programs can use a third alternative mode in which + they can distinguish the relative order of options and other arguments. */ + +#include "getopt.h" + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +char *optarg = NULL; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +/* 1003.2 says this must be 1 before any call. */ +int optind = 1; + +/* Formerly, initialization of getopt depended on optind==0, which + causes problems with re-calling getopt as programs generally don't + know that. */ + +int __getopt_initialized = 0; + +/* The next char to be scanned in the option-element + in which the last option character we returned was found. + This allows us to pick up the scan where we left off. + + If this is zero, or a null string, it means resume the scan + by advancing to the next ARGV-element. */ + +static char *nextchar; + +/* Callers store zero here to inhibit the error message + for unrecognized options. */ + +int opterr = 1; + +/* Set to an option character which was unrecognized. + This must be initialized on some systems to avoid linking in the + system's own getopt implementation. */ + +int optopt = '?'; + +/* Describe how to deal with options that follow non-option ARGV-elements. + + If the caller did not specify anything, + the default is REQUIRE_ORDER if the environment variable + POSIXLY_CORRECT is defined, PERMUTE otherwise. + + REQUIRE_ORDER means don't recognize them as options; + stop option processing when the first non-option is seen. + This is what Unix does. + This mode of operation is selected by either setting the environment + variable POSIXLY_CORRECT, or using `+' as the first character + of the list of option characters. + + PERMUTE is the default. We permute the contents of ARGV as we scan, + so that eventually all the non-options are at the end. This allows options + to be given in any order, even with programs that were not written to + expect this. + + RETURN_IN_ORDER is an option available to programs that were written + to expect options and other ARGV-elements in any order and that care about + the ordering of the two. We describe each non-option ARGV-element + as if it were the argument of an option with character code 1. + Using `-' as the first character of the list of option characters + selects this mode of operation. + + The special argument `--' forces an end of option-scanning regardless + of the value of `ordering'. In the case of RETURN_IN_ORDER, only + `--' can cause `getopt' to return -1 with `optind' != ARGC. */ + +static enum +{ + REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER +} ordering; + +/* Value of POSIXLY_CORRECT environment variable. */ +static char *posixly_correct; + +#ifdef __GNU_LIBRARY__ +/* We want to avoid inclusion of string.h with non-GNU libraries + because there are many ways it can cause trouble. + On some systems, it contains special magic macros that don't work + in GCC. */ +# include +# define my_index strchr +#else + +# if HAVE_STRING_H +# include +# else +# if HAVE_STRINGS_H +# include +# endif +# endif + +/* Avoid depending on library functions or files + whose names are inconsistent. */ + +#ifndef getenv +extern char *getenv (); +#endif + +static char * +my_index (str, chr) + const char *str; + int chr; +{ + while (*str) + { + if (*str == chr) + return (char *) str; + str++; + } + return 0; +} + +/* If using GCC, we can safely declare strlen this way. + If not using GCC, it is ok not to declare it. */ +#ifdef __GNUC__ +/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. + That was relevant to code that was here before. */ +# if (!defined __STDC__ || !__STDC__) && !defined strlen +/* gcc with -traditional declares the built-in strlen to return int, + and has done so at least since version 2.4.5. -- rms. */ +extern int strlen (const char *); +# endif /* not __STDC__ */ +#endif /* __GNUC__ */ + +#endif /* not __GNU_LIBRARY__ */ + +/* Handle permutation of arguments. */ + +/* Describe the part of ARGV that contains non-options that have + been skipped. `first_nonopt' is the index in ARGV of the first of them; + `last_nonopt' is the index after the last of them. */ + +static int first_nonopt; +static int last_nonopt; + +#ifdef _LIBC +/* Bash 2.0 gives us an environment variable containing flags + indicating ARGV elements that should not be considered arguments. */ + +/* Defined in getopt_init.c */ +extern char *__getopt_nonoption_flags; + +static int nonoption_flags_max_len; +static int nonoption_flags_len; + +static int original_argc; +static char *const *original_argv; + +/* Make sure the environment variable bash 2.0 puts in the environment + is valid for the getopt call we must make sure that the ARGV passed + to getopt is that one passed to the process. */ +static void +__attribute__ ((unused)) +store_args_and_env (int argc, char *const *argv) +{ + /* XXX This is no good solution. We should rather copy the args so + that we can compare them later. But we must not use malloc(3). */ + original_argc = argc; + original_argv = argv; +} +# ifdef text_set_element +text_set_element (__libc_subinit, store_args_and_env); +# endif /* text_set_element */ + +# define SWAP_FLAGS(ch1, ch2) \ + if (nonoption_flags_len > 0) \ + { \ + char __tmp = __getopt_nonoption_flags[ch1]; \ + __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ + __getopt_nonoption_flags[ch2] = __tmp; \ + } +#else /* !_LIBC */ +# define SWAP_FLAGS(ch1, ch2) +#endif /* _LIBC */ + +/* Exchange two adjacent subsequences of ARGV. + One subsequence is elements [first_nonopt,last_nonopt) + which contains all the non-options that have been skipped so far. + The other is elements [last_nonopt,optind), which contains all + the options processed since those non-options were skipped. + + `first_nonopt' and `last_nonopt' are relocated so that they describe + the new indices of the non-options in ARGV after they are moved. */ + +#if defined __STDC__ && __STDC__ +static void exchange (char **); +#endif + +static void +exchange (argv) + char **argv; +{ + int bottom = first_nonopt; + int middle = last_nonopt; + int top = optind; + char *tem; + + /* Exchange the shorter segment with the far end of the longer segment. + That puts the shorter segment into the right place. + It leaves the longer segment in the right place overall, + but it consists of two parts that need to be swapped next. */ + +#ifdef _LIBC + /* First make sure the handling of the `__getopt_nonoption_flags' + string can work normally. Our top argument must be in the range + of the string. */ + if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) + { + /* We must extend the array. The user plays games with us and + presents new arguments. */ + char *new_str = malloc (top + 1); + if (new_str == NULL) + nonoption_flags_len = nonoption_flags_max_len = 0; + else + { + memset (mempcpy (new_str, __getopt_nonoption_flags, + nonoption_flags_max_len), + '\0', top + 1 - nonoption_flags_max_len); + nonoption_flags_max_len = top + 1; + __getopt_nonoption_flags = new_str; + } + } +#endif + + while (top > middle && middle > bottom) + { + if (top - middle > middle - bottom) + { + /* Bottom segment is the short one. */ + int len = middle - bottom; + register int i; + + /* Swap it with the top part of the top segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[top - (middle - bottom) + i]; + argv[top - (middle - bottom) + i] = tem; + SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); + } + /* Exclude the moved bottom segment from further swapping. */ + top -= len; + } + else + { + /* Top segment is the short one. */ + int len = top - middle; + register int i; + + /* Swap it with the bottom part of the bottom segment. */ + for (i = 0; i < len; i++) + { + tem = argv[bottom + i]; + argv[bottom + i] = argv[middle + i]; + argv[middle + i] = tem; + SWAP_FLAGS (bottom + i, middle + i); + } + /* Exclude the moved top segment from further swapping. */ + bottom += len; + } + } + + /* Update records for the slots the non-options now occupy. */ + + first_nonopt += (optind - last_nonopt); + last_nonopt = optind; +} + +/* Initialize the internal data when the first call is made. */ + +#if defined __STDC__ && __STDC__ +static const char *_getopt_initialize (int, char *const *, const char *); +#endif +static const char * +_getopt_initialize (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + /* Start processing options with ARGV-element 1 (since ARGV-element 0 + is the program name); the sequence of previously skipped + non-option ARGV-elements is empty. */ + + first_nonopt = last_nonopt = optind; + + nextchar = NULL; + + posixly_correct = getenv ("POSIXLY_CORRECT"); + + /* Determine how to handle the ordering of options and nonoptions. */ + + if (optstring[0] == '-') + { + ordering = RETURN_IN_ORDER; + ++optstring; + } + else if (optstring[0] == '+') + { + ordering = REQUIRE_ORDER; + ++optstring; + } + else if (posixly_correct != NULL) + ordering = REQUIRE_ORDER; + else + ordering = PERMUTE; + +#ifdef _LIBC + if (posixly_correct == NULL + && argc == original_argc && argv == original_argv) + { + if (nonoption_flags_max_len == 0) + { + if (__getopt_nonoption_flags == NULL + || __getopt_nonoption_flags[0] == '\0') + nonoption_flags_max_len = -1; + else + { + const char *orig_str = __getopt_nonoption_flags; + int len = nonoption_flags_max_len = strlen (orig_str); + if (nonoption_flags_max_len < argc) + nonoption_flags_max_len = argc; + __getopt_nonoption_flags = + (char *) malloc (nonoption_flags_max_len); + if (__getopt_nonoption_flags == NULL) + nonoption_flags_max_len = -1; + else + memset (mempcpy (__getopt_nonoption_flags, orig_str, len), + '\0', nonoption_flags_max_len - len); + } + } + nonoption_flags_len = nonoption_flags_max_len; + } + else + nonoption_flags_len = 0; +#endif + + return optstring; +} + +/* Scan elements of ARGV (whose length is ARGC) for option characters + given in OPTSTRING. + + If an element of ARGV starts with '-', and is not exactly "-" or "--", + then it is an option element. The characters of this element + (aside from the initial '-') are option characters. If `getopt' + is called repeatedly, it returns successively each of the option characters + from each of the option elements. + + If `getopt' finds another option character, it returns that character, + updating `optind' and `nextchar' so that the next call to `getopt' can + resume the scan with the following option character or ARGV-element. + + If there are no more option characters, `getopt' returns -1. + Then `optind' is the index in ARGV of the first ARGV-element + that is not an option. (The ARGV-elements have been permuted + so that those that are not options now come last.) + + OPTSTRING is a string containing the legitimate option characters. + If an option character is seen that is not listed in OPTSTRING, + return '?' after printing an error message. If you set `opterr' to + zero, the error message is suppressed but we still return '?'. + + If a char in OPTSTRING is followed by a colon, that means it wants an arg, + so the following text in the same ARGV-element, or the text of the following + ARGV-element, is returned in `optarg'. Two colons mean an option that + wants an optional arg; if there is text in the current ARGV-element, + it is returned in `optarg', otherwise `optarg' is set to zero. + + If OPTSTRING starts with `-' or `+', it requests different methods of + handling the non-option ARGV-elements. + See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. + + Long-named options begin with `--' instead of `-'. + Their names may be abbreviated as long as the abbreviation is unique + or is an exact match for some defined option. If they have an + argument, it follows the option name in the same ARGV-element, separated + from the option name by a `=', or else the in next ARGV-element. + When `getopt' finds a long-named option, it returns 0 if that option's + `flag' field is nonzero, the value of the option's `val' field + if the `flag' field is zero. + + The elements of ARGV aren't really const, because we permute them. + But we pretend they're const in the prototype to be compatible + with other systems. + + LONGOPTS is a vector of `struct option' terminated by an + element containing a name which is zero. + + LONGIND returns the index in LONGOPT of the long-named option found. + It is only valid when a long-named option has been found by the most + recent call. + + If LONG_ONLY is nonzero, '-' as well as '--' can introduce + long-named options. */ + +int +_getopt_internal (argc, argv, optstring, longopts, longind, long_only) + int argc; + char *const *argv; + const char *optstring; + const struct option *longopts; + int *longind; + int long_only; +{ + optarg = NULL; + + if (optind == 0 || !__getopt_initialized) + { + if (optind == 0) + optind = 1; /* Don't scan ARGV[0], the program name. */ + optstring = _getopt_initialize (argc, argv, optstring); + __getopt_initialized = 1; + } + + /* Test whether ARGV[optind] points to a non-option argument. + Either it does not have option syntax, or there is an environment flag + from the shell indicating it is not an option. The later information + is only used when the used in the GNU libc. */ +#ifdef _LIBC +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ + || (optind < nonoption_flags_len \ + && __getopt_nonoption_flags[optind] == '1')) +#else +# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') +#endif + + if (nextchar == NULL || *nextchar == '\0') + { + /* Advance to the next ARGV-element. */ + + /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been + moved back by the user (who may also have changed the arguments). */ + if (last_nonopt > optind) + last_nonopt = optind; + if (first_nonopt > optind) + first_nonopt = optind; + + if (ordering == PERMUTE) + { + /* If we have just processed some options following some non-options, + exchange them so that the options come first. */ + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (last_nonopt != optind) + first_nonopt = optind; + + /* Skip any additional non-options + and extend the range of non-options previously skipped. */ + + while (optind < argc && NONOPTION_P) + optind++; + last_nonopt = optind; + } + + /* The special ARGV-element `--' means premature end of options. + Skip it like a null option, + then exchange with previous non-options as if it were an option, + then skip everything else like a non-option. */ + + if (optind != argc && !strcmp (argv[optind], "--")) + { + optind++; + + if (first_nonopt != last_nonopt && last_nonopt != optind) + exchange ((char **) argv); + else if (first_nonopt == last_nonopt) + first_nonopt = optind; + last_nonopt = argc; + + optind = argc; + } + + /* If we have done all the ARGV-elements, stop the scan + and back over any non-options that we skipped and permuted. */ + + if (optind == argc) + { + /* Set the next-arg-index to point at the non-options + that we previously skipped, so the caller will digest them. */ + if (first_nonopt != last_nonopt) + optind = first_nonopt; + return -1; + } + + /* If we have come to a non-option and did not permute it, + either stop the scan or describe it to the caller and pass it by. */ + + if (NONOPTION_P) + { + if (ordering == REQUIRE_ORDER) + return -1; + optarg = argv[optind++]; + return 1; + } + + /* We have found another option-ARGV-element. + Skip the initial punctuation. */ + + nextchar = (argv[optind] + 1 + + (longopts != NULL && argv[optind][1] == '-')); + } + + /* Decode the current option-ARGV-element. */ + + /* Check whether the ARGV-element is a long option. + + If long_only and the ARGV-element has the form "-f", where f is + a valid short option, don't consider it an abbreviated form of + a long option that starts with f. Otherwise there would be no + way to give the -f short option. + + On the other hand, if there's a long option "fubar" and + the ARGV-element is "-fu", do consider that an abbreviation of + the long option, just like "--fu", and not "-f" with arg "u". + + This distinction seems to be the most useful approach. */ + + if (longopts != NULL + && (argv[optind][1] == '-' + || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = -1; + int option_index; + + for (nameend = nextchar; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) + == (unsigned int) strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, _("%s: option `%s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + optopt = 0; + return '?'; + } + + if (pfound != NULL) + { + option_index = indfound; + optind++; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + { + if (argv[optind - 1][1] == '-') + /* --option */ + fprintf (stderr, + _("%s: option `--%s' doesn't allow an argument\n"), + argv[0], pfound->name); + else + /* +option or -option */ + fprintf (stderr, + _("%s: option `%c%s' doesn't allow an argument\n"), + argv[0], argv[optind - 1][0], pfound->name); + + nextchar += strlen (nextchar); + + optopt = pfound->val; + return '?'; + } + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + optopt = pfound->val; + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + + /* Can't find it as a long option. If this is not getopt_long_only, + or the option starts with '--' or is not a valid short + option, then it's an error. + Otherwise interpret it as a short option. */ + if (!long_only || argv[optind][1] == '-' + || my_index (optstring, *nextchar) == NULL) + { + if (opterr) + { + if (argv[optind][1] == '-') + /* --option */ + fprintf (stderr, _("%s: unrecognized option `--%s'\n"), + argv[0], nextchar); + else + /* +option or -option */ + fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), + argv[0], argv[optind][0], nextchar); + } + nextchar = (char *) ""; + optind++; + optopt = 0; + return '?'; + } + } + + /* Look at and handle the next short option-character. */ + + { + char c = *nextchar++; + char *temp = my_index (optstring, c); + + /* Increment `optind' when we start to process its last character. */ + if (*nextchar == '\0') + ++optind; + + if (temp == NULL || c == ':') + { + if (opterr) + { + if (posixly_correct) + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: illegal option -- %c\n"), + argv[0], c); + else + fprintf (stderr, _("%s: invalid option -- %c\n"), + argv[0], c); + } + optopt = c; + return '?'; + } + /* Convenience. Treat POSIX -W foo same as long option --foo */ + if (temp[0] == 'W' && temp[1] == ';') + { + char *nameend; + const struct option *p; + const struct option *pfound = NULL; + int exact = 0; + int ambig = 0; + int indfound = 0; + int option_index; + + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + return c; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + + /* optarg is now the argument, see if it's in the + table of longopts. */ + + for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) + /* Do nothing. */ ; + + /* Test all long options for either exact match + or abbreviated matches. */ + for (p = longopts, option_index = 0; p->name; p++, option_index++) + if (!strncmp (p->name, nextchar, nameend - nextchar)) + { + if ((unsigned int) (nameend - nextchar) == strlen (p->name)) + { + /* Exact match found. */ + pfound = p; + indfound = option_index; + exact = 1; + break; + } + else if (pfound == NULL) + { + /* First nonexact match found. */ + pfound = p; + indfound = option_index; + } + else + /* Second or later nonexact match found. */ + ambig = 1; + } + if (ambig && !exact) + { + if (opterr) + fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), + argv[0], argv[optind]); + nextchar += strlen (nextchar); + optind++; + return '?'; + } + if (pfound != NULL) + { + option_index = indfound; + if (*nameend) + { + /* Don't test has_arg with >, because some C compilers don't + allow it to be used on enums. */ + if (pfound->has_arg) + optarg = nameend + 1; + else + { + if (opterr) + fprintf (stderr, _("\ +%s: option `-W %s' doesn't allow an argument\n"), + argv[0], pfound->name); + + nextchar += strlen (nextchar); + return '?'; + } + } + else if (pfound->has_arg == 1) + { + if (optind < argc) + optarg = argv[optind++]; + else + { + if (opterr) + fprintf (stderr, + _("%s: option `%s' requires an argument\n"), + argv[0], argv[optind - 1]); + nextchar += strlen (nextchar); + return optstring[0] == ':' ? ':' : '?'; + } + } + nextchar += strlen (nextchar); + if (longind != NULL) + *longind = option_index; + if (pfound->flag) + { + *(pfound->flag) = pfound->val; + return 0; + } + return pfound->val; + } + nextchar = NULL; + return 'W'; /* Let the application handle it. */ + } + if (temp[1] == ':') + { + if (temp[2] == ':') + { + /* This is an option that accepts an argument optionally. */ + if (*nextchar != '\0') + { + optarg = nextchar; + optind++; + } + else + optarg = NULL; + nextchar = NULL; + } + else + { + /* This is an option that requires an argument. */ + if (*nextchar != '\0') + { + optarg = nextchar; + /* If we end this ARGV-element by taking the rest as an arg, + we must advance to the next element now. */ + optind++; + } + else if (optind == argc) + { + if (opterr) + { + /* 1003.2 specifies the format of this message. */ + fprintf (stderr, + _("%s: option requires an argument -- %c\n"), + argv[0], c); + } + optopt = c; + if (optstring[0] == ':') + c = ':'; + else + c = '?'; + } + else + /* We already incremented `optind' once; + increment it again when taking next ARGV-elt as argument. */ + optarg = argv[optind++]; + nextchar = NULL; + } + } + return c; + } +} + +int +getopt (argc, argv, optstring) + int argc; + char *const *argv; + const char *optstring; +{ + return _getopt_internal (argc, argv, optstring, + (const struct option *) 0, + (int *) 0, + 0); +} + +#endif /* Not ELIDE_CODE. */ + +#ifdef TEST + +/* Compile with -DTEST to make an executable for use in testing + the above definition of `getopt'. */ + +int +main (argc, argv) + int argc; + char **argv; +{ + int c; + int digit_optind = 0; + + while (1) + { + int this_option_optind = optind ? optind : 1; + + c = getopt (argc, argv, "abc:d:0123456789"); + if (c == -1) + break; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (digit_optind != 0 && digit_optind != this_option_optind) + printf ("digits occur in two different argv-elements.\n"); + digit_optind = this_option_optind; + printf ("option %c\n", c); + break; + + case 'a': + printf ("option a\n"); + break; + + case 'b': + printf ("option b\n"); + break; + + case 'c': + printf ("option c with value `%s'\n", optarg); + break; + + case '?': + break; + + default: + printf ("?? getopt returned character code 0%o ??\n", c); + } + } + + if (optind < argc) + { + printf ("non-option ARGV-elements: "); + while (optind < argc) + printf ("%s ", argv[optind++]); + printf ("\n"); + } + + exit (0); +} + +#endif /* TEST */ diff --git a/getopt.h b/getopt.h new file mode 100644 index 0000000..a99a229 --- /dev/null +++ b/getopt.h @@ -0,0 +1,144 @@ +/* Declarations for getopt. + Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 2000, + 2002 Free Software Foundation, Inc. + + NOTE: The canonical source of this file is maintained with the GNU C Library. + Bugs can be reported to bug-glibc@gnu.org. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#ifndef _GETOPT_H +#define _GETOPT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +/* For communication from `getopt' to the caller. + When `getopt' finds an option that takes an argument, + the argument value is returned here. + Also, when `ordering' is RETURN_IN_ORDER, + each non-option ARGV-element is returned here. */ + +extern char *optarg; + +/* Index in ARGV of the next element to be scanned. + This is used for communication to and from the caller + and for communication between successive calls to `getopt'. + + On entry to `getopt', zero means this is the first call; initialize. + + When `getopt' returns -1, this is the index of the first of the + non-option elements that the caller should itself scan. + + Otherwise, `optind' communicates from one call to the next + how much of ARGV has been scanned so far. */ + +extern int optind; + +/* Callers store zero here to inhibit the error message `getopt' prints + for unrecognized options. */ + +extern int opterr; + +/* Set to an option character which was unrecognized. */ + +extern int optopt; + +/* Describe the long-named options requested by the application. + The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector + of `struct option' terminated by an element containing a name which is + zero. + + The field `has_arg' is: + no_argument (or 0) if the option does not take an argument, + required_argument (or 1) if the option requires an argument, + optional_argument (or 2) if the option takes an optional argument. + + If the field `flag' is not NULL, it points to a variable that is set + to the value given in the field `val' when the option is found, but + left unchanged if the option is not found. + + To have a long-named option do something other than set an `int' to + a compiled-in constant, such as set a value from `optarg', set the + option's `flag' field to zero and its `val' field to a nonzero + value (the equivalent single-letter option character, if there is + one). For long options that have a zero `flag' field, `getopt' + returns the contents of the `val' field. */ + +struct option +{ +#if defined (__STDC__) && __STDC__ + const char *name; +#else + char *name; +#endif + /* has_arg can't be an enum because some compilers complain about + type mismatches in all the code that assumes it is an int. */ + int has_arg; + int *flag; + int val; +}; + +/* Names for the values of the `has_arg' field of `struct option'. */ + +#define no_argument 0 +#define required_argument 1 +#define optional_argument 2 + +#if defined (__STDC__) && __STDC__ +/* HAVE_DECL_* is a three-state macro: undefined, 0 or 1. If it is + undefined, we haven't run the autoconf check so provide the + declaration without arguments. If it is 0, we checked and failed + to find the declaration so provide a fully prototyped one. If it + is 1, we found it so don't provide any declaration at all. */ +#if !HAVE_DECL_GETOPT +#if defined (__GNU_LIBRARY__) || defined (HAVE_DECL_GETOPT) +/* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in unistd.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ +extern int getopt (int argc, char *const *argv, const char *shortopts); +#else +#ifndef __cplusplus +extern int getopt (); +#endif /* __cplusplus */ +#endif +#endif /* !HAVE_DECL_GETOPT */ + +extern int getopt_long (int argc, char *const *argv, const char *shortopts, + const struct option *longopts, int *longind); +extern int getopt_long_only (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind); + +/* Internal only. Users should not call this directly. */ +extern int _getopt_internal (int argc, char *const *argv, + const char *shortopts, + const struct option *longopts, int *longind, + int long_only); +#else /* not __STDC__ */ +extern int getopt (); +extern int getopt_long (); +extern int getopt_long_only (); + +extern int _getopt_internal (); +#endif /* __STDC__ */ + +#ifdef __cplusplus +} +#endif + +#endif /* getopt.h */ diff --git a/ias.c b/ias.c index bf1fb11..5485a7d 100644 --- a/ias.c +++ b/ias.c @@ -1,60 +1,60 @@ - -/* - * sscep -- Simple SCEP client implementation - * Copyright (c) Jarkko Turkulainen 2003. All rights reserved. - * See the file COPYRIGHT for licensing information. - */ - - -/* - * Routines for pkcs7_issuer_and_subject data type needed when - * sending GETCertInitial requests. - */ - -#include "sscep.h" -#include "ias.h" - -int i2d_pkcs7_issuer_and_subject(pkcs7_issuer_and_subject *a, - unsigned char **pp) { - - M_ASN1_I2D_vars(a); - M_ASN1_I2D_len(a->issuer,i2d_X509_NAME); - M_ASN1_I2D_len(a->subject,i2d_X509_NAME); - M_ASN1_I2D_seq_total(); - M_ASN1_I2D_put(a->issuer,i2d_X509_NAME); - M_ASN1_I2D_put(a->subject,i2d_X509_NAME); - M_ASN1_I2D_finish(); -} - -pkcs7_issuer_and_subject * -d2i_pkcs7_issuer_and_subject(pkcs7_issuer_and_subject **a, - unsigned char **pp, long length) { - - M_ASN1_D2I_vars(a, pkcs7_issuer_and_subject *, - pkcs7_issuer_and_subject_new); - M_ASN1_D2I_Init(); - M_ASN1_D2I_start_sequence(); - M_ASN1_D2I_get(ret->issuer,d2i_X509_NAME); - M_ASN1_D2I_get(ret->subject,d2i_X509_NAME); - M_ASN1_D2I_Finish(a,pkcs7_issuer_and_subject_free, 99); -} - -pkcs7_issuer_and_subject *pkcs7_issuer_and_subject_new(void) { - - pkcs7_issuer_and_subject *ret=NULL; - ASN1_CTX c; - M_ASN1_New_Malloc(ret,pkcs7_issuer_and_subject); - M_ASN1_New(ret->issuer,X509_NAME_new); - M_ASN1_New(ret->subject,X509_NAME_new); - return(ret); - M_ASN1_New_Error(199); -} - -void pkcs7_issuer_and_subject_free(pkcs7_issuer_and_subject *a) { - - if (a == NULL) return; - X509_NAME_free(a->issuer); - M_ASN1_INTEGER_free(a->subject); - OPENSSL_free(a); -} - + +/* + * sscep -- Simple SCEP client implementation + * Copyright (c) Jarkko Turkulainen 2003. All rights reserved. + * See the file COPYRIGHT for licensing information. + */ + + +/* + * Routines for pkcs7_issuer_and_subject data type needed when + * sending GETCertInitial requests. + */ + +#include "sscep.h" +#include "ias.h" + +int i2d_pkcs7_issuer_and_subject(pkcs7_issuer_and_subject *a, + unsigned char **pp) { + + M_ASN1_I2D_vars(a); + M_ASN1_I2D_len(a->issuer,i2d_X509_NAME); + M_ASN1_I2D_len(a->subject,i2d_X509_NAME); + M_ASN1_I2D_seq_total(); + M_ASN1_I2D_put(a->issuer,i2d_X509_NAME); + M_ASN1_I2D_put(a->subject,i2d_X509_NAME); + M_ASN1_I2D_finish(); +} + +pkcs7_issuer_and_subject * +d2i_pkcs7_issuer_and_subject(pkcs7_issuer_and_subject **a, + unsigned char **pp, long length) { + + M_ASN1_D2I_vars(a, pkcs7_issuer_and_subject *, + pkcs7_issuer_and_subject_new); + M_ASN1_D2I_Init(); + M_ASN1_D2I_start_sequence(); + M_ASN1_D2I_get(ret->issuer,d2i_X509_NAME); + M_ASN1_D2I_get(ret->subject,d2i_X509_NAME); + M_ASN1_D2I_Finish(a,pkcs7_issuer_and_subject_free, 99); +} + +pkcs7_issuer_and_subject *pkcs7_issuer_and_subject_new(void) { + + pkcs7_issuer_and_subject *ret=NULL; + ASN1_CTX c; + M_ASN1_New_Malloc(ret,pkcs7_issuer_and_subject); + M_ASN1_New(ret->issuer,X509_NAME_new); + M_ASN1_New(ret->subject,X509_NAME_new); + return(ret); + M_ASN1_New_Error(199); +} + +void pkcs7_issuer_and_subject_free(pkcs7_issuer_and_subject *a) { + + if (a == NULL) return; + X509_NAME_free(a->issuer); + M_ASN1_INTEGER_free(a->subject); + OPENSSL_free(a); +} + diff --git a/ias.h b/ias.h index 470d908..a8b7ad2 100644 --- a/ias.h +++ b/ias.h @@ -1,23 +1,23 @@ - -/* - * sscep -- Simple SCEP client implementation - * Copyright (c) Jarkko Turkulainen 2003. All rights reserved. - * See the file COPYRIGHT for licensing information. - */ - -/* Macros */ - -#define i2d_pkcs7_issuer_and_subject_bio(bp, ias) \ - ASN1_i2d_bio(i2d_pkcs7_issuer_and_subject, bp, (unsigned char *)ias) -#define i2d_PKCS7_ISSUER_AND_SERIAL_bio(bp, ias) \ - ASN1_i2d_bio(i2d_PKCS7_ISSUER_AND_SERIAL, bp, (unsigned char *)ias) - -/* Routines */ -int i2d_pkcs7_issuer_and_subject(pkcs7_issuer_and_subject *, unsigned char **); -pkcs7_issuer_and_subject * -d2i_pkcs7_issuer_and_subject(pkcs7_issuer_and_subject **, unsigned char **, - long length); -pkcs7_issuer_and_subject *pkcs7_issuer_and_subject_new(void); -void pkcs7_issuer_and_subject_free(pkcs7_issuer_and_subject *); - - + +/* + * sscep -- Simple SCEP client implementation + * Copyright (c) Jarkko Turkulainen 2003. All rights reserved. + * See the file COPYRIGHT for licensing information. + */ + +/* Macros */ + +#define i2d_pkcs7_issuer_and_subject_bio(bp, ias) \ + ASN1_i2d_bio(i2d_pkcs7_issuer_and_subject, bp, (unsigned char *)ias) +#define i2d_PKCS7_ISSUER_AND_SERIAL_bio(bp, ias) \ + ASN1_i2d_bio(i2d_PKCS7_ISSUER_AND_SERIAL, bp, (unsigned char *)ias) + +/* Routines */ +int i2d_pkcs7_issuer_and_subject(pkcs7_issuer_and_subject *, unsigned char **); +pkcs7_issuer_and_subject * +d2i_pkcs7_issuer_and_subject(pkcs7_issuer_and_subject **, unsigned char **, + long length); +pkcs7_issuer_and_subject *pkcs7_issuer_and_subject_new(void); +void pkcs7_issuer_and_subject_free(pkcs7_issuer_and_subject *); + + diff --git a/init.c b/init.c index 72ec427..f78030a 100644 --- a/init.c +++ b/init.c @@ -7,6 +7,9 @@ /* Configuration file initialization */ #include "sscep.h" +#ifdef WIN32 +#define strdup(str) _strdup(str) +#endif void init_config(FILE *conf) { diff --git a/net.c b/net.c index beaf26d..9520ae2 100644 --- a/net.c +++ b/net.c @@ -11,6 +11,21 @@ #include "sscep.h" +#ifdef WIN32 +void perror_w32 (const char *message) +{ + char buffer[BUFSIZ]; + + /* letzten Fehlertext holen und formatieren */ + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, (LPWSTR) buffer, + sizeof buffer, NULL); + fprintf(stderr, "%s: %s", message, buffer); +} + +#define perror perror_w32 + +#endif + int send_msg(struct http_reply *http,char *msg,char *host,int port,int operation) { int sd, rc, used, bytes; @@ -18,6 +33,14 @@ send_msg(struct http_reply *http,char *msg,char *host,int port,int operation) { struct hostent *h; char tmp[1024], *buf, *p; +#ifdef WIN32 + int tv=timeout*1000; +#else + struct timeval tv; + tv.tv_sec = timeout; + tv.tv_usec = 0; +#endif + /* resolve name */ h = gethostbyname(host); if (h == NULL) { @@ -37,7 +60,7 @@ send_msg(struct http_reply *http,char *msg,char *host,int port,int operation) { perror("cannot open socket "); return (1); } - + /* bind any port number */ localAddr.sin_family = AF_INET; localAddr.sin_addr.s_addr = htonl(INADDR_ANY); @@ -48,39 +71,52 @@ send_msg(struct http_reply *http,char *msg,char *host,int port,int operation) { perror("error "); return (1); } - + /* connect to server */ - alarm(timeout); + /* The two socket options SO_RCVTIMEO and SO_SNDTIMEO do not work with connect + connect has a default timeout of 120 */ rc = connect(sd, (struct sockaddr *) &servAddr, sizeof(servAddr)); - alarm(0); if (rc < 0) { perror("cannot connect"); return (1); } - + setsockopt(sd,SOL_SOCKET, SO_RCVTIMEO,(void *)&tv, sizeof(tv)); + setsockopt(sd,SOL_SOCKET, SO_SNDTIMEO,(void *)&tv, sizeof(tv)); /* send data */ - alarm(timeout); - rc = send(sd, msg, sizeof(char) * strlen(msg), 0); - alarm(0); + rc = send(sd, msg,strlen(msg), 0); if (rc < 0) { perror("cannot send data "); close(sd); return (1); } - + else if(rc != strlen(msg)) + { + fprintf(stderr,"incomplete send\n"); + close(sd); + return (1); + } + /* Get response */ - alarm(timeout); buf = (char *)malloc(1024); used = 0; - while ((bytes = read(sd, &buf[used], 1024)) > 0) { + while ((bytes = recv(sd,&buf[used],1024,0)) > 0) { used += bytes; buf = (char *)realloc(buf, used + 1024); - } - alarm(0); + } + if (bytes < 0) { + perror("error receiving data "); + close(sd); + return (1); + } buf[used] = '\0'; - + + /* Fetch the status code: */ + #ifdef WIN32 + sscanf(buf, "%s %d ", tmp, &http->status); + #else sscanf(buf, "%s %d ", tmp, &http->status); + #endif if (v_flag) fprintf(stdout, "%s: server returned status code %d\n", pname, http->status); @@ -140,7 +176,11 @@ send_msg(struct http_reply *http,char *msg,char *host,int port,int operation) { fprintf(stderr, "%s: cannot find data from http reply\n",pname); } +#ifdef WIN32 + closesocket(sd); +#else close(sd); +#endif return (0); mime_err: @@ -153,7 +193,7 @@ send_msg(struct http_reply *http,char *msg,char *host,int port,int operation) { char * url_encode(char *s, size_t n) { char *r; size_t len; - int i; + unsigned int i; char ch[2]; /* Allocate 2 times bigger space than the original string */ @@ -162,27 +202,56 @@ char * url_encode(char *s, size_t n) { if (r == NULL) { return NULL; } +#ifdef WIN32 + strcpy_s(r, sizeof(r), ""); +#else strcpy(r, ""); +#endif /* Copy data */ for (i = 0; i < n; i++) { switch (*(s+i)) { case '+': +#ifdef WIN32 + //strncat_s(r, sizeof(r), "%2B", len); + strncat(r, "%2B", len); +#else strncat(r, "%2B", len); +#endif break; case '-': +#ifdef WIN32 + //strncat_s(r, sizeof(r), "%2D", len); strncat(r, "%2D", len); +#else + strncat(r, "%2D", len); +#endif break; case '=': - strncat(r, "%3D", len); +#ifdef WIN32 + //strncat_s(r, sizeof(r), "%3D", len); + strncat(r, "32D", len); +#else + strncat(r, "32D", len); +#endif break; case '\n': +#ifdef WIN32 + //strncat_s(r, sizeof(r), "%0A", len); + strncat(r, "%0A", len); +#else strncat(r, "%0A", len); +#endif break; default: ch[0] = *(s+i); ch[1] = '\0'; +#ifdef WIN32 + //strncat_s(r, sizeof(r), ch, len); + strncat(r, ch, len); +#else strncat(r, ch, len); +#endif break; } } diff --git a/pkcs7.c b/pkcs7.c index 7550a2e..6c8c295 100644 --- a/pkcs7.c +++ b/pkcs7.c @@ -1,734 +1,734 @@ -/* - * sscep -- Simple SCEP client implementation - * Copyright (c) Jarkko Turkulainen 2003. All rights reserved. - * See the file COPYRIGHT for licensing information. - */ - -/* PKCS#7 routines */ - -#include "sscep.h" -#include "ias.h" - -/* - * Wrap data in PKCS#7 envelopes and base64-encode the result. - * Data is PKCS#10 request in PKCSReq, or pkcs7_issuer_and_subject - * structure in GetCertInitial and PKCS7_ISSUER_AND_SERIAL in - * GetCert and GETCrl. - */ -int pkcs7_wrap(struct scep *s) { - BIO *databio = NULL; - BIO *encbio = NULL; - BIO *pkcs7bio = NULL; - BIO *memorybio = NULL; - BIO *outbio = NULL; - BIO *base64bio = NULL; - unsigned char *buffer = NULL; - int rc, len = 0; - STACK_OF(X509) *recipients; - PKCS7 *p7enc; - PKCS7_SIGNER_INFO *si; - STACK_OF(X509_ATTRIBUTE) *attributes; - X509 *signercert = NULL; - EVP_PKEY *signerkey = NULL; - - /* Create a new sender nonce for all messages - * XXXXXXXXXXXXXX should it be per transaction? */ - s->sender_nonce_len = 16; - s->sender_nonce = (unsigned char *)malloc(s->sender_nonce_len); - RAND_bytes(s->sender_nonce, s->sender_nonce_len); - - /* Prepare data payload */ - switch(s->request_type) { - case SCEP_REQUEST_PKCSREQ: - /* - * Set printable message type - * We set this later as an autheticated attribute - * "messageType". - */ - s->request_type_str = SCEP_REQUEST_PKCSREQ_STR; - - /* Signer cert */ - signercert = s->signercert; - signerkey = s->signerkey; - - /* Create inner PKCS#7 */ - if (v_flag) - printf("%s: creating inner PKCS#7\n", pname); - - /* Read request in memory bio */ - databio = BIO_new(BIO_s_mem()); - if ((rc = i2d_X509_REQ_bio(databio, request)) <= 0) { - fprintf(stderr, "%s: error writing " - "certificate request in bio\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - BIO_flush(databio); - BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); - break; - - case SCEP_REQUEST_GETCERTINIT: - - /* Set printable message type */ - s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR; - - /* Signer cert */ - signercert = s->signercert; - signerkey = s->signerkey; - - /* Create inner PKCS#7 */ - if (v_flag) - printf("%s: creating inner PKCS#7\n", pname); - - /* Read data in memory bio */ - databio = BIO_new(BIO_s_mem()); - if ((rc = i2d_pkcs7_issuer_and_subject_bio(databio, - s->ias_getcertinit)) <= 0) { - fprintf(stderr, "%s: error writing " - "GetCertInitial data in bio\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - BIO_flush(databio); - BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); - break; - - case SCEP_REQUEST_GETCERT: - /* Set printable message type */ - s->request_type_str = SCEP_REQUEST_GETCERT_STR; - - /* Signer cert */ - signercert = localcert; - signerkey = rsa; - - /* Read data in memory bio */ - databio = BIO_new(BIO_s_mem()); - if ((rc = i2d_PKCS7_ISSUER_AND_SERIAL_bio(databio, - s->ias_getcert)) <= 0) { - fprintf(stderr, "%s: error writing " - "GetCert data in bio\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - BIO_flush(databio); - BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); - break; - - case SCEP_REQUEST_GETCRL: - /* Set printable message type */ - s->request_type_str = SCEP_REQUEST_GETCRL_STR; - - /* Signer cert */ - signercert = localcert; - signerkey = rsa; - - /* Read data in memory bio */ - databio = BIO_new(BIO_s_mem()); - if ((rc = i2d_PKCS7_ISSUER_AND_SERIAL_bio(databio, - s->ias_getcrl)) <= 0) { - fprintf(stderr, "%s: error writing " - "GetCert data in bio\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - BIO_flush(databio); - BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); - break; - } - /* Below this is the common code for all request_type */ - - /* Read in the payload */ - s->request_len = BIO_get_mem_data(databio, &s->request_payload); - if (v_flag) - printf("%s: data payload size: %d bytes\n", pname, - s->request_len); - BIO_free(databio); - - /* Create encryption certificate stack */ - if ((recipients = sk_X509_new(NULL)) == NULL) { - fprintf(stderr, "%s: error creating " - "certificate stack\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - /* Use different CA cert for encryption if requested */ - if (e_flag) { - if (sk_X509_push(recipients, encert) <= 0) { - fprintf(stderr, "%s: error adding recipient encryption " - "certificate\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - /* Use same CA cert also for encryption */ - } else { - if (sk_X509_push(recipients, cacert) <= 0) { - fprintf(stderr, "%s: error adding recipient encryption " - "certificate\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - } - - /* Create BIO for encryption */ - if ((encbio = BIO_new_mem_buf(s->request_payload, - s->request_len)) == NULL) { - fprintf(stderr, "%s: error creating data " "bio\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - - /* Encrypt */ - if (!(p7enc = PKCS7_encrypt(recipients, encbio, - enc_alg, PKCS7_BINARY))) { - fprintf(stderr, "%s: request payload encrypt failed\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - if (v_flag) - printf("%s: successfully encrypted payload\n", pname); - - /* Write encrypted data */ - memorybio = BIO_new(BIO_s_mem()); - if (i2d_PKCS7_bio(memorybio, p7enc) <= 0) { - fprintf(stderr, "%s: error writing encrypted data\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - BIO_flush(memorybio); - BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); - len = BIO_get_mem_data(memorybio, &buffer); - if (v_flag) - printf("%s: envelope size: %d bytes\n", pname, len); - if (d_flag) { - printf("%s: printing PEM fomatted PKCS#7\n", pname); - PEM_write_PKCS7(stdout, p7enc); - } - BIO_free(memorybio); - - /* Create outer PKCS#7 */ - if (v_flag) - printf("%s: creating outer PKCS#7\n", pname); - s->request_p7 = PKCS7_new(); - if (s->request_p7 == NULL) { - fprintf(stderr, "%s: failed creating PKCS#7 for signing\n", - pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed)) { - fprintf(stderr, "%s: failed setting PKCS#7 type\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - - /* Add signer certificate and signature */ - PKCS7_add_certificate(s->request_p7, signercert); - if ((si = PKCS7_add_signature(s->request_p7, - signercert, signerkey, sig_alg)) == NULL) { - fprintf(stderr, "%s: error adding PKCS#7 signature\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - if (v_flag) - printf("%s: signature added successfully\n", pname); - - /* Set signed attributes */ - if (v_flag) - printf("%s: adding signed attributes\n", pname); - attributes = sk_X509_ATTRIBUTE_new_null(); - add_attribute_string(attributes, nid_transId, s->transaction_id); - add_attribute_string(attributes, nid_messageType, s->request_type_str); - add_attribute_octet(attributes, nid_senderNonce, s->sender_nonce, - s->sender_nonce_len); - PKCS7_set_signed_attributes(si, attributes); - - /* Add contentType */ - if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, - V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) { - fprintf(stderr, "%s: error adding NID_pkcs9_contentType\n", - pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - - /* Create new content */ - if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data)) { - fprintf(stderr, "%s: failed setting PKCS#7 content type\n", - pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - - /* Write data */ - pkcs7bio = PKCS7_dataInit(s->request_p7, NULL); - if (pkcs7bio == NULL) { - fprintf(stderr, "%s: error opening bio for writing PKCS#7 " - "data\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - if (len != BIO_write(pkcs7bio, buffer, len)) { - fprintf(stderr, "%s: error writing PKCS#7 data\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - if (v_flag) - printf("%s: PKCS#7 data written successfully\n", pname); - - /* Finalize PKCS#7 */ - if (!PKCS7_dataFinal(s->request_p7, pkcs7bio)) { - fprintf(stderr, "%s: error finalizing outer PKCS#7\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - if (d_flag) { - printf("%s: printing PEM fomatted PKCS#7\n", pname); - PEM_write_PKCS7(stdout, s->request_p7); - } - - /* base64-encode the data */ - if (v_flag) - printf("%s: applying base64 encoding\n",pname); - - /* Create base64 filtering bio */ - memorybio = BIO_new(BIO_s_mem()); - base64bio = BIO_new(BIO_f_base64()); - outbio = BIO_push(base64bio, memorybio); - - /* Copy PKCS#7 */ - i2d_PKCS7_bio(outbio, s->request_p7); - BIO_flush(outbio); - BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); - s->request_len = BIO_get_mem_data(memorybio, &s->request_payload); - if (v_flag) - printf("%s: base64 encoded payload size: %d bytes\n", - pname, s->request_len); - BIO_free(outbio); - - return (0); -} - -/* - * Unwrap PKCS#7 data and decrypt if necessary - */ -int pkcs7_unwrap(struct scep *s) { - BIO *memorybio; - BIO *outbio; - BIO *pkcs7bio; - int i, len, bytes, used; - STACK_OF(PKCS7_SIGNER_INFO) *sk; - PKCS7 *p7enc; - PKCS7_SIGNER_INFO *si; - STACK_OF(X509_ATTRIBUTE) *attribs; - char *p; - unsigned char buffer[1024]; - X509 *recipientcert; - EVP_PKEY *recipientkey; - - /* Create new memory BIO for outer PKCS#7 */ - memorybio = BIO_new(BIO_s_mem()); - - /* Read in data */ - if (v_flag) - printf("%s: reading outer PKCS#7\n",pname); - if ((len = BIO_write(memorybio, s->reply_payload, s->reply_len)) <= 0) { - fprintf(stderr, "%s: error reading PKCS#7 data\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - if (v_flag) - printf("%s: PKCS#7 payload size: %d bytes\n", pname, len); - BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); - s->reply_p7 = d2i_PKCS7_bio(memorybio, NULL); - if (d_flag) { - printf("%s: printing PEM fomatted PKCS#7\n", pname); - PEM_write_PKCS7(stdout, s->reply_p7); - } - - /* Make sure this is a signed PKCS#7 */ - if (!PKCS7_type_is_signed(s->reply_p7)) { - fprintf(stderr, "%s: PKCS#7 is not signed!\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - - /* Create BIO for content data */ - pkcs7bio = PKCS7_dataInit(s->reply_p7, NULL); - if (pkcs7bio == NULL) { - fprintf(stderr, "%s: cannot get PKCS#7 data\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - - /* Copy enveloped data from PKCS#7 */ - outbio = BIO_new(BIO_s_mem()); - used = 0; - for (;;) { - bytes = BIO_read(pkcs7bio, buffer, sizeof(buffer)); - used += bytes; - if (bytes <= 0) break; - BIO_write(outbio, buffer, bytes); - } - BIO_flush(outbio); - if (v_flag) - printf("%s: PKCS#7 contains %d bytes of enveloped data\n", - pname, used); - - /* Get signer */ - sk = PKCS7_get_signer_info(s->reply_p7); - if (sk == NULL) { - fprintf(stderr, "%s: cannot get signer info!\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - - /* Verify signature */ - if (v_flag) - printf("%s: verifying signature\n", pname); - si = sk_PKCS7_SIGNER_INFO_value(sk, 0); - if (PKCS7_signatureVerify(pkcs7bio, s->reply_p7, si, cacert) <= 0) { - fprintf(stderr, "%s: error verifying signature\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - if (v_flag) - printf("%s: signature ok\n", pname); - - /* Get signed attributes */ - if (v_flag) - printf("%s: finding signed attributes\n", pname); - attribs = PKCS7_get_signed_attributes(si); - if (attribs == NULL) { - fprintf(stderr, "%s: no attributes found\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - - /* Transaction id */ - if ((get_signed_attribute(attribs, nid_transId, - V_ASN1_PRINTABLESTRING, &p)) == 1) { - fprintf(stderr, "%s: cannot find transId\n", pname); - exit (SCEP_PKISTATUS_P7); - } - if (v_flag) - printf("%s: reply transaction id: %s\n", pname, p); - if (strncmp(s->transaction_id, p, strlen(p))) { - fprintf(stderr, "%s: transaction id mismatch\n", pname); - exit (SCEP_PKISTATUS_P7); - } - /* Message type, should be of type CertRep */ - if ((i = get_signed_attribute(attribs, nid_messageType, - V_ASN1_PRINTABLESTRING, &p)) == 1) { - fprintf(stderr, "%s: cannot find messageType\n", pname); - exit (SCEP_PKISTATUS_P7); - } - if (atoi(p) != 3) { - fprintf(stderr, "%s: wrong message type in reply\n", pname); - exit (SCEP_PKISTATUS_P7); - } - if (v_flag) - printf("%s: reply message type is good\n", pname); - - /* Sender and recipient nonces: */ - if ((i = get_signed_attribute(attribs, nid_senderNonce, - V_ASN1_OCTET_STRING, &p)) == 1) { - if (v_flag) - fprintf(stderr, "%s: cannot find senderNonce\n", pname); - /* Some implementations don't put in on reply */ - /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXX - exit (SCEP_PKISTATUS_P7); */ - } - s->reply_sender_nonce = p; - if (v_flag) { - printf("%s: senderNonce in reply: ", pname); - for (i = 0; i < 16; i++) { - printf("%02X", s->reply_sender_nonce[i]); - } - printf("\n"); - } - if (( i = get_signed_attribute(attribs, nid_recipientNonce, - V_ASN1_OCTET_STRING, &p)) == 1) { - fprintf(stderr, "%s: cannot find recipientNonce\n", pname); - exit (SCEP_PKISTATUS_P7); - } - s->reply_recipient_nonce = p; - if (v_flag) { - printf("%s: recipientNonce in reply: ", pname); - for (i = 0; i < 16; i++) { - printf("%02X", s->reply_recipient_nonce[i]); - } - printf("\n"); - } - /* - * Compare recipient nonce to original sender nonce - * The draft says nothing about this, but it makes sense to me.. - * XXXXXXXXXXXXXX check - */ - for (i = 0; i < 16; i++) { - if (s->sender_nonce[i] != s->reply_recipient_nonce[i]) { - if (v_flag) - fprintf(stderr, "%s: corrupted nonce " - "received\n", pname); - /* Instead of exit, break out */ - break; - } - } - /* Get pkiStatus */ - if ((i = get_signed_attribute(attribs, nid_pkiStatus, - V_ASN1_PRINTABLESTRING, &p)) == 1) { - fprintf(stderr, "%s: cannot find pkiStatus\n", pname); - /* This is a mandatory attribute.. */ - exit (SCEP_PKISTATUS_P7); - } - switch (atoi(p)) { - case SCEP_PKISTATUS_SUCCESS: - printf("%s: pkistatus: SUCCESS\n",pname); - s->pki_status = SCEP_PKISTATUS_SUCCESS; - break; - case SCEP_PKISTATUS_FAILURE: - printf("%s: pkistatus: FAILURE\n",pname); - s->pki_status = SCEP_PKISTATUS_FAILURE; - break; - case SCEP_PKISTATUS_PENDING: - printf("%s: pkistatus: PENDING\n",pname); - s->pki_status = SCEP_PKISTATUS_PENDING; - break; - default: - fprintf(stderr, "%s: wrong pkistatus in reply\n",pname); - exit (SCEP_PKISTATUS_P7); - } - - /* Get failInfo */ - if (s->pki_status == SCEP_PKISTATUS_FAILURE) { - if ((i = get_signed_attribute(attribs, nid_failInfo, - V_ASN1_PRINTABLESTRING, &p)) == 1) { - fprintf(stderr, "%s: cannot find failInfo\n", - pname); - exit (SCEP_PKISTATUS_P7); - } - switch (atoi(p)) { - case SCEP_FAILINFO_BADALG: - s->fail_info = SCEP_FAILINFO_BADALG; - printf("%s: reason: %s\n", pname, - SCEP_FAILINFO_BADALG_STR); - break; - case SCEP_FAILINFO_BADMSGCHK: - s->fail_info = SCEP_FAILINFO_BADMSGCHK; - printf("%s: reason: %s\n", pname, - SCEP_FAILINFO_BADMSGCHK_STR); - break; - case SCEP_FAILINFO_BADREQ: - s->fail_info = SCEP_FAILINFO_BADREQ; - printf("%s: reason: %s\n", pname, - SCEP_FAILINFO_BADREQ_STR); - break; - case SCEP_FAILINFO_BADTIME: - s->fail_info = SCEP_FAILINFO_BADTIME; - printf("%s: reason: %s\n", pname, - SCEP_FAILINFO_BADTIME_STR); - break; - case SCEP_FAILINFO_BADCERTID: - s->fail_info = SCEP_FAILINFO_BADCERTID; - printf("%s: reason: %s\n", pname, - SCEP_FAILINFO_BADCERTID_STR); - break; - default: - fprintf(stderr, "%s: wrong failInfo in " "reply\n",pname); - exit (SCEP_PKISTATUS_P7); - } - } - /* If FAILURE or PENDING, we can return */ - if (s->pki_status != SCEP_PKISTATUS_SUCCESS) { - /* There shouldn't be any more data... */ - if (v_flag && (used != 0)) { - fprintf(stderr, "%s: illegal size of payload\n", pname); - } - return (0); - } - /* We got success and expect data */ - if (used == 0) { - fprintf(stderr, "%s: illegal size of payload\n", pname); - exit (SCEP_PKISTATUS_P7); - } - - /* Decrypt the inner PKCS#7 */ - if ((s->request_type == SCEP_REQUEST_PKCSREQ) || - (s->request_type == SCEP_REQUEST_GETCERTINIT)) { - recipientcert = s->signercert; - recipientkey = s->signerkey; - } - else { - recipientcert = localcert; - recipientkey = rsa; - } - if (v_flag) - printf("%s: reading inner PKCS#7\n",pname); - p7enc = d2i_PKCS7_bio(outbio, NULL); - if (p7enc == NULL) { - fprintf(stderr, "%s: cannot read inner PKCS#7\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - if (d_flag) { - printf("%s: printing PEM fomatted PKCS#7\n", pname); - PEM_write_PKCS7(stdout, p7enc); - } - - /* Decrypt the data */ - outbio = BIO_new(BIO_s_mem()); - if (v_flag) - printf("%s: decrypting inner PKCS#7\n",pname); - if (PKCS7_decrypt(p7enc, recipientkey, recipientcert, outbio, 0) == 0) { - fprintf(stderr, "%s: error decrypting inner PKCS#7\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - BIO_flush(outbio); - - /* Write decrypted data */ - s->reply_len = BIO_get_mem_data(outbio, &s->reply_payload); - if (v_flag) - printf("%s: PKCS#7 payload size: %d bytes\n", pname, - s->reply_len); - BIO_set_flags(outbio, BIO_FLAGS_MEM_RDONLY); - s->reply_p7 = d2i_PKCS7_bio(outbio, NULL); - - return (0); - -} - -/* Add signed attributes */ -int -add_attribute_string(STACK_OF(X509_ATTRIBUTE) *attrs, int nid, char *buffer) { - ASN1_STRING *asn1_string = NULL; - X509_ATTRIBUTE *x509_a; - int c; - - if (v_flag) - printf("%s: adding string attribute %s\n", pname, - OBJ_nid2sn(nid)); - - asn1_string = ASN1_STRING_new(); - if ((c = ASN1_STRING_set(asn1_string, buffer, strlen(buffer))) <= 0) { - fprintf(stderr, "%s: error adding data to ASN.1 string\n", - pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - x509_a = X509_ATTRIBUTE_create(nid, V_ASN1_PRINTABLESTRING, - asn1_string); - sk_X509_ATTRIBUTE_push(attrs, x509_a); - - return (0); - -} -int -add_attribute_octet(STACK_OF(X509_ATTRIBUTE) *attrs, int nid, char *buffer, - int len) { - ASN1_STRING *asn1_string = NULL; - X509_ATTRIBUTE *x509_a; - int c; - - if (v_flag) - printf("%s: adding octet attribute %s\n", pname, - OBJ_nid2sn(nid)); - - asn1_string = ASN1_STRING_new(); - if ((c = ASN1_STRING_set(asn1_string, buffer, len)) <= 0) { - fprintf(stderr, "%s: error adding data to ASN.1 string\n", - pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - x509_a = X509_ATTRIBUTE_create(nid, V_ASN1_OCTET_STRING, - asn1_string); - sk_X509_ATTRIBUTE_push(attrs, x509_a); - - return (0); - -} - -/* Find signed attributes */ -int -get_signed_attribute(STACK_OF(X509_ATTRIBUTE) *attribs, int nid, - int type, char **buffer) { - int rc; - ASN1_TYPE *asn1_type; - unsigned int len; - - /* Find attribute */ - rc = get_attribute(attribs, nid, &asn1_type); - if (rc == 1) { - if (v_flag) - fprintf(stderr, "%s: error finding attribute\n",pname); - return (1); - } - if (ASN1_TYPE_get(asn1_type) != type) { - fprintf(stderr, "%s: wrong ASN.1 type\n",pname); - exit (SCEP_PKISTATUS_P7); - } - - /* Copy data */ - len = ASN1_STRING_length(asn1_type->value.asn1_string); - if (len <= 0) { - return (1); - } else if (v_flag) - printf("%s: allocating %d bytes for attribute\n", pname, len); - if (type == V_ASN1_PRINTABLESTRING) { - *buffer = (unsigned char *)malloc(len + 1); - } else { - *buffer = (unsigned char *)malloc(len); - } - if (*buffer == NULL) { - fprintf(stderr, "%s: cannot malloc space for attribute\n", - pname); - exit (SCEP_PKISTATUS_P7); - } - memcpy(*buffer, ASN1_STRING_data(asn1_type->value.asn1_string), len); - - /* Add null terminator if it's a PrintableString */ - if (type == V_ASN1_PRINTABLESTRING) { - (*buffer)[len] = 0; - len++; - } - - return (0); -} -int -get_attribute(STACK_OF(X509_ATTRIBUTE) *attribs, int required_nid, - ASN1_TYPE **asn1_type) { - int i; - ASN1_OBJECT *asn1_obj = NULL; - X509_ATTRIBUTE *x509_attrib = NULL; - - if (v_flag) - printf("%s: finding attribute %s\n", pname, - OBJ_nid2sn(required_nid)); - *asn1_type = NULL; - asn1_obj = OBJ_nid2obj(required_nid); - if (asn1_obj == NULL) { - fprintf(stderr, "%s: error creating ASN.1 object\n", pname); - ERR_print_errors_fp(stderr); - exit (SCEP_PKISTATUS_P7); - } - /* Find attribute */ - for (i = 0; i < sk_X509_ATTRIBUTE_num(attribs); i++) { - x509_attrib = sk_X509_ATTRIBUTE_value(attribs, i); - if (OBJ_cmp(x509_attrib->object, asn1_obj) == 0) { - if ((x509_attrib->value.set) && - (sk_ASN1_TYPE_num(x509_attrib->value.set) != 0)) { - if (*asn1_type != NULL) { - fprintf(stderr, "%s: no value found", - pname); - exit (SCEP_PKISTATUS_P7); - } - *asn1_type = - sk_ASN1_TYPE_value(x509_attrib->value.set, 0); - } - } - } - - if (*asn1_type == NULL) - return (1); - return (0); -} +/* + * sscep -- Simple SCEP client implementation + * Copyright (c) Jarkko Turkulainen 2003. All rights reserved. + * See the file COPYRIGHT for licensing information. + */ + +/* PKCS#7 routines */ + +#include "sscep.h" +#include "ias.h" + +/* + * Wrap data in PKCS#7 envelopes and base64-encode the result. + * Data is PKCS#10 request in PKCSReq, or pkcs7_issuer_and_subject + * structure in GetCertInitial and PKCS7_ISSUER_AND_SERIAL in + * GetCert and GETCrl. + */ +int pkcs7_wrap(struct scep *s) { + BIO *databio = NULL; + BIO *encbio = NULL; + BIO *pkcs7bio = NULL; + BIO *memorybio = NULL; + BIO *outbio = NULL; + BIO *base64bio = NULL; + unsigned char *buffer = NULL; + int rc, len = 0; + STACK_OF(X509) *recipients; + PKCS7 *p7enc; + PKCS7_SIGNER_INFO *si; + STACK_OF(X509_ATTRIBUTE) *attributes; + X509 *signercert = NULL; + EVP_PKEY *signerkey = NULL; + + /* Create a new sender nonce for all messages + * XXXXXXXXXXXXXX should it be per transaction? */ + s->sender_nonce_len = 16; + s->sender_nonce = (unsigned char *)malloc(s->sender_nonce_len); + RAND_bytes(s->sender_nonce, s->sender_nonce_len); + + /* Prepare data payload */ + switch(s->request_type) { + case SCEP_REQUEST_PKCSREQ: + /* + * Set printable message type + * We set this later as an autheticated attribute + * "messageType". + */ + s->request_type_str = SCEP_REQUEST_PKCSREQ_STR; + + /* Signer cert */ + signercert = s->signercert; + signerkey = s->signerkey; + + /* Create inner PKCS#7 */ + if (v_flag) + printf("%s: creating inner PKCS#7\n", pname); + + /* Read request in memory bio */ + databio = BIO_new(BIO_s_mem()); + if ((rc = i2d_X509_REQ_bio(databio, request)) <= 0) { + fprintf(stderr, "%s: error writing " + "certificate request in bio\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + BIO_flush(databio); + BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); + break; + + case SCEP_REQUEST_GETCERTINIT: + + /* Set printable message type */ + s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR; + + /* Signer cert */ + signercert = s->signercert; + signerkey = s->signerkey; + + /* Create inner PKCS#7 */ + if (v_flag) + printf("%s: creating inner PKCS#7\n", pname); + + /* Read data in memory bio */ + databio = BIO_new(BIO_s_mem()); + if ((rc = i2d_pkcs7_issuer_and_subject_bio(databio, + s->ias_getcertinit)) <= 0) { + fprintf(stderr, "%s: error writing " + "GetCertInitial data in bio\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + BIO_flush(databio); + BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); + break; + + case SCEP_REQUEST_GETCERT: + /* Set printable message type */ + s->request_type_str = SCEP_REQUEST_GETCERT_STR; + + /* Signer cert */ + signercert = localcert; + signerkey = rsa; + + /* Read data in memory bio */ + databio = BIO_new(BIO_s_mem()); + if ((rc = i2d_PKCS7_ISSUER_AND_SERIAL_bio(databio, + s->ias_getcert)) <= 0) { + fprintf(stderr, "%s: error writing " + "GetCert data in bio\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + BIO_flush(databio); + BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); + break; + + case SCEP_REQUEST_GETCRL: + /* Set printable message type */ + s->request_type_str = SCEP_REQUEST_GETCRL_STR; + + /* Signer cert */ + signercert = localcert; + signerkey = rsa; + + /* Read data in memory bio */ + databio = BIO_new(BIO_s_mem()); + if ((rc = i2d_PKCS7_ISSUER_AND_SERIAL_bio(databio, + s->ias_getcrl)) <= 0) { + fprintf(stderr, "%s: error writing " + "GetCert data in bio\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + BIO_flush(databio); + BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); + break; + } + /* Below this is the common code for all request_type */ + + /* Read in the payload */ + s->request_len = BIO_get_mem_data(databio, &s->request_payload); + if (v_flag) + printf("%s: data payload size: %d bytes\n", pname, + s->request_len); + BIO_free(databio); + + /* Create encryption certificate stack */ + if ((recipients = sk_X509_new(NULL)) == NULL) { + fprintf(stderr, "%s: error creating " + "certificate stack\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + /* Use different CA cert for encryption if requested */ + if (e_flag) { + if (sk_X509_push(recipients, encert) <= 0) { + fprintf(stderr, "%s: error adding recipient encryption " + "certificate\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + /* Use same CA cert also for encryption */ + } else { + if (sk_X509_push(recipients, cacert) <= 0) { + fprintf(stderr, "%s: error adding recipient encryption " + "certificate\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + } + + /* Create BIO for encryption */ + if ((encbio = BIO_new_mem_buf(s->request_payload, + s->request_len)) == NULL) { + fprintf(stderr, "%s: error creating data " "bio\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + + /* Encrypt */ + if (!(p7enc = PKCS7_encrypt(recipients, encbio, + enc_alg, PKCS7_BINARY))) { + fprintf(stderr, "%s: request payload encrypt failed\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + if (v_flag) + printf("%s: successfully encrypted payload\n", pname); + + /* Write encrypted data */ + memorybio = BIO_new(BIO_s_mem()); + if (i2d_PKCS7_bio(memorybio, p7enc) <= 0) { + fprintf(stderr, "%s: error writing encrypted data\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + BIO_flush(memorybio); + BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); + len = BIO_get_mem_data(memorybio, &buffer); + if (v_flag) + printf("%s: envelope size: %d bytes\n", pname, len); + if (d_flag) { + printf("%s: printing PEM fomatted PKCS#7\n", pname); + PEM_write_PKCS7(stdout, p7enc); + } + BIO_free(memorybio); + + /* Create outer PKCS#7 */ + if (v_flag) + printf("%s: creating outer PKCS#7\n", pname); + s->request_p7 = PKCS7_new(); + if (s->request_p7 == NULL) { + fprintf(stderr, "%s: failed creating PKCS#7 for signing\n", + pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed)) { + fprintf(stderr, "%s: failed setting PKCS#7 type\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + + /* Add signer certificate and signature */ + PKCS7_add_certificate(s->request_p7, signercert); + if ((si = PKCS7_add_signature(s->request_p7, + signercert, signerkey, sig_alg)) == NULL) { + fprintf(stderr, "%s: error adding PKCS#7 signature\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + if (v_flag) + printf("%s: signature added successfully\n", pname); + + /* Set signed attributes */ + if (v_flag) + printf("%s: adding signed attributes\n", pname); + attributes = sk_X509_ATTRIBUTE_new_null(); + add_attribute_string(attributes, nid_transId, s->transaction_id); + add_attribute_string(attributes, nid_messageType, s->request_type_str); + add_attribute_octet(attributes, nid_senderNonce, s->sender_nonce, + s->sender_nonce_len); + PKCS7_set_signed_attributes(si, attributes); + + /* Add contentType */ + if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, + V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) { + fprintf(stderr, "%s: error adding NID_pkcs9_contentType\n", + pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + + /* Create new content */ + if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data)) { + fprintf(stderr, "%s: failed setting PKCS#7 content type\n", + pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + + /* Write data */ + pkcs7bio = PKCS7_dataInit(s->request_p7, NULL); + if (pkcs7bio == NULL) { + fprintf(stderr, "%s: error opening bio for writing PKCS#7 " + "data\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + if (len != BIO_write(pkcs7bio, buffer, len)) { + fprintf(stderr, "%s: error writing PKCS#7 data\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + if (v_flag) + printf("%s: PKCS#7 data written successfully\n", pname); + + /* Finalize PKCS#7 */ + if (!PKCS7_dataFinal(s->request_p7, pkcs7bio)) { + fprintf(stderr, "%s: error finalizing outer PKCS#7\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + if (d_flag) { + printf("%s: printing PEM fomatted PKCS#7\n", pname); + PEM_write_PKCS7(stdout, s->request_p7); + } + + /* base64-encode the data */ + if (v_flag) + printf("%s: applying base64 encoding\n",pname); + + /* Create base64 filtering bio */ + memorybio = BIO_new(BIO_s_mem()); + base64bio = BIO_new(BIO_f_base64()); + outbio = BIO_push(base64bio, memorybio); + + /* Copy PKCS#7 */ + i2d_PKCS7_bio(outbio, s->request_p7); + BIO_flush(outbio); + BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); + s->request_len = BIO_get_mem_data(memorybio, &s->request_payload); + if (v_flag) + printf("%s: base64 encoded payload size: %d bytes\n", + pname, s->request_len); + BIO_free(outbio); + + return (0); +} + +/* + * Unwrap PKCS#7 data and decrypt if necessary + */ +int pkcs7_unwrap(struct scep *s) { + BIO *memorybio; + BIO *outbio; + BIO *pkcs7bio; + int i, len, bytes, used; + STACK_OF(PKCS7_SIGNER_INFO) *sk; + PKCS7 *p7enc; + PKCS7_SIGNER_INFO *si; + STACK_OF(X509_ATTRIBUTE) *attribs; + char *p; + unsigned char buffer[1024]; + X509 *recipientcert; + EVP_PKEY *recipientkey; + + /* Create new memory BIO for outer PKCS#7 */ + memorybio = BIO_new(BIO_s_mem()); + + /* Read in data */ + if (v_flag) + printf("%s: reading outer PKCS#7\n",pname); + if ((len = BIO_write(memorybio, s->reply_payload, s->reply_len)) <= 0) { + fprintf(stderr, "%s: error reading PKCS#7 data\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + if (v_flag) + printf("%s: PKCS#7 payload size: %d bytes\n", pname, len); + BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); + s->reply_p7 = d2i_PKCS7_bio(memorybio, NULL); + if (d_flag) { + printf("%s: printing PEM fomatted PKCS#7\n", pname); + PEM_write_PKCS7(stdout, s->reply_p7); + } + + /* Make sure this is a signed PKCS#7 */ + if (!PKCS7_type_is_signed(s->reply_p7)) { + fprintf(stderr, "%s: PKCS#7 is not signed!\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + + /* Create BIO for content data */ + pkcs7bio = PKCS7_dataInit(s->reply_p7, NULL); + if (pkcs7bio == NULL) { + fprintf(stderr, "%s: cannot get PKCS#7 data\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + + /* Copy enveloped data from PKCS#7 */ + outbio = BIO_new(BIO_s_mem()); + used = 0; + for (;;) { + bytes = BIO_read(pkcs7bio, buffer, sizeof(buffer)); + used += bytes; + if (bytes <= 0) break; + BIO_write(outbio, buffer, bytes); + } + BIO_flush(outbio); + if (v_flag) + printf("%s: PKCS#7 contains %d bytes of enveloped data\n", + pname, used); + + /* Get signer */ + sk = PKCS7_get_signer_info(s->reply_p7); + if (sk == NULL) { + fprintf(stderr, "%s: cannot get signer info!\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + + /* Verify signature */ + if (v_flag) + printf("%s: verifying signature\n", pname); + si = sk_PKCS7_SIGNER_INFO_value(sk, 0); + if (PKCS7_signatureVerify(pkcs7bio, s->reply_p7, si, cacert) <= 0) { + fprintf(stderr, "%s: error verifying signature\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + if (v_flag) + printf("%s: signature ok\n", pname); + + /* Get signed attributes */ + if (v_flag) + printf("%s: finding signed attributes\n", pname); + attribs = PKCS7_get_signed_attributes(si); + if (attribs == NULL) { + fprintf(stderr, "%s: no attributes found\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + + /* Transaction id */ + if ((get_signed_attribute(attribs, nid_transId, + V_ASN1_PRINTABLESTRING, &p)) == 1) { + fprintf(stderr, "%s: cannot find transId\n", pname); + exit (SCEP_PKISTATUS_P7); + } + if (v_flag) + printf("%s: reply transaction id: %s\n", pname, p); + if (strncmp(s->transaction_id, p, strlen(p))) { + fprintf(stderr, "%s: transaction id mismatch\n", pname); + exit (SCEP_PKISTATUS_P7); + } + /* Message type, should be of type CertRep */ + if ((i = get_signed_attribute(attribs, nid_messageType, + V_ASN1_PRINTABLESTRING, &p)) == 1) { + fprintf(stderr, "%s: cannot find messageType\n", pname); + exit (SCEP_PKISTATUS_P7); + } + if (atoi(p) != 3) { + fprintf(stderr, "%s: wrong message type in reply\n", pname); + exit (SCEP_PKISTATUS_P7); + } + if (v_flag) + printf("%s: reply message type is good\n", pname); + + /* Sender and recipient nonces: */ + if ((i = get_signed_attribute(attribs, nid_senderNonce, + V_ASN1_OCTET_STRING, &p)) == 1) { + if (v_flag) + fprintf(stderr, "%s: cannot find senderNonce\n", pname); + /* Some implementations don't put in on reply */ + /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXX + exit (SCEP_PKISTATUS_P7); */ + } + s->reply_sender_nonce = p; + if (v_flag) { + printf("%s: senderNonce in reply: ", pname); + for (i = 0; i < 16; i++) { + printf("%02X", s->reply_sender_nonce[i]); + } + printf("\n"); + } + if (( i = get_signed_attribute(attribs, nid_recipientNonce, + V_ASN1_OCTET_STRING, &p)) == 1) { + fprintf(stderr, "%s: cannot find recipientNonce\n", pname); + exit (SCEP_PKISTATUS_P7); + } + s->reply_recipient_nonce = p; + if (v_flag) { + printf("%s: recipientNonce in reply: ", pname); + for (i = 0; i < 16; i++) { + printf("%02X", s->reply_recipient_nonce[i]); + } + printf("\n"); + } + /* + * Compare recipient nonce to original sender nonce + * The draft says nothing about this, but it makes sense to me.. + * XXXXXXXXXXXXXX check + */ + for (i = 0; i < 16; i++) { + if (s->sender_nonce[i] != s->reply_recipient_nonce[i]) { + if (v_flag) + fprintf(stderr, "%s: corrupted nonce " + "received\n", pname); + /* Instead of exit, break out */ + break; + } + } + /* Get pkiStatus */ + if ((i = get_signed_attribute(attribs, nid_pkiStatus, + V_ASN1_PRINTABLESTRING, &p)) == 1) { + fprintf(stderr, "%s: cannot find pkiStatus\n", pname); + /* This is a mandatory attribute.. */ + exit (SCEP_PKISTATUS_P7); + } + switch (atoi(p)) { + case SCEP_PKISTATUS_SUCCESS: + printf("%s: pkistatus: SUCCESS\n",pname); + s->pki_status = SCEP_PKISTATUS_SUCCESS; + break; + case SCEP_PKISTATUS_FAILURE: + printf("%s: pkistatus: FAILURE\n",pname); + s->pki_status = SCEP_PKISTATUS_FAILURE; + break; + case SCEP_PKISTATUS_PENDING: + printf("%s: pkistatus: PENDING\n",pname); + s->pki_status = SCEP_PKISTATUS_PENDING; + break; + default: + fprintf(stderr, "%s: wrong pkistatus in reply\n",pname); + exit (SCEP_PKISTATUS_P7); + } + + /* Get failInfo */ + if (s->pki_status == SCEP_PKISTATUS_FAILURE) { + if ((i = get_signed_attribute(attribs, nid_failInfo, + V_ASN1_PRINTABLESTRING, &p)) == 1) { + fprintf(stderr, "%s: cannot find failInfo\n", + pname); + exit (SCEP_PKISTATUS_P7); + } + switch (atoi(p)) { + case SCEP_FAILINFO_BADALG: + s->fail_info = SCEP_FAILINFO_BADALG; + printf("%s: reason: %s\n", pname, + SCEP_FAILINFO_BADALG_STR); + break; + case SCEP_FAILINFO_BADMSGCHK: + s->fail_info = SCEP_FAILINFO_BADMSGCHK; + printf("%s: reason: %s\n", pname, + SCEP_FAILINFO_BADMSGCHK_STR); + break; + case SCEP_FAILINFO_BADREQ: + s->fail_info = SCEP_FAILINFO_BADREQ; + printf("%s: reason: %s\n", pname, + SCEP_FAILINFO_BADREQ_STR); + break; + case SCEP_FAILINFO_BADTIME: + s->fail_info = SCEP_FAILINFO_BADTIME; + printf("%s: reason: %s\n", pname, + SCEP_FAILINFO_BADTIME_STR); + break; + case SCEP_FAILINFO_BADCERTID: + s->fail_info = SCEP_FAILINFO_BADCERTID; + printf("%s: reason: %s\n", pname, + SCEP_FAILINFO_BADCERTID_STR); + break; + default: + fprintf(stderr, "%s: wrong failInfo in " "reply\n",pname); + exit (SCEP_PKISTATUS_P7); + } + } + /* If FAILURE or PENDING, we can return */ + if (s->pki_status != SCEP_PKISTATUS_SUCCESS) { + /* There shouldn't be any more data... */ + if (v_flag && (used != 0)) { + fprintf(stderr, "%s: illegal size of payload\n", pname); + } + return (0); + } + /* We got success and expect data */ + if (used == 0) { + fprintf(stderr, "%s: illegal size of payload\n", pname); + exit (SCEP_PKISTATUS_P7); + } + + /* Decrypt the inner PKCS#7 */ + if ((s->request_type == SCEP_REQUEST_PKCSREQ) || + (s->request_type == SCEP_REQUEST_GETCERTINIT)) { + recipientcert = s->signercert; + recipientkey = s->signerkey; + } + else { + recipientcert = localcert; + recipientkey = rsa; + } + if (v_flag) + printf("%s: reading inner PKCS#7\n",pname); + p7enc = d2i_PKCS7_bio(outbio, NULL); + if (p7enc == NULL) { + fprintf(stderr, "%s: cannot read inner PKCS#7\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + if (d_flag) { + printf("%s: printing PEM fomatted PKCS#7\n", pname); + PEM_write_PKCS7(stdout, p7enc); + } + + /* Decrypt the data */ + outbio = BIO_new(BIO_s_mem()); + if (v_flag) + printf("%s: decrypting inner PKCS#7\n",pname); + if (PKCS7_decrypt(p7enc, recipientkey, recipientcert, outbio, 0) == 0) { + fprintf(stderr, "%s: error decrypting inner PKCS#7\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + BIO_flush(outbio); + + /* Write decrypted data */ + s->reply_len = BIO_get_mem_data(outbio, &s->reply_payload); + if (v_flag) + printf("%s: PKCS#7 payload size: %d bytes\n", pname, + s->reply_len); + BIO_set_flags(outbio, BIO_FLAGS_MEM_RDONLY); + s->reply_p7 = d2i_PKCS7_bio(outbio, NULL); + + return (0); + +} + +/* Add signed attributes */ +int +add_attribute_string(STACK_OF(X509_ATTRIBUTE) *attrs, int nid, char *buffer) { + ASN1_STRING *asn1_string = NULL; + X509_ATTRIBUTE *x509_a; + int c; + + if (v_flag) + printf("%s: adding string attribute %s\n", pname, + OBJ_nid2sn(nid)); + + asn1_string = ASN1_STRING_new(); + if ((c = ASN1_STRING_set(asn1_string, buffer, strlen(buffer))) <= 0) { + fprintf(stderr, "%s: error adding data to ASN.1 string\n", + pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + x509_a = X509_ATTRIBUTE_create(nid, V_ASN1_PRINTABLESTRING, + asn1_string); + sk_X509_ATTRIBUTE_push(attrs, x509_a); + + return (0); + +} +int +add_attribute_octet(STACK_OF(X509_ATTRIBUTE) *attrs, int nid, char *buffer, + int len) { + ASN1_STRING *asn1_string = NULL; + X509_ATTRIBUTE *x509_a; + int c; + + if (v_flag) + printf("%s: adding octet attribute %s\n", pname, + OBJ_nid2sn(nid)); + + asn1_string = ASN1_STRING_new(); + if ((c = ASN1_STRING_set(asn1_string, buffer, len)) <= 0) { + fprintf(stderr, "%s: error adding data to ASN.1 string\n", + pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + x509_a = X509_ATTRIBUTE_create(nid, V_ASN1_OCTET_STRING, + asn1_string); + sk_X509_ATTRIBUTE_push(attrs, x509_a); + + return (0); + +} + +/* Find signed attributes */ +int +get_signed_attribute(STACK_OF(X509_ATTRIBUTE) *attribs, int nid, + int type, char **buffer) { + int rc; + ASN1_TYPE *asn1_type; + unsigned int len; + + /* Find attribute */ + rc = get_attribute(attribs, nid, &asn1_type); + if (rc == 1) { + if (v_flag) + fprintf(stderr, "%s: error finding attribute\n",pname); + return (1); + } + if (ASN1_TYPE_get(asn1_type) != type) { + fprintf(stderr, "%s: wrong ASN.1 type\n",pname); + exit (SCEP_PKISTATUS_P7); + } + + /* Copy data */ + len = ASN1_STRING_length(asn1_type->value.asn1_string); + if (len <= 0) { + return (1); + } else if (v_flag) + printf("%s: allocating %d bytes for attribute\n", pname, len); + if (type == V_ASN1_PRINTABLESTRING) { + *buffer = ( char *)malloc(len + 1); + } else { + *buffer = ( char *)malloc(len); + } + if (*buffer == NULL) { + fprintf(stderr, "%s: cannot malloc space for attribute\n", + pname); + exit (SCEP_PKISTATUS_P7); + } + memcpy(*buffer, ASN1_STRING_data(asn1_type->value.asn1_string), len); + + /* Add null terminator if it's a PrintableString */ + if (type == V_ASN1_PRINTABLESTRING) { + (*buffer)[len] = 0; + len++; + } + + return (0); +} +int +get_attribute(STACK_OF(X509_ATTRIBUTE) *attribs, int required_nid, + ASN1_TYPE **asn1_type) { + int i; + ASN1_OBJECT *asn1_obj = NULL; + X509_ATTRIBUTE *x509_attrib = NULL; + + if (v_flag) + printf("%s: finding attribute %s\n", pname, + OBJ_nid2sn(required_nid)); + *asn1_type = NULL; + asn1_obj = OBJ_nid2obj(required_nid); + if (asn1_obj == NULL) { + fprintf(stderr, "%s: error creating ASN.1 object\n", pname); + ERR_print_errors_fp(stderr); + exit (SCEP_PKISTATUS_P7); + } + /* Find attribute */ + for (i = 0; i < sk_X509_ATTRIBUTE_num(attribs); i++) { + x509_attrib = sk_X509_ATTRIBUTE_value(attribs, i); + if (OBJ_cmp(x509_attrib->object, asn1_obj) == 0) { + if ((x509_attrib->value.set) && + (sk_ASN1_TYPE_num(x509_attrib->value.set) != 0)) { + if (*asn1_type != NULL) { + fprintf(stderr, "%s: no value found", + pname); + exit (SCEP_PKISTATUS_P7); + } + *asn1_type = + sk_ASN1_TYPE_value(x509_attrib->value.set, 0); + } + } + } + + if (*asn1_type == NULL) + return (1); + return (0); +} diff --git a/sceputils.c b/sceputils.c index 4d3e2a7..c2342de 100644 --- a/sceputils.c +++ b/sceputils.c @@ -245,7 +245,11 @@ key_fingerprint(X509_REQ *req) { /* Copy as ASCII string and return: */ for (c = 0; c < MD5_DIGEST_LENGTH; c++, str += 2) { + #ifdef WIN32 + sprintf_s((char *)str, sizeof(str), "%02X", md[c]); + #else sprintf((char *)str, "%02X", md[c]); + #endif } *(str+2) = '\0'; diff --git a/sscep.c b/sscep.c index 6440536..a0c3eab 100644 --- a/sscep.c +++ b/sscep.c @@ -17,13 +17,13 @@ handle_serial (char * serial) int hex = NULL != strchr (serial, ':'); /* Convert serial to a decimal serial when input is - a hexidecimal representation of the serial */ - if (hex) + a hexidecimal representation of the serial */ + if (hex) { unsigned int i,ii; char *tmp_serial = (char*) calloc (strlen (serial) + 1,1); - - for (i=0,ii=0; '\0'!=serial[i];i++) + + for (i=0,ii=0; '\0'!=serial[i];i++) { if (':'!=serial[i]) tmp_serial[ii++]=serial[i]; @@ -33,7 +33,7 @@ handle_serial (char * serial) else { unsigned int i; - for (i=0; ! hex && '\0' != serial[i]; i++) + for (i=0; ! hex && '\0' != serial[i]; i++) hex = 'a'==serial[i]||'b'==serial[i]||'c'==serial[i]||'d'==serial[i]||'e'==serial[i]||'f'==serial[i]; } @@ -65,6 +65,7 @@ handle_serial (char * serial) int main(int argc, char **argv) { + ENGINE *e; int c, host_port = 80, count = 1; char *host_name, *p, *dir_name = NULL; char http_string[16384]; @@ -74,6 +75,38 @@ main(int argc, char **argv) { struct scep scep_t; FILE *fp = NULL; BIO *bp; + +#ifdef WIN32 + WORD wVersionRequested; + WSADATA wsaData; + int err; + + wVersionRequested = MAKEWORD( 2, 2 ); + + err = WSAStartup( wVersionRequested, &wsaData ); + if ( err != 0 ) + { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + return; + } + + /* Confirm that the WinSock DLL supports 2.2.*/ + /* Note that if the DLL supports versions greater */ + /* than 2.2 in addition to 2.2, it will still return */ + /* 2.2 in wVersion since that is the version we */ + /* requested. */ + + if ( LOBYTE( wsaData.wVersion ) != 2 || + HIBYTE( wsaData.wVersion ) != 2 ) + { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + WSACleanup( ); + return; + } + +#endif /* Initialize scep layer */ init_scep(); @@ -81,9 +114,6 @@ main(int argc, char **argv) { /* Set program name */ pname = argv[0]; - /* Define signal trap */ - (void)signal(SIGALRM, catchalarm); - /* Set timeout */ timeout = TIMEOUT; @@ -105,7 +135,7 @@ main(int argc, char **argv) { } /* Skip first parameter and parse the rest of the command */ optind++; - while ((c = getopt(argc, argv, "c:de:E:f:F:i:k:K:l:L:n:O:p:r:Rs:S:t:T:u:vw:")) != -1) + while ((c = getopt(argc, argv, "c:de:E:f:g:hF:i:k:K:l:L:n:O:p:r:Rs:S:t:T:u:vw:m:H")) != -1) switch(c) { case 'c': c_flag = 1; @@ -130,6 +160,16 @@ main(int argc, char **argv) { f_flag = 1; f_char = optarg; break; + case 'g': + g_flag = 1; + g_char = optarg; + break; + case 'h'://TODO ändern bspw --inform=ID + h_flag = 1; + break; + case 'H': + H_flag = 1; + break; case 'i': i_flag = 1; i_char = optarg; @@ -150,6 +190,10 @@ main(int argc, char **argv) { L_flag = 1; L_char = optarg; break; + case 'm': + m_flag = 1; + m_char = optarg; + break; case 'n': n_flag = 1; n_num = atoi(optarg); @@ -210,7 +254,11 @@ main(int argc, char **argv) { /* Read in the configuration file: */ if (f_char) { - if (!(fp = fopen(f_char, "r"))) + #ifdef WIN32 + if ((fopen_s(&fp, f_char, "r"))) + #else + if (!(fp = fopen(f_char, "r"))) + #endif fprintf(stderr, "%s: cannot open %s\n", pname, f_char); else { init_config(fp); @@ -220,6 +268,108 @@ main(int argc, char **argv) { if (v_flag) fprintf(stdout, "%s: starting sscep, version %s\n", pname, VERSION); + + /*enable Engine Support */ + if (g_flag) { + + ENGINE_load_builtin_engines(); + ENGINE_load_dynamic(); + // ENGINE_ctrl_cmd + //if its not dynamic, try to load it directly. If OpenSSL has it already we are good to go! + if(strcmp(g_char, "dynamic") != 0) + { + e = ENGINE_by_id(g_char); + if ((e==NULL) && v_flag){ + printf("Engine %s could not be loaded. Trying to load dynamically...\n", g_char); + } + } + + if(e == NULL) + { + //it seems OpenSSL did not already have it. In this case we will try to load it dynamically + //currently we can not set a path, so OpenSSL must be able to find the engine + e = ENGINE_by_id("dynamic"); + + //if we can't even load the dynamic engine, something is seriously wrong. We can't go on from here! + if(e == NULL) { + ERR_load_crypto_strings(); + fprintf(stderr, "Engine dynamic could not be loaded, Error message: %s\n", ERR_error_string(ERR_peek_last_error(), NULL)); + ERR_free_strings(); + exit (SCEP_PKISTATUS_ERROR); + } else if(v_flag) + printf("Engine dynamic was loaded\n"); + + //To load dynamically we have to tell openssl where to find it. + //Currently, we can not provide the path, only the name. May be added in future version + if(ENGINE_ctrl_cmd_string(e, "SO_PATH", g_char, 0) == 0) { + ERR_load_crypto_strings(); + fprintf(stderr, "Loading %s did not succeed: %s\n", g_char, ERR_error_string(ERR_peek_last_error(), NULL)); + ERR_free_strings(); + exit (SCEP_PKISTATUS_ERROR); + } else if (v_flag) + printf("%s was found.\n", g_char); + + //engine will be added to the list of available engines. Should be done for complete import. + if(ENGINE_ctrl_cmd_string(e, "LIST_ADD", "1", 0) == 0) { + ERR_load_crypto_strings(); + fprintf(stderr, "Executing LIST_ADD did not succeed: %s\n", ERR_error_string(ERR_peek_last_error(), NULL)); + ERR_free_strings(); + exit (SCEP_PKISTATUS_ERROR); + } else if(v_flag) + printf("Added %s to list of engines.\n", g_char); + + //Finally we load the engine. + if(ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0) == 0) { + ERR_load_crypto_strings(); + fprintf(stderr, "Executing LOAD did not succeed: %s\n", ERR_error_string(ERR_peek_last_error(), NULL)); + ERR_free_strings(); + exit (SCEP_PKISTATUS_ERROR); + } else if(v_flag) + printf("Loading engine %s succeeded\n", g_char); + + //all these functions were only needed if we loaded dynamically. Otherwise we could just skip this step. + } + + //define this engine as a default for all our crypto operations. This way OpenSSL automatically chooses the right functions + if(ENGINE_set_default(e, ENGINE_METHOD_ALL) == 0) { + ERR_load_crypto_strings(); + fprintf(stderr, "Error loading on setting defaults: %s\n", ERR_error_string(ERR_peek_last_error(), NULL)); + ERR_free_strings(); + exit (SCEP_PKISTATUS_ERROR); + } else if(v_flag) + printf("Engine %s made default for all operations\n", g_char); + + //we need a functional reference and as such need to initialize + if(ENGINE_init(e) == 0) { + ERR_load_crypto_strings(); + fprintf(stderr, "Engine Init did not work: %s\n", ERR_error_string(ERR_peek_last_error(), NULL)); + ERR_free_strings(); + exit (SCEP_PKISTATUS_ERROR); + } else if(v_flag) + printf("Engine %s initialized\n", g_char); + + // below is old code. This just kept for reference purposes and will be removed in future releases. + // target for a future releas is to make the path dynamically adjustable + + /*if(strcmp(g_char,"dynamic")==0){ + //TODO attribut draus machen! + if(!ENGINE_ctrl_cmd_string(e, "SO_PATH", "/home/rt3130/workspace-cc++/JKnCipher/Debug/libJKnCipher.so", 0)){ + fprintf(stderr, "Couldn't Initialize shared library\n"); + } + ENGINE_ctrl_cmd_string(e, "LIST_ADD", "1", 0); + ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0); + } + //else + if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)){ + fprintf(stderr, "Error using Engine %s\n", g_char); + exit (SCEP_PKISTATUS_ERROR); + } + else if (v_flag){ + fprintf(stdout, "Engine successfully enabled\n"); + }*/ + + } + /* * Check argument logic. */ @@ -235,9 +385,9 @@ main(int argc, char **argv) { } } if (operation_flag == SCEP_OPERATION_ENROLL) { - if (!k_flag) { + if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n",pname); - exit (SCEP_PKISTATUS_ERROR); + //exit (SCEP_PKISTATUS_ERROR); } if (!r_flag) { fprintf(stderr, "%s: missing request (-r)\n",pname); @@ -252,9 +402,9 @@ main(int argc, char **argv) { if (!n_flag) n_num = MAX_POLL_COUNT; if (!t_flag) - t_num = POLL_TIME; + t_num = POLL_TIME; if (!T_flag) - T_num = MAX_POLL_TIME; + T_num = MAX_POLL_TIME; } if (operation_flag == SCEP_OPERATION_GETCERT) { if (!l_flag) { @@ -299,7 +449,11 @@ main(int argc, char **argv) { exit (SCEP_PKISTATUS_ERROR); } if (p_flag) { + #ifdef WIN32 + host_name = _strdup(p_char); + #else host_name = strdup(p_char); + #endif dir_name = url_char; } @@ -313,9 +467,18 @@ main(int argc, char **argv) { exit (SCEP_PKISTATUS_ERROR); } if (p_flag) { + #ifdef WIN32 + host_name = _strdup(p_char); + #else host_name = strdup(p_char); + #endif dir_name = url_char; - } else if (!(host_name = strdup(url_char + 7))) + } + #ifdef WIN32 + else if (!(host_name = _strdup(url_char + 7))) + #else + else if (!(host_name = strdup(url_char + 7))) + #endif error_memory(); p = host_name; c = 0; @@ -326,7 +489,7 @@ main(int argc, char **argv) { c = 1; } if (*p == ':') { - *p = '\0'; + *p = '\0'; if (*(p+1)) host_port = atoi(p+1); } p++; @@ -401,13 +564,13 @@ main(int argc, char **argv) { snprintf(http_string, sizeof(http_string), "GET %s%s?operation=GetCACert&message=%s " "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name, - i_char); + i_char); printf("%s: requesting CA certificate\n", pname); if (d_flag) fprintf(stdout, "%s: scep msg: %s", pname, http_string); /* - * Send http message. + * Send http message. * Response is written to http_response struct "reply". */ reply.payload = NULL; @@ -444,7 +607,12 @@ main(int argc, char **argv) { } /* Write PEM-formatted file: */ - if (!(fp = fopen(c_char, "w"))) { + #ifdef WIN32 + if ((fopen_s(&fp, c_char, "w"))) + #else + if (!(fp = fopen(c_char, "w"))) + #endif + { fprintf(stderr, "%s: cannot open CA file for " "writing\n", pname); exit (SCEP_PKISTATUS_ERROR); @@ -479,21 +647,37 @@ main(int argc, char **argv) { if (!k_flag) { fprintf(stderr, "%s: missing private key (-k)\n", pname); - exit (SCEP_PKISTATUS_FILE); + //exit (SCEP_PKISTATUS_FILE); + } + if (k_flag) { + if(!h_flag){ + read_key(&rsa, k_char); + } + else{ + if(v_flag) + printf("Loading private key for new key from engine %s\n", g_char); + read_key_Engine(&rsa, k_char,e); + } } - read_key(&rsa, k_char); - if ((K_flag && !O_flag) || (!K_flag && O_flag)) { fprintf(stderr, "%s: -O also requires -K (and vice-versa)\n", pname); exit (SCEP_PKISTATUS_FILE); } if (K_flag) { - read_key(&renewal_key, K_char); + //TODO auf hwcrhk prüfen? + if(!H_flag){ + read_key(&renewal_key, K_char); + } + else{ + if(v_flag) + printf("Loading old private key for signature from engine %s\n", g_char); + read_key_Engine(&renewal_key, K_char,e); + } } if (O_flag) { - read_cert(&renewal_cert, O_char); + read_cert(&renewal_cert, O_char); } if (operation_flag == SCEP_OPERATION_ENROLL) @@ -512,7 +696,7 @@ main(int argc, char **argv) { fprintf(stdout, "%s: generating selfsigned " "certificate\n", pname); - if (! O_flag) + if (! O_flag) new_selfsigned(&scep_t); else { /* Use existing certificate */ @@ -523,7 +707,11 @@ main(int argc, char **argv) { /* Write the selfsigned certificate if requested */ if (L_flag) { /* Write PEM-formatted file: */ + #ifdef WIN32 + if ((fopen_s(&fp, L_char, "w"))) { + #else if (!(fp = fopen(L_char, "w"))) { + #endif fprintf(stderr, "%s: cannot open " "file for writing\n", pname); exit (SCEP_PKISTATUS_ERROR); @@ -623,15 +811,37 @@ main(int argc, char **argv) { pkcs7_wrap(&scep_t); /* URL-encode */ - p = url_encode(scep_t.request_payload, + p = url_encode((char *)scep_t.request_payload, scep_t.request_len); + /*Test mode print SCEP request and don't send it*/ + if(m_flag){ + + /* Write output file : */ +#ifdef WIN32 + if ((fopen_s(&fp, m_char, "w"))) +#else + if (!(fp = fopen(m_char, "w"))) +#endif + { + fprintf(stderr, "%s: cannot open output file for " + "writing\n", m_char); + }else + { + printf("%s: writing PEM fomatted PKCS#7\n", pname); + PEM_write_PKCS7(fp, scep_t.request_p7); + } + + //printf("Print SCEP Request:\n %s\n",scep_t.request_payload); + return 0; + } + /* Forge the HTTP message */ snprintf(http_string, sizeof(http_string), "GET %s%s?operation=" "PKIOperation&message=" "%s HTTP/1.0\r\n\r\n", - p_flag ? "" : "/", dir_name, p); + p_flag ? "" : "/", dir_name, p); if (d_flag) fprintf(stdout, "%s: scep msg: %s", @@ -658,7 +868,7 @@ main(int argc, char **argv) { /* Check payload */ scep_t.reply_len = reply.bytes; - scep_t.reply_payload = reply.payload; + scep_t.reply_payload = (unsigned char *)reply.payload; pkcs7_unwrap(&scep_t); pkistatus = scep_t.pki_status; @@ -706,7 +916,7 @@ main(int argc, char **argv) { } default: fprintf(stderr, "%s: unknown " - "pkiStatus\n", pname); + "pkiStatus\n", pname); exit (SCEP_PKISTATUS_ERROR); } } @@ -730,6 +940,19 @@ main(int argc, char **argv) { write_crl(&scep_t); break; } + //TODO + //richtiger ort für disable?? +// if(e){ +// ENGINE_finish(*e); +// ENGINE_free(*e); +// hwEngine = NULL; +// ENGINE_cleanup(); +// } +// + + + + return (pkistatus); } @@ -745,6 +968,8 @@ usage() { "\nGeneral OPTIONS\n" " -u SCEP server URL\n" " -p Use proxy server at host:port\n" + " -g Enable Engine support\n" + " -h Keyforme=ID."//TODO " -f Use configuration file\n" " -c CA certificate file (write if OPERATION is getca)\n" " -E PKCS#7 encryption algorithm (des|3des|blowfish)\n" diff --git a/sscep.h b/sscep.h index d10debc..bae154d 100644 --- a/sscep.h +++ b/sscep.h @@ -16,13 +16,32 @@ #include #include #include +#include "getopt.h" + +#ifdef WIN32 + +#include +#include + +#define snprintf _snprintf +#define close _close +#define sleep(t_num) Sleep((t_num)*1000) +#pragma comment(lib, "crypt32.lib") + +#else + #include #include #include #include #include #include + +#endif + #include +#include +#include #include #include #include @@ -35,7 +54,7 @@ #include #include #include - +#include /* Global defines */ #define VERSION "20081211" @@ -111,6 +130,9 @@ int operation_flag; #define SCEP_FAILINFO_BADCERTID_STR \ "No certificate could be identified matching" +//define encoding for capi engine support +#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) + /* End of Global defines */ @@ -254,12 +276,18 @@ int init_scep(void); /* Read RSA private key file */ void read_key(EVP_PKEY** key, char* filename); +/* Read RSA private key using hwcrhk */ +void read_key_Engine(EVP_PKEY** key, char* filename, ENGINE *e); + /* Read CA certificate file */ void read_ca_cert(void); /* Read local certificate file */ void read_cert(X509** cert, char* filename); +/* Read certificate from engine */ +/*void read_cert_Engine(X509** cert, char* id, ENGINE *e, char* filename);*/ + /* Read certificate request and private key */ void read_request(void);