OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / user / sscep / sscep.c
1
2 /*
3  * sscep -- Simple SCEP client implementation
4  * Copyright (c) Jarkko Turkulainen 2003. All rights reserved.
5  * See the file COPYRIGHT for licensing information.
6  */
7
8
9 /* Main routine */
10
11
12 #include "sscep.h"
13
14 static char *
15 handle_serial (char * serial)
16 {
17         int hex = NULL != strchr (serial, ':');
18
19         /* Convert serial to a decimal serial when input is
20            a hexidecimal representation of the serial */        
21         if (hex) 
22         {
23                 unsigned int i,ii;
24                 char *tmp_serial = (char*) calloc (strlen (serial) + 1,1);
25                 
26                 for (i=0,ii=0; '\0'!=serial[i];i++) 
27                 {
28                         if (':'!=serial[i])
29                                 tmp_serial[ii++]=serial[i];
30                 }
31                 serial=tmp_serial;
32         }
33         else
34         {
35                 unsigned int i;
36                 for (i=0; ! hex && '\0' != serial[i]; i++) 
37                         hex = 'a'==serial[i]||'b'==serial[i]||'c'==serial[i]||'d'==serial[i]||'e'==serial[i]||'f'==serial[i];
38         }
39
40         if (hex)
41         {
42                 ASN1_INTEGER* ai;
43                 BIGNUM *ret;
44                 BIO* in = BIO_new_mem_buf(serial, -1);
45                 char buf[1025];
46                 ai=ASN1_INTEGER_new();
47                 if (ai == NULL) return NULL;
48                 if (!a2i_ASN1_INTEGER(in,ai,buf,1024))
49                 {
50                         return NULL;
51                 }
52                 ret=ASN1_INTEGER_to_BN(ai,NULL);
53                 if (ret == NULL)
54                 {
55                         return NULL;
56                 }
57                 else
58                 {
59                  serial = BN_bn2dec(ret);
60                 }
61         }
62
63         return serial;
64 } /* handle_serial */
65
66 int
67 main(int argc, char **argv) {
68         int                     c, host_port = 80, count = 1;
69         char                    *host_name, *p, *dir_name = NULL;
70         char                    http_string[16384];
71         struct http_reply       reply;
72         unsigned int            n;
73         unsigned char           md[EVP_MAX_MD_SIZE];
74         struct scep             scep_t;
75         FILE                    *fp = NULL;
76         BIO                     *bp;
77
78         /* Initialize scep layer */
79         init_scep();
80
81         /* Set program name */
82         pname = argv[0];
83
84         /* Define signal trap */
85         (void)signal(SIGALRM, catchalarm);
86
87         /* Set timeout */
88         timeout = TIMEOUT;
89
90         /* Check operation parameter */
91         if (!argv[1]) {
92                 usage();
93         } else if (!strncmp(argv[1], "getca", 5)) {
94                 operation_flag = SCEP_OPERATION_GETCA;
95         } else if (!strncmp(argv[1], "enroll", 6)) {
96                 operation_flag = SCEP_OPERATION_ENROLL;
97         } else if (!strncmp(argv[1], "getcert", 7)) {
98                 operation_flag = SCEP_OPERATION_GETCERT;
99         } else if (!strncmp(argv[1], "getcrl", 6)) {
100                 operation_flag = SCEP_OPERATION_GETCRL;
101         } else {
102                 fprintf(stderr, "%s: missing or illegal operation parameter\n",
103                                 argv[0]);
104                 usage();
105         }
106         /* Skip first parameter and parse the rest of the command */
107         optind++;
108         while ((c = getopt(argc, argv, "c:de:E:f:F:i:k:K:l:L:n:O:p:r:Rs:S:t:T:u:vw:")) != -1)
109                 switch(c) {
110                         case 'c':
111                                 c_flag = 1;
112                                 c_char = optarg;
113                                 break;
114                         case 'd':
115                                 d_flag = 1;
116                                 break;
117                         case 'e':
118                                 e_flag = 1;
119                                 e_char = optarg;
120                                 break;
121                         case 'E':
122                                 E_flag = 1;
123                                 E_char = optarg;
124                                 break;
125                         case 'F':
126                                 F_flag = 1;
127                                 F_char = optarg;
128                                 break;
129                         case 'f':
130                                 f_flag = 1;
131                                 f_char = optarg;
132                                 break;
133                         case 'i':
134                                 i_flag = 1;
135                                 i_char = optarg;
136                                 break;
137                         case 'k':
138                                 k_flag = 1;
139                                 k_char = optarg;
140                                 break;
141                         case 'K':
142                                 K_flag = 1;
143                                 K_char = optarg;
144                                 break;
145                         case 'l':
146                                 l_flag = 1;
147                                 l_char = optarg;
148                                 break;
149                         case 'L':
150                                 L_flag = 1;
151                                 L_char = optarg;
152                                 break;
153                         case 'n':
154                                 n_flag = 1;
155                                 n_num = atoi(optarg);
156                                 break;
157                         case 'O':
158                                 O_flag = 1;
159                                 O_char = optarg;
160                                 break;
161                         case 'p':
162                                 p_flag = 1;
163                                 p_char = optarg;
164                                 break;
165                         case 'r':
166                                 r_flag = 1;
167                                 r_char = optarg;
168                                 break;
169                         case 'R':
170                                 R_flag = 1;
171                                 break;
172                         case 's':
173                                 s_flag = 1;
174                                 /*s_char = optarg;*/
175                                 s_char = handle_serial(optarg);
176                                 break;
177                         case 'S':
178                                 S_flag = 1;
179                                 S_char = optarg;
180                                 break;
181                         case 't':
182                                 t_flag = 1;
183                                 t_num = atoi(optarg);
184                                 break;
185                         case 'T':
186                                 T_flag = 1;
187                                 T_num = atoi(optarg);
188                                 break;
189                         case 'u':
190                                 u_flag = 1;
191                                 url_char = optarg;
192                                 break;
193                         case 'v':
194                                 v_flag = 1;
195                                 break;
196                         case 'w':
197                                 w_flag = 1;
198                                 w_char = optarg;
199                                 break;
200                         default:
201                           printf("argv: %s\n", argv[optind]);
202                                 usage();
203                 }
204         argc -= optind;
205         argv += optind;
206
207         /* If we debug, include verbose messages also */
208         if (d_flag)
209                 v_flag = 1;
210
211         /* Read in the configuration file: */
212         if (f_char) {
213                 if (!(fp = fopen(f_char, "r"))) 
214                         fprintf(stderr, "%s: cannot open %s\n", pname, f_char);
215                 else {
216                         init_config(fp);
217                         (void)fclose(fp);
218                 }
219         }
220         if (v_flag)
221                 fprintf(stdout, "%s: starting sscep, version %s\n",
222                         pname, VERSION);
223         /*
224          * Check argument logic.
225          */
226         if (!c_flag) {
227                 if (operation_flag == SCEP_OPERATION_GETCA) {
228                         fprintf(stderr,
229                           "%s: missing CA certificate filename (-c)\n", pname);
230                         exit (SCEP_PKISTATUS_ERROR);
231                 } else {
232                         fprintf(stderr,
233                                 "%s: missing CA certificate (-c)\n", pname);
234                         exit (SCEP_PKISTATUS_ERROR);
235                 }
236         }
237         if (operation_flag == SCEP_OPERATION_ENROLL) {
238                 if (!k_flag) { 
239                         fprintf(stderr, "%s: missing private key (-k)\n",pname);
240                         exit (SCEP_PKISTATUS_ERROR);
241                 }
242                 if (!r_flag) {
243                         fprintf(stderr, "%s: missing request (-r)\n",pname);
244                         exit (SCEP_PKISTATUS_ERROR);
245
246                 }
247                 if (!l_flag) {
248                         fprintf(stderr, "%s: missing local cert (-l)\n",pname);
249                         exit (SCEP_PKISTATUS_ERROR);
250                 }
251                 /* Set polling limits */
252                 if (!n_flag)
253                         n_num = MAX_POLL_COUNT;
254                 if (!t_flag)
255                         t_num = POLL_TIME;      
256                 if (!T_flag)
257                         T_num = MAX_POLL_TIME;  
258         }
259         if (operation_flag == SCEP_OPERATION_GETCERT) {
260                 if (!l_flag) {
261                         fprintf(stderr, "%s: missing local cert (-l)\n",pname);
262                         exit (SCEP_PKISTATUS_ERROR);
263                 }
264                 if (!s_flag) {
265                         fprintf(stderr, "%s: missing serial no (-s)\n", pname);
266                         exit (SCEP_PKISTATUS_ERROR);
267                 }
268                 if (!w_flag) {
269                         fprintf(stderr, "%s: missing cert file (-w)\n",pname);
270                         exit (SCEP_PKISTATUS_ERROR);
271                 }
272                 if (!k_flag) {
273                         fprintf(stderr, "%s: missing private key (-k)\n",pname);
274                         exit (SCEP_PKISTATUS_ERROR);
275                 }
276         }
277         if (operation_flag == SCEP_OPERATION_GETCRL) {
278                 if (!l_flag) {
279                         fprintf(stderr, "%s: missing local cert (-l)\n",pname);
280                         exit (SCEP_PKISTATUS_ERROR);
281                 }
282                 if (!w_flag) {
283                         fprintf(stderr, "%s: missing crl file (-w)\n",pname);
284                         exit (SCEP_PKISTATUS_ERROR);
285                 }
286                 if (!k_flag) {
287                         fprintf(stderr, "%s: missing private key (-k)\n",pname);
288                         exit (SCEP_PKISTATUS_ERROR);
289                 }
290         }
291
292         /* Break down the URL */
293         if (!u_flag) {
294                 fprintf(stderr, "%s: missing URL (-u)\n", pname);
295                 exit (SCEP_PKISTATUS_ERROR);
296         }
297         if (strncmp(url_char, "http://", 7) && !p_flag) {
298                 fprintf(stderr, "%s: illegal URL %s\n", pname, url_char);
299                 exit (SCEP_PKISTATUS_ERROR);
300         }
301         if (p_flag) {
302                 host_name = strdup(p_char);
303                 dir_name = url_char;
304         }
305
306         /* Break down the URL */
307         if (!u_flag) {
308                 fprintf(stderr, "%s: missing URL (-u)\n", pname);
309                 exit (SCEP_PKISTATUS_ERROR);
310         }
311         if (strncmp(url_char, "http://", 7) && !p_flag) {
312                 fprintf(stderr, "%s: illegal URL %s\n", pname, url_char);
313                 exit (SCEP_PKISTATUS_ERROR);
314         }
315         if (p_flag) {
316                 host_name = strdup(p_char);
317                 dir_name = url_char;
318         } else if (!(host_name = strdup(url_char + 7)))
319                 error_memory();
320         p = host_name;
321         c = 0;
322         while (*p != '\0') {
323                 if (*p == '/' && !p_flag && !c) {
324                         *p = '\0';
325                         if (*(p+1)) dir_name = p + 1;
326                         c = 1;
327                 }
328                 if (*p == ':') {
329                         *p = '\0';      
330                         if (*(p+1)) host_port = atoi(p+1);
331                 }
332                 p++;
333         }
334         if (!dir_name) {
335                 fprintf(stderr, "%s: illegal URL\n", pname);
336                 exit (SCEP_PKISTATUS_ERROR);
337         }
338         if (host_port < 1 || host_port > 65550) {
339                 fprintf(stderr, "%s: illegal port number %d\n", pname,
340                                 host_port);
341                 exit (SCEP_PKISTATUS_ERROR);
342         }
343         if (v_flag) {
344                 fprintf(stdout, "%s: hostname: %s\n", pname, host_name);
345                 fprintf(stdout, "%s: directory: %s\n", pname, dir_name);
346                 fprintf(stdout, "%s: port: %d\n", pname, host_port);
347         }
348
349         /* Check algorithms */
350         if (!E_flag) {
351                 enc_alg = (EVP_CIPHER *)EVP_des_cbc();
352         } else if (!strncmp(E_char, "blowfish", 8)) {
353                 enc_alg = (EVP_CIPHER *)EVP_bf_cbc();
354         } else if (!strncmp(E_char, "des", 3)) {
355                 enc_alg = (EVP_CIPHER *)EVP_des_cbc();
356         } else if (!strncmp(E_char, "3des", 4)) {
357                 enc_alg = (EVP_CIPHER *)EVP_des_ede3_cbc();
358         } else {
359                 fprintf(stderr, "%s: unsupported algorithm: %s\n",
360                         pname, E_char);
361                 exit (SCEP_PKISTATUS_ERROR);
362         }
363         if (!S_flag) {
364                 sig_alg = (EVP_MD *)EVP_md5();
365         } else if (!strncmp(S_char, "md5", 3)) {
366                 sig_alg = (EVP_MD *)EVP_md5();
367         } else if (!strncmp(S_char, "sha1", 4)) {
368                 sig_alg = (EVP_MD *)EVP_sha1();
369         } else {
370                 fprintf(stderr, "%s: unsupported algorithm: %s\n",
371                         pname, S_char);
372                 exit (SCEP_PKISTATUS_ERROR);
373         }
374         /* Fingerprint algorithm */
375         if (!F_flag) {
376                 fp_alg = (EVP_MD *)EVP_md5();
377         } else if (!strncmp(F_char, "md5", 3)) {
378                 fp_alg = (EVP_MD *)EVP_md5();
379         } else if (!strncmp(F_char, "sha1", 4)) {
380                 fp_alg = (EVP_MD *)EVP_sha1();
381         } else {
382                 fprintf(stderr, "%s: unsupported algorithm: %s\n",
383                         pname, F_char);
384                 exit (SCEP_PKISTATUS_ERROR);
385         }
386
387         /*
388          * Switch to operation specific code
389          */
390         switch(operation_flag) {
391                 case SCEP_OPERATION_GETCA:
392                         if (v_flag)
393                                 fprintf(stdout, "%s: SCEP_OPERATION_GETCA\n",
394                                         pname);
395
396                         /* Set CA identifier */
397                         if (!i_flag)
398                                 i_char = CA_IDENTIFIER;
399
400                         /* Forge the HTTP message */
401                         snprintf(http_string, sizeof(http_string),
402                          "GET %s%s?operation=GetCACert&message=%s "
403                          "HTTP/1.0\r\n\r\n", p_flag ? "" : "/", dir_name,
404                                         i_char); 
405                         printf("%s: requesting CA certificate\n", pname);
406                         if (d_flag)
407                                 fprintf(stdout, "%s: scep msg: %s", pname,
408                                         http_string);
409                         /*
410                          * Send http message. 
411                          * Response is written to http_response struct "reply".
412                          */
413                         reply.payload = NULL;
414                         if ((c = send_msg (&reply, http_string, host_name,
415                                         host_port, operation_flag)) == 1) {
416                                 fprintf(stderr, "%s: error while sending "
417                                         "message\n", pname);
418                                 exit (SCEP_PKISTATUS_NET);
419                         }
420                         if (reply.payload == NULL) {
421                                 fprintf(stderr, "%s: no data, perhaps you "
422                                    "should define CA identifier (-i)\n", pname);
423                                 exit (SCEP_PKISTATUS_SUCCESS);
424                         }
425                         printf("%s: valid response from server\n", pname);
426                         if (reply.type == SCEP_MIME_GETCA_RA) {
427                                 /* XXXXXXXXXXXXXXXXXXXXX chain not verified */
428                                 write_ca_ra(&reply);
429                         }
430                         /* Read payload as DER X.509 object: */
431                         bp = BIO_new_mem_buf(reply.payload, reply.bytes);
432                         cacert = d2i_X509_bio(bp, NULL);
433
434                         /* Read and print certificate information */
435                         if (!X509_digest(cacert, fp_alg, md, &n)) {
436                                 ERR_print_errors_fp(stderr);
437                                 exit (SCEP_PKISTATUS_ERROR);
438                         }
439                         printf("%s: %s fingerprint: ", pname,
440                                 OBJ_nid2sn(EVP_MD_type(fp_alg)));
441                         for (c = 0; c < (int)n; c++) {
442                                 printf("%02X%c",md[c],
443                                         (c + 1 == (int)n) ?'\n':':');
444                         }
445
446                         /* Write PEM-formatted file: */
447                         if (!(fp = fopen(c_char, "w"))) {
448                                 fprintf(stderr, "%s: cannot open CA file for "
449                                         "writing\n", pname);
450                                 exit (SCEP_PKISTATUS_ERROR);
451                         }
452                         if (PEM_write_X509(fp, cacert) != 1) {
453                                 fprintf(stderr, "%s: error while writing CA "
454                                         "file\n", pname);
455                                 ERR_print_errors_fp(stderr);
456                                 exit (SCEP_PKISTATUS_ERROR);
457                         }
458                         printf("%s: CA certificate written as %s\n",
459                                 pname, c_char);
460                         (void)fclose(fp);
461                         pkistatus = SCEP_PKISTATUS_SUCCESS;
462                         break;
463
464                 case SCEP_OPERATION_GETCERT:
465                 case SCEP_OPERATION_GETCRL:
466                         /* Read local certificate */
467                         if (!l_flag) {
468                           fprintf(stderr, "%s: missing local cert (-l)\n", pname);
469                           exit (SCEP_PKISTATUS_FILE);
470                         }
471                         read_cert(&localcert, l_char);
472
473                 case SCEP_OPERATION_ENROLL:
474                         /*
475                          * Read in CA cert, private key and certificate
476                          * request in global variables.
477                          */
478                         read_ca_cert();
479
480                         if (!k_flag) {
481                           fprintf(stderr, "%s: missing private key (-k)\n", pname);
482                           exit (SCEP_PKISTATUS_FILE);
483                         }
484                         read_key(&rsa, k_char);
485
486                         if ((K_flag && !O_flag) || (!K_flag && O_flag)) {
487                           fprintf(stderr, "%s: -O also requires -K (and vice-versa)\n", pname);
488                           exit (SCEP_PKISTATUS_FILE);
489                         }
490
491                         if (K_flag) {
492                           read_key(&renewal_key, K_char);
493                         }
494
495                         if (O_flag) {
496                           read_cert(&renewal_cert, O_char);
497                         }
498
499                         if (operation_flag == SCEP_OPERATION_ENROLL)
500                                 read_request();
501
502                         /*
503                          * Create a new SCEP transaction and self-signed
504                          * certificate based on cert request
505                          */
506                         if (v_flag)
507                                 fprintf(stdout, "%s: new transaction\n", pname);
508                         new_transaction(&scep_t);
509                         if (operation_flag != SCEP_OPERATION_ENROLL)
510                                 goto not_enroll;
511                         if (v_flag)
512                                   fprintf(stdout, "%s: generating selfsigned "
513                                         "certificate\n", pname);
514
515                         if (! O_flag) 
516                           new_selfsigned(&scep_t);
517                         else {
518                           /* Use existing certificate */
519                           scep_t.signercert = renewal_cert;
520                           scep_t.signerkey = renewal_key;
521                         }
522
523                         /* Write the selfsigned certificate if requested */
524                         if (L_flag) {
525                                 /* Write PEM-formatted file: */
526                                 if (!(fp = fopen(L_char, "w"))) {
527                                         fprintf(stderr, "%s: cannot open "
528                                           "file for writing\n", pname);
529                                         exit (SCEP_PKISTATUS_ERROR);
530                                 }
531                                 if (PEM_write_X509(fp,scep_t.signercert) != 1) {
532                                         fprintf(stderr, "%s: error while "
533                                           "writing certificate file\n", pname);
534                                         ERR_print_errors_fp(stderr);
535                                         exit (SCEP_PKISTATUS_ERROR);
536                                 }
537                                 printf("%s: selfsigned certificate written "
538                                         "as %s\n", pname, L_char);
539                                 (void)fclose(fp);
540                         }
541                         /* Write issuer name and subject (GetCertInitial): */
542                         if (!(scep_t.ias_getcertinit->subject =
543                                         X509_REQ_get_subject_name(request))) {
544                                 fprintf(stderr, "%s: error getting subject "
545                                         "for GetCertInitial\n", pname);
546                                 ERR_print_errors_fp(stderr);
547                                 exit (SCEP_PKISTATUS_ERROR);
548                         }
549 not_enroll:
550                         if (!(scep_t.ias_getcertinit->issuer =
551                                          X509_get_issuer_name(cacert))) {
552                                 fprintf(stderr, "%s: error getting issuer "
553                                         "for GetCertInitial\n", pname);
554                                 ERR_print_errors_fp(stderr);
555                                 exit (SCEP_PKISTATUS_ERROR);
556                         }
557                         /* Write issuer name and serial (GETC{ert,rl}): */
558                         scep_t.ias_getcert->issuer =
559                                  scep_t.ias_getcertinit->issuer;
560                         scep_t.ias_getcrl->issuer =
561                                  scep_t.ias_getcertinit->issuer;
562                         if (!(scep_t.ias_getcrl->serial =
563                                         X509_get_serialNumber(cacert))) {
564                                 fprintf(stderr, "%s: error getting serial "
565                                         "for GetCertInitial\n", pname);
566                                 ERR_print_errors_fp(stderr);
567                                 exit (SCEP_PKISTATUS_ERROR);
568                         }
569                         /* User supplied serial number */
570                         if (s_flag) {
571                             if (!(ASN1_INTEGER_set(scep_t.ias_getcert->serial,
572                                                 (long)atoi(s_char)))) {
573                                         fprintf(stderr, "%s: error converting "
574                                                 "serial\n", pname);
575                                         ERR_print_errors_fp(stderr);
576                                         exit (SCEP_PKISTATUS_ERROR);
577                                 }
578                         }
579                 break;
580         }
581         switch(operation_flag) {
582                 case SCEP_OPERATION_ENROLL:
583                         if (v_flag)
584                                 fprintf(stdout,
585                                         "%s: SCEP_OPERATION_ENROLL\n", pname);
586                         /* Resum mode: set GetCertInitial */
587                         if (R_flag) {
588                                 if (n_num == 0)
589                                         exit (SCEP_PKISTATUS_SUCCESS);
590                                 printf("%s: requesting certificate (#1)\n",
591                                         pname);
592                                 scep_t.request_type = SCEP_REQUEST_GETCERTINIT;
593                                 count++;
594                         } else {
595                                 printf("%s: sending certificate request\n",
596                                         pname);
597                                 scep_t.request_type = SCEP_REQUEST_PKCSREQ;
598                         }
599                         break;
600
601                 case SCEP_OPERATION_GETCERT:
602                         if (v_flag)
603                                 fprintf(stdout,
604                                         "%s: SCEP_OPERATION_GETCERT\n", pname);
605
606                         scep_t.request_type = SCEP_REQUEST_GETCERT;
607                         printf("%s: requesting certificate\n",pname);
608                         break;
609
610                 case SCEP_OPERATION_GETCRL:
611                         if (v_flag)
612                                 fprintf(stdout,
613                                         "%s: SCEP_OPERATION_GETCRL\n", pname);
614
615                         scep_t.request_type = SCEP_REQUEST_GETCRL;
616                         printf("%s: requesting crl\n",pname);
617                         break;
618                 }
619
620                 /* Enter polling loop */
621                 while (scep_t.pki_status != SCEP_PKISTATUS_SUCCESS) {
622                         /* create payload */
623                         pkcs7_wrap(&scep_t);
624
625                         /* URL-encode */
626                         p = url_encode(scep_t.request_payload,
627                                 scep_t.request_len);
628
629                         /* Forge the HTTP message */
630                         snprintf(http_string, sizeof(http_string),
631                                 "GET %s%s?operation="
632                                 "PKIOperation&message="
633                                 "%s HTTP/1.0\r\n\r\n",
634                                 p_flag ? "" : "/", dir_name, p); 
635
636                         if (d_flag)
637                                 fprintf(stdout, "%s: scep msg: %s",
638                                         pname, http_string);
639
640                         /* send http */
641                         reply.payload = NULL;
642                         if ((c = send_msg (&reply, http_string, host_name,
643                                         host_port, operation_flag)) == 1) {
644                                 fprintf(stderr, "%s: error while sending "
645                                         "message\n", pname);
646                                 exit (SCEP_PKISTATUS_NET);
647                         }
648                         /* Verisign Onsite returns strange reply...
649                          * XXXXXXXXXXXXXXXXXXX */
650                         if ((reply.status == 200) && (reply.payload == NULL)) {
651                                 /*
652                                 scep_t.pki_status = SCEP_PKISTATUS_PENDING;
653                                 break;
654                                 */
655                                 exit (SCEP_PKISTATUS_ERROR);
656                         }
657                         printf("%s: valid response from server\n", pname);
658
659                         /* Check payload */
660                         scep_t.reply_len = reply.bytes;
661                         scep_t.reply_payload = reply.payload;
662                         pkcs7_unwrap(&scep_t);
663                         pkistatus = scep_t.pki_status;
664
665                         switch(scep_t.pki_status) {
666                                 case SCEP_PKISTATUS_SUCCESS:
667                                         break;
668                                 case SCEP_PKISTATUS_PENDING:
669                                         /* Check time limits */
670                                         if (((t_num * count) >= T_num) ||
671                                             (count > n_num)) {
672                                                 exit (pkistatus);
673                                         }
674                                         scep_t.request_type =
675                                                 SCEP_REQUEST_GETCERTINIT;
676
677                                         /* Wait for poll interval */
678                                         if (v_flag)
679                                           printf("%s: waiting for %d secs\n",
680                                                 pname, t_num);
681                                         sleep(t_num);
682                                         printf("%s: requesting certificate "
683                                                 "(#%d)\n", pname, count);
684
685                                         /* Add counter */
686                                         count++;
687                                         break;
688
689                                 case SCEP_PKISTATUS_FAILURE:
690
691                                         /* Handle failure */
692                                         switch (scep_t.fail_info) {
693                                                 case SCEP_FAILINFO_BADALG:
694                                                   exit (SCEP_PKISTATUS_BADALG);
695                                                 case SCEP_FAILINFO_BADMSGCHK:
696                                                   exit (SCEP_PKISTATUS_BADMSGCHK);
697                                                 case SCEP_FAILINFO_BADREQ:
698                                                   exit (SCEP_PKISTATUS_BADREQ);
699                                                 case SCEP_FAILINFO_BADTIME:
700                                                   exit (SCEP_PKISTATUS_BADTIME);
701                                                 case SCEP_FAILINFO_BADCERTID:
702                                                   exit (SCEP_PKISTATUS_BADCERTID);
703                                                 /* Shouldn't be there... */
704                                                 default:
705                                                   exit (SCEP_PKISTATUS_ERROR);
706                                         }
707                                 default:
708                                         fprintf(stderr, "%s: unknown "
709                                                 "pkiStatus\n", pname);  
710                                         exit (SCEP_PKISTATUS_ERROR);
711                         }
712         }
713         /* We got SUCCESS, analyze the reply */
714         switch (scep_t.request_type) {
715
716                 /* Local certificate */
717                 case SCEP_REQUEST_PKCSREQ:
718                 case SCEP_REQUEST_GETCERTINIT:
719                         write_local_cert(&scep_t);
720                         break;
721
722                 /* Other end entity certificate */
723                 case SCEP_REQUEST_GETCERT:
724                         write_other_cert(&scep_t);
725                         break;
726
727                         break;
728                 /* CRL */
729                 case SCEP_REQUEST_GETCRL:
730                         write_crl(&scep_t);
731                         break;
732         }
733         return (pkistatus);
734 }
735
736 void
737 usage() {
738         fprintf(stdout, "\nsscep version %s\n\n" , VERSION);
739         fprintf(stdout, "Usage: %s OPERATION [OPTIONS]\n"
740         "\nAvailable OPERATIONs are\n"
741         "  getca             Get CA/RA certificate(s)\n"
742         "  enroll            Enroll certificate\n"
743         "  getcert           Query certificate\n"
744         "  getcrl            Query CRL\n"
745         "\nGeneral OPTIONS\n"
746         "  -u <url>          SCEP server URL\n"
747         "  -p <host:port>    Use proxy server at host:port\n"
748         "  -f <file>         Use configuration file\n"
749         "  -c <file>         CA certificate file (write if OPERATION is getca)\n"
750         "  -E <name>         PKCS#7 encryption algorithm (des|3des|blowfish)\n"
751         "  -S <name>         PKCS#7 signature algorithm (md5|sha1)\n"
752         "  -v                Verbose operation\n"
753         "  -d                Debug (even more verbose operation)\n"
754         "\nOPTIONS for OPERATION getca are\n"
755         "  -i <string>       CA identifier string\n"
756         "  -F <name>         Fingerprint algorithm\n"
757         "\nOPTIONS for OPERATION enroll are\n"
758         "  -k <file>         Private key file\n"
759         "  -r <file>         Certificate request file\n"
760         "  -K <file>         Signature private key file, use with -O\n"
761         "  -O <file>         Signature certificate (used instead of self-signed)\n"
762         "  -l <file>         Write enrolled certificate in file\n"
763         "  -e <file>         Use different CA cert for encryption\n"
764         "  -L <file>         Write selfsigned certificate in file\n"
765         "  -t <secs>         Polling interval in seconds\n"
766         "  -T <secs>         Max polling time in seconds\n"
767         "  -n <count>        Max number of GetCertInitial requests\n"
768         "  -R                Resume interrupted enrollment\n"
769         "\nOPTIONS for OPERATION getcert are\n"
770         "  -k <file>         Private key file\n"
771         "  -l <file>         Local certificate file\n"
772         "  -s <number>       Certificate serial number\n"
773         "  -w <file>         Write certificate in file\n"
774         "\nOPTIONS for OPERATION getcrl are\n"
775         "  -k <file>         Private key file\n"
776         "  -l <file>         Local certificate file\n"
777         "  -w <file>         Write CRL in file\n\n", pname);
778         exit(0);
779 }
780
781 void
782 catchalarm(int signo) {
783         fprintf(stderr, "%s: connection timed out\n", pname);
784         exit (SCEP_PKISTATUS_TIMEOUT);
785 }