3 * sscep -- Simple SCEP client implementation
4 * Copyright (c) Jarkko Turkulainen 2003. All rights reserved.
5 * See the file COPYRIGHT for licensing information.
13 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
25 #include <openssl/evp.h>
26 #include <openssl/crypto.h>
27 #include <openssl/buffer.h>
28 #include <openssl/asn1.h>
29 #include <openssl/x509.h>
30 #include <openssl/x509v3.h>
31 #include <openssl/pkcs7.h>
32 #include <openssl/err.h>
33 #include <openssl/pem.h>
34 #include <openssl/rand.h>
35 #include <openssl/md5.h>
36 #include <openssl/objects.h>
37 #include <openssl/asn1_mac.h>
41 #define VERSION "20081211"
44 extern int operation_flag;
45 #define SCEP_OPERATION_GETCA 1
46 #define SCEP_OPERATION_ENROLL 3
47 #define SCEP_OPERATION_GETCERT 5
48 #define SCEP_OPERATION_GETCRL 7
50 /* SCEP MIME headers */
51 #define MIME_GETCA "application/x-x509-ca-cert"
52 #define MIME_GETCA_RA "application/x-x509-ca-ra-cert"
53 /* Entrust VPN connector uses different MIME types */
54 #define MIME_PKI "x-pki-message"
55 #define MIME_GETCA_RA_ENTRUST "application/x-x509-ra-ca-certs"
57 /* SCEP reply types based on MIME headers */
58 #define SCEP_MIME_GETCA 1
59 #define SCEP_MIME_GETCA_RA 3
60 #define SCEP_MIME_PKI 5
62 /* SCEP request types */
63 #define SCEP_REQUEST_NONE 0
64 #define SCEP_REQUEST_PKCSREQ 19
65 #define SCEP_REQUEST_PKCSREQ_STR "19"
66 #define SCEP_REQUEST_GETCERTINIT 20
67 #define SCEP_REQUEST_GETCERTINIT_STR "20"
68 #define SCEP_REQUEST_GETCERT 21
69 #define SCEP_REQUEST_GETCERT_STR "21"
70 #define SCEP_REQUEST_GETCRL 22
71 #define SCEP_REQUEST_GETCRL_STR "22"
73 /* SCEP reply types */
74 #define SCEP_REPLY_NONE 0
75 #define SCEP_REPLY_CERTREP 3
76 #define SCEP_REPLY_CERTREP_STR "3"
78 /* SCEP pkiStatus values (also used as SSCEP return values) */
79 #define SCEP_PKISTATUS_SUCCESS 0
80 #define SCEP_PKISTATUS_FAILURE 2
81 #define SCEP_PKISTATUS_PENDING 3
83 /* SSCEP return values (not in SCEP draft) */
84 #define SCEP_PKISTATUS_ERROR 1 /* General error */
85 #define SCEP_PKISTATUS_BADALG 70 /* BADALG failInfo */
86 #define SCEP_PKISTATUS_BADMSGCHK 71 /* BADMSGCHK failInfo */
87 #define SCEP_PKISTATUS_BADREQ 72 /* BADREQ failInfo */
88 #define SCEP_PKISTATUS_BADTIME 73 /* BADTIME failInfo */
89 #define SCEP_PKISTATUS_BADCERTID 74 /* BADCERTID failInfo */
90 #define SCEP_PKISTATUS_TIMEOUT 89 /* Network timeout */
91 #define SCEP_PKISTATUS_SS 91 /* Error generating selfsigned */
92 #define SCEP_PKISTATUS_FILE 93 /* Error in file handling */
93 #define SCEP_PKISTATUS_NET 95 /* Network sending message */
94 #define SCEP_PKISTATUS_P7 97 /* Error in pkcs7 routines */
95 #define SCEP_PKISTATUS_UNSET 99 /* Unset pkiStatus */
97 /* SCEP failInfo values */
98 #define SCEP_FAILINFO_BADALG 0
99 #define SCEP_FAILINFO_BADALG_STR \
100 "Unrecognized or unsupported algorithm ident"
101 #define SCEP_FAILINFO_BADMSGCHK 1
102 #define SCEP_FAILINFO_BADMSGCHK_STR \
103 "Integrity check failed"
104 #define SCEP_FAILINFO_BADREQ 2
105 #define SCEP_FAILINFO_BADREQ_STR \
106 "Transaction not permitted or supported"
107 #define SCEP_FAILINFO_BADTIME 3
108 #define SCEP_FAILINFO_BADTIME_STR \
109 "Message time field was not sufficiently close to the system time"
110 #define SCEP_FAILINFO_BADCERTID 4
111 #define SCEP_FAILINFO_BADCERTID_STR \
112 "No certificate could be identified matching"
114 /* End of Global defines */
117 /* Global variables */
122 /* Network timeout */
125 /* Certificates, requests, keys.. */
128 extern X509 *localcert;
129 extern X509 *othercert;
130 extern X509 *renewal_cert;
131 extern X509_REQ *request;
132 extern EVP_PKEY *rsa;
133 extern EVP_PKEY *renewal_key;
134 extern X509_CRL *crl;
136 extern FILE *reqfile;
137 extern FILE *otherfile;
138 extern FILE *crlfile;
140 /* Fingerprint, signing and encryption algorithms */
141 extern EVP_MD *fp_alg;
142 extern EVP_MD *sig_alg;
143 extern EVP_CIPHER *enc_alg;
145 /* OpenSSL OID handles */
146 extern int nid_messageType;
147 extern int nid_pkiStatus;
148 extern int nid_failInfo;
149 extern int nid_senderNonce;
150 extern int nid_recipientNonce;
151 extern int nid_transId;
152 extern int nid_extensionReq;
154 /* Global pkistatus */
155 extern int pkistatus;
157 /* End of Global variables */
162 /* GETCertInital data structure */
167 } pkcs7_issuer_and_subject;
169 /* HTTP reply structure */
172 /* SCEP reply type */
185 /* SCEP transaction structure */
188 /* SCEP message types */
190 char *request_type_str;
192 char *reply_type_str;
194 /* SCEP message status */
196 char *pki_status_str;
200 /* SCEP transaction attributes */
201 char *transaction_id;
202 unsigned char *sender_nonce;
203 int sender_nonce_len;
204 unsigned char *reply_recipient_nonce;
205 unsigned char *reply_sender_nonce;
206 int recipient_nonce_len;
216 unsigned char *request_payload;
218 pkcs7_issuer_and_subject *ias_getcertinit;
219 PKCS7_ISSUER_AND_SERIAL *ias_getcert;
220 PKCS7_ISSUER_AND_SERIAL *ias_getcrl;
224 unsigned char *reply_payload;
228 /* End of structures */
233 /* Print usage information */
236 /* Send HTTP message */
237 int send_msg (struct http_reply *, char *, char *, int, int);
240 void catchalarm (int);
242 /* Get config file parameter */
243 char *get_string (char *);
245 /* Report memory error */
246 void error_memory(void);
248 /* Initialize config file */
249 void init_config(FILE *);
251 /* Initialize SCEP layer */
254 /* Read RSA private key file */
255 void read_key(EVP_PKEY** key, char* filename);
257 /* Read CA certificate file */
258 void read_ca_cert(void);
260 /* Read local certificate file */
261 void read_cert(X509** cert, char* filename);
263 /* Read certificate request and private key */
264 void read_request(void);
267 void write_crl(struct scep *);
269 /* Write local certificate file */
270 void write_local_cert(struct scep *);
272 /* Write other certificate file */
273 void write_other_cert(struct scep *);
276 int write_ca_ra(struct http_reply *);
278 /* Create new SCEP session */
279 int new_transaction(struct scep *);
281 /* Create self-signed certificate */
282 int new_selfsigned(struct scep *);
284 /* Get key fingerprint */
285 char * key_fingerprint(X509_REQ *);
287 /* PKCS#7 encode message */
288 int pkcs7_wrap(struct scep *);
290 /* PKCS#7 decode message */
291 int pkcs7_unwrap(struct scep *);
293 /* Add signed string attribute */
294 int add_attribute_string(STACK_OF(X509_ATTRIBUTE) *, int, char *);
296 /* Add signed octet attribute */
297 int add_attribute_octet(STACK_OF(X509_ATTRIBUTE) *, int, char *, int);
299 /* Find signed attributes */
300 int get_signed_attribute(STACK_OF(X509_ATTRIBUTE) *, int, int, char **);
301 int get_attribute(STACK_OF(X509_ATTRIBUTE) *, int, ASN1_TYPE **);
304 char *url_encode (char *, size_t);
306 /* End of Functions */