This patch adds support for signing requests with an existing key. It was taken from CertNanny diff -uN sscep/Makefile sscep-ng2/Makefile --- sscep/Makefile 2003-01-22 06:23:18.000000000 +0100 +++ sscep-ng2/Makefile 2006-04-25 19:38:49.000000000 +0200 @@ -7,13 +7,14 @@ CC = gcc CFLAGS = -Wall -O +LDLIBS = -lcrypto 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) $(CPPFLAGS) $(LDFLAGS) -o $(PROG) $(OBJS) $(LDLIBS) clean: rm -f $(PROG) $(OBJS) $(MAN) core diff -uN sscep/README sscep-ng2/README --- sscep/README 2003-04-17 07:49:46.000000000 +0200 +++ sscep-ng2/README 2006-04-28 10:27:44.000000000 +0200 @@ -51,11 +51,13 @@ o iPlanet CMS (getca and enroll works)* o VeriSign Onsite (getca and enroll works)** o Entrust VPN Connect (getca and enroll works)*** +o OpenCA (getca, enroll, getcrl and automatic approval works)**** (*) by default, subjectAltName extensions are dropped from certificate (**) only DNS subjectAltName allowed (demo mode) (***) demo requires to use /C=US/O=Entrust - +(****) automatic approval according to newer SCEP drafts requires + OpenCA 0.9.2.4 or higher HOW TO COMPILE ============== @@ -76,7 +78,7 @@ $ ./sscep -sscep version 20030131 +sscep version 2005XXXX Usage: ./sscep OPERATION [OPTIONS] @@ -103,6 +105,8 @@ OPTIONS for OPERATION enroll are -k Private key file -r Certificate request file + -K Signature private key file + -O Signature certificate (used instead of self-signed) -l Write enrolled certificate in file -e Use different CA cert for encryption -L Write selfsigned certificate in file @@ -152,6 +156,16 @@ CAIdentifier Some CAs require you to define this. Example: mydomain.com Command line option: -i +CheckSubjectName + Check subject DN in the certificate return by the CA. The + default is to match on the public key only. Up to version + 20040325 sscep checked on the subject DN only, which is a + problem e.g. if the CA adds a SER attribute, enforces a + naming policy or fixes encoding errors (e.g. with Java keytool + and DC). + Example: yes + Command line option: -C + CertReqFile Certificate request file created with mkrequest. Example: ./local.csr Command line option: -r @@ -171,6 +185,21 @@ the signature. Example: ./enc.crt Command line option: -e +SignCertFile Instead of creating a self-signed certificate from the + new key pair use an already existing certficate/key to + sign the SCEP request. If the "old" certificate and + key is used, the CA can verify that the holder of the + private key for an existing certificate re-enrolls for + a renewal certificate, allowing for automatic approval + of the request. Requires specification of the corresponding + signature private key file (-K, SignKeyFile). + Example: ./sig.crt + Command line option: -O + +SignKeyFile See SignCertFile. Specifies the corresponding private key. + Example: ./sig.key + Command line option: -K + FingerPrint Display fingerprint algorithm. Available algorithms are md5 and sha1. Default is md5. Command line option: -F @@ -367,6 +396,23 @@ the challenge password), it returns SUCCESS as a first reply. Otherwise, the enrollment requires manual signing and authentication (perhaps a phone call). +Newer SCEP draft versions allow to use the existing certificate (issued +by the CA) to authenticate a renewal request. In this context, the SCEP +request with the new public key is signed with the old certificate and +key (instead of using a self-signed certificate created from the new +key pair). +To use this feature, use the command line options -O and -K to specify +the old certificate and private key (SignCertFile and SignCertKey +in the configuration file). +The actual behaviour of the SCEP server depends on the CA policy and +on the capabilities of the SCEP server (not all servers implement +this feature, using the existing certificate with an older SCEP server +may or may not work, depending on implementation). + +Note: Newer versions of OpenCA (http://www.openca.info/) support +an SCEP server that is capable of automatically approving SCEP requests +signed with the already existing key pair. + STEP 5 - Use certificate ======================== diff -uN sscep/cmd.h sscep-ng2/cmd.h --- sscep/cmd.h 2003-01-30 08:57:34.000000000 +0100 +++ sscep-ng2/cmd.h 2006-04-28 10:01:10.000000000 +0200 @@ -16,6 +16,9 @@ int c_flag; char *c_char; +/* Check subject DN */ +int C_flag; + /* Debug? */ int d_flag; @@ -51,10 +54,18 @@ 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; diff -uN sscep/draft-nourse-scep-11.txt sscep-ng2/draft-nourse-scep-11.txt --- sscep/draft-nourse-scep-11.txt 1970-01-01 01:00:00.000000000 +0100 +++ sscep-ng2/draft-nourse-scep-11.txt 2006-04-25 16:27:03.000000000 +0200 @@ -0,0 +1,2367 @@ + +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 -uN sscep/fileutils.c sscep-ng2/fileutils.c --- sscep/fileutils.c 2003-04-15 12:53:45.000000000 +0200 +++ sscep-ng2/fileutils.c 2006-04-28 10:03:24.000000000 +0200 @@ -55,8 +55,11 @@ PKCS7 *p7; STACK_OF(X509) *certs; X509 *cert = NULL; + ASN1_BIT_STRING *cert_pubkey = NULL; FILE *fp; int i; + ASN1_BIT_STRING *request_pubkey = + request->req_info->pubkey->public_key; localcert = NULL; @@ -66,29 +69,44 @@ /* Find cert */ for (i = 0; i < sk_X509_num(certs); i++) { - char buffer[1024]; - cert = sk_X509_value(certs, i); + cert_pubkey = X509_get_X509_PUBKEY(cert)->public_key; +#define fu_print_name(n) \ + X509_NAME_print_ex_fp(stdout,(n),0,XN_FLAG_RFC2253|ASN1_STRFLGS_SHOW_TYPE) if (v_flag) { - printf("%s: found certificate with\n" - " subject: %s\n", pname, - X509_NAME_oneline(X509_get_subject_name(cert), - buffer, sizeof(buffer))); - printf(" issuer: %s\n", - X509_NAME_oneline(X509_get_issuer_name(cert), - buffer, sizeof(buffer))); + printf("%s: found certificate with\n subject: ", pname); + fu_print_name(X509_get_subject_name(cert)); + printf("\n issuer: "); + fu_print_name(X509_get_issuer_name(cert)); + printf("\n"); } - /* The subject has to match that of our request */ - if (!X509_NAME_cmp(X509_get_subject_name(cert), + /* The public keys of the request and certificate must match */ + if (M_ASN1_BIT_STRING_cmp(request_pubkey,cert_pubkey) != 0) { + if (v_flag) + printf(" public keys of request and certificate don't match\n"); + continue; + } + /* The subject has to match that of our request, + if the "Compare subject DN" flag is set */ + if (C_flag && X509_NAME_cmp(X509_get_subject_name(cert), X509_REQ_get_subject_name(request))) { - - /* 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 (v_flag) { + printf(" certificate subject names doesn't match request subject name:\n "); + fu_print_name(X509_REQ_get_subject_name(request)); + printf("\n"); } - } + continue; + } +#undef fu_print_name + /* The subject cannot be the issuer (selfsigned) */ + if (!X509_NAME_cmp(X509_get_subject_name(cert), + X509_get_issuer_name(cert))) { + if (v_flag) + printf(" certificate is self signed\n"); + continue; + } + localcert = cert; + break; } if (localcert == NULL) { fprintf(stderr, "%s: cannot find requested certificate\n", @@ -320,34 +338,36 @@ /* Read local certificate (GetCert and GetCrl) */ void -read_local_cert(void) { - if (!l_flag || !(localfile = fopen(l_char, "r"))) { - fprintf(stderr, "%s: cannot open local cert file\n", pname); +read_cert(X509** cert, char* filename) { + FILE *file; + if (!(file = fopen(filename, "r"))) { + fprintf(stderr, "%s: cannot open cert file %s\n", pname, filename); exit (SCEP_PKISTATUS_FILE); } - if (!PEM_read_X509(localfile, &localcert, NULL, NULL)) { - fprintf(stderr, "%s: error while reading local cert\n", pname); + if (!PEM_read_X509(file, cert, NULL, NULL)) { + fprintf(stderr, "%s: error while reading cert %s\n", pname, filename); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_FILE); } - fclose(localfile); + fclose(file); } /* Read private key */ void -read_key(void) { +read_key(EVP_PKEY** key, char* filename) { + FILE *file; /* Read private key file */ - if (!k_flag || !(keyfile = fopen(k_char, "r"))) { - fprintf(stderr, "%s: cannot open private key file\n", pname); + if (!(file = fopen(filename, "r"))) { + fprintf(stderr, "%s: cannot open private key file %s\n", pname, filename); exit (SCEP_PKISTATUS_FILE); } - if (!PEM_read_PrivateKey(keyfile, &rsa, NULL, NULL)) { - fprintf(stderr, "%s: error while reading private key\n", pname); + if (!PEM_read_PrivateKey(file, key, NULL, NULL)) { + fprintf(stderr, "%s: error while reading private key %s\n", pname, filename); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_FILE); } - fclose(keyfile); + fclose(file); } /* Read PKCS#10 request */ diff -uN sscep/init.c sscep-ng2/init.c --- sscep/init.c 2003-01-31 10:07:16.000000000 +0100 +++ sscep-ng2/init.c 2006-04-28 10:11:40.000000000 +0200 @@ -61,6 +61,9 @@ if (!(i_char = strdup(str2))) error_memory(); } + } else if (!strncmp(str1, "CheckSubjectName", 16)) { + if (!strncmp(str2, "yes", 3) && !C_flag) + C_flag = 1; } else if (!strncmp(str1, "CertReqFile", 11)) { if (!r_flag) { r_flag = 1; @@ -114,6 +117,12 @@ if (!(l_char = strdup(str2))) error_memory(); } + } else if (!strncmp(str1, "SignCertFile", 12)) { + if (!O_flag) { + O_flag = 1; + if (!(O_char = strdup(str2))) + error_memory(); + } } else if (!strncmp(str1, "MaxPollCount", 12)) { if (!n_flag) { n_flag = 1; @@ -130,6 +139,12 @@ if (!(k_char = strdup(str2))) error_memory(); } + } else if (!strncmp(str1, "SignKeyFile", 11)) { + if (!K_flag) { + K_flag = 1; + if (!(K_char = strdup(str2))) + error_memory(); + } } else if (!strncmp(str1, "SelfSignedFile", 15)) { if (!L_flag) { L_flag = 1; diff -uN sscep/pkcs7.c sscep-ng2/pkcs7.c --- sscep/pkcs7.c 2003-02-10 06:04:48.000000000 +0100 +++ sscep-ng2/pkcs7.c 2006-04-26 13:40:34.000000000 +0200 @@ -28,7 +28,8 @@ PKCS7 *p7enc; PKCS7_SIGNER_INFO *si; STACK_OF(X509_ATTRIBUTE) *attributes; - X509 *signer = NULL; + X509 *signercert = NULL; + EVP_PKEY *signerkey = NULL; /* Create a new sender nonce for all messages * XXXXXXXXXXXXXX should it be per transaction? */ @@ -47,7 +48,8 @@ s->request_type_str = SCEP_REQUEST_PKCSREQ_STR; /* Signer cert */ - signer = s->selfsigned; + signercert = s->signercert; + signerkey = s->signerkey; /* Create inner PKCS#7 */ if (v_flag) @@ -71,7 +73,8 @@ s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR; /* Signer cert */ - signer = s->selfsigned; + signercert = s->signercert; + signerkey = s->signerkey; /* Create inner PKCS#7 */ if (v_flag) @@ -95,7 +98,8 @@ s->request_type_str = SCEP_REQUEST_GETCERT_STR; /* Signer cert */ - signer = localcert; + signercert = localcert; + signerkey = rsa; /* Read data in memory bio */ databio = BIO_new(BIO_s_mem()); @@ -115,7 +119,8 @@ s->request_type_str = SCEP_REQUEST_GETCRL_STR; /* Signer cert */ - signer = localcert; + signercert = localcert; + signerkey = rsa; /* Read data in memory bio */ databio = BIO_new(BIO_s_mem()); @@ -217,9 +222,9 @@ } /* Add signer certificate and signature */ - PKCS7_add_certificate(s->request_p7, signer); + PKCS7_add_certificate(s->request_p7, signercert); if ((si = PKCS7_add_signature(s->request_p7, - signer, rsa, sig_alg)) == NULL) { + signercert, signerkey, sig_alg)) == NULL) { fprintf(stderr, "%s: error adding PKCS#7 signature\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); @@ -317,7 +322,8 @@ STACK_OF(X509_ATTRIBUTE) *attribs; char *p; unsigned char buffer[1024]; - X509 *recipient; + X509 *recipientcert; + EVP_PKEY *recipientkey; /* Create new memory BIO for outer PKCS#7 */ memorybio = BIO_new(BIO_s_mem()); @@ -547,10 +553,14 @@ /* Decrypt the inner PKCS#7 */ if ((s->request_type == SCEP_REQUEST_PKCSREQ) || - (s->request_type == SCEP_REQUEST_GETCERTINIT)) - recipient = s->selfsigned; - else - recipient = localcert; + (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); @@ -568,7 +578,7 @@ outbio = BIO_new(BIO_s_mem()); if (v_flag) printf("%s: decrypting inner PKCS#7\n",pname); - if (PKCS7_decrypt(p7enc, rsa, recipient, outbio, 0) == 0) { + 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); diff -uN sscep/sceputils.c sscep-ng2/sceputils.c --- sscep/sceputils.c 2003-02-09 14:18:23.000000000 +0100 +++ sscep-ng2/sceputils.c 2006-04-25 16:27:03.000000000 +0200 @@ -156,7 +156,8 @@ } /* Copy the pointer and return */ - s->selfsigned = cert; + s->signercert = cert; + s->signerkey = rsa; return (0); } diff -uN sscep/sscep.c sscep-ng2/sscep.c --- sscep/sscep.c 2003-04-17 07:47:04.000000000 +0200 +++ sscep-ng2/sscep.c 2006-04-28 11:06:16.000000000 +0200 @@ -53,12 +53,15 @@ } /* Skip first parameter and parse the rest of the command */ optind++; - while ((c = getopt(argc, argv, "c:de:E:f:F:i:k:l:L:n:p:r:Rs:S:t:T:u:vw:")) != -1) + while ((c = getopt(argc, argv, "c:Cde:E:f:F:i:k:K:l:L:n:O:p:r:Rs:S:t:T:u:vw:")) != -1) switch(c) { case 'c': c_flag = 1; c_char = optarg; break; + case 'C': + C_flag = 1; + break; case 'd': d_flag = 1; break; @@ -86,6 +89,10 @@ k_flag = 1; k_char = optarg; break; + case 'K': + K_flag = 1; + K_char = optarg; + break; case 'l': l_flag = 1; l_char = optarg; @@ -98,6 +105,10 @@ n_flag = 1; n_num = atoi(optarg); break; + case 'O': + O_flag = 1; + O_char = optarg; + break; case 'p': p_flag = 1; p_char = optarg; @@ -137,6 +148,7 @@ w_char = optarg; break; default: + printf("argv: %s\n", argv[optind]); usage(); } argc -= optind; @@ -402,15 +414,38 @@ case SCEP_OPERATION_GETCERT: case SCEP_OPERATION_GETCRL: /* Read local certificate */ - read_local_cert(); + if (!l_flag) { + fprintf(stderr, "%s: missing local cert (-l)\n", pname); + exit (SCEP_PKISTATUS_FILE); + } + read_cert(&localcert, l_char); case SCEP_OPERATION_ENROLL: /* * Read in CA cert, private key and certificate * request in global variables. */ - read_ca_cert(); - read_key(); + read_ca_cert(); + + if (!k_flag) { + fprintf(stderr, "%s: missing private key (-k)\n", pname); + exit (SCEP_PKISTATUS_FILE); + } + 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); + } + + if (O_flag) { + read_cert(&renewal_cert, O_char); + } + if (operation_flag == SCEP_OPERATION_ENROLL) read_request(); @@ -426,7 +461,14 @@ if (v_flag) fprintf(stdout, "%s: generating selfsigned " "certificate\n", pname); - new_selfsigned(&scep_t); + + if (! O_flag) + new_selfsigned(&scep_t); + else { + /* Use existing certificate */ + scep_t.signercert = renewal_cert; + scep_t.signerkey = renewal_key; + } /* Write the selfsigned certificate if requested */ if (L_flag) { @@ -436,7 +478,7 @@ "file for writing\n", pname); exit (SCEP_PKISTATUS_ERROR); } - if (PEM_write_X509(fp,scep_t.selfsigned) != 1) { + if (PEM_write_X509(fp,scep_t.signercert) != 1) { fprintf(stderr, "%s: error while " "writing certificate file\n", pname); ERR_print_errors_fp(stderr); @@ -643,7 +685,8 @@ void usage() { - fprintf(stdout, "\nsscep version %s\n\n" , VERSION); + fprintf(stdout, "\nsscep version %s using %s\n\n" , + VERSION,SSLeay_version(SSLEAY_VERSION)); fprintf(stdout, "Usage: %s OPERATION [OPTIONS]\n" "\nAvailable OPERATIONs are\n" " getca Get CA/RA certificate(s)\n" @@ -665,6 +708,8 @@ "\nOPTIONS for OPERATION enroll are\n" " -k Private key file\n" " -r Certificate request file\n" + " -K Signature private key file, use with -O\n" + " -O Signature certificate (used instead of self-signed)\n" " -l Write enrolled certificate in file\n" " -e Use different CA cert for encryption\n" " -L Write selfsigned certificate in file\n" @@ -672,6 +717,8 @@ " -T Max polling time in seconds\n" " -n Max number of GetCertInitial requests\n" " -R Resume interrupted enrollment\n" + " -C Check subject DN in the certificate return by the\n" + " CA (default is to match on the public key only)\n" "\nOPTIONS for OPERATION getcert are\n" " -k Private key file\n" " -l Local certificate file\n" diff -uN sscep/sscep.h sscep-ng2/sscep.h --- sscep/sscep.h 2003-04-17 07:50:04.000000000 +0200 +++ sscep-ng2/sscep.h 2006-04-28 10:46:49.000000000 +0200 @@ -36,10 +36,9 @@ #include #include - /* Global defines */ -#define VERSION "20030417" +#define VERSION "20060428" /* SCEP operations */ int operation_flag; @@ -128,13 +127,13 @@ X509 *encert; X509 *localcert; X509 *othercert; +X509 *renewal_cert; X509_REQ *request; EVP_PKEY *rsa; +EVP_PKEY *renewal_key; X509_CRL *crl; FILE *cafile; FILE *reqfile; -FILE *keyfile; -FILE *localfile; FILE *otherfile; FILE *crlfile; @@ -207,7 +206,9 @@ int recipient_nonce_len; /* Certificates */ - X509 *selfsigned; + X509 *signercert; + EVP_PKEY *signerkey; + EVP_PKEY *pkey; /* Request */ @@ -251,13 +252,13 @@ int init_scep(void); /* Read RSA private key file */ -void read_key(void); +void read_key(EVP_PKEY** key, char* filename); /* Read CA certificate file */ void read_ca_cert(void); /* Read local certificate file */ -void read_local_cert(void); +void read_cert(X509** cert, char* filename); /* Read certificate request and private key */ void read_request(void);