x400_msrcv_sign.c
1/* Copyright (c) 2003-2013, Isode Limited, London, England.
2 * All rights reserved.
3 *
4 * Acquisition and use of this software and related materials for any
5 * purpose requires a written licence agreement from Isode Limited,
6 * or a written licence from an organisation licenced by Isode Limited
7 * to grant such a licence.
8 *
9 */
10
11/*
12 *
13 * @VERSION@
14 * Simple example program for receiving a message from a store.
15 * The security environment is set up so that signed messages
16 * will have the MOAC verified.
17 *
18 * Note that a valid Digital Identity is no longer required in order to
19 * perform verification. Instead the name of a directory containing trusted,
20 * self signed certificates in DER form can be passed in.
21 */
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <x400_msapi.h>
26#include <seclabel_api.h> /* For security labels */
27#include "example.h"
28#include "ms_example.h"
29
30int num_unsigned_rcvd;
31int num_unverified_rcvd;
32int num_verified_rcvd;
33
34static char *optstr = "u37m:d:p:w:M:D:P:W:e:b:x:Y:U:";
35
36static void usage(void);
37
38
39static int get_msg(
40 struct X400msSession *sp
41);
42
43static void setup_default_new_sec_env(
44 struct X400msSession *sp,
45 char *sec_trusted_cert_dir
46);
47
48static void setup_default_old_sec_env(
49 struct X400msSession *sp,
50 char *id,
51 char *dn,
52 char *pw /* passphrase for private key in pkcs12 file */
53);
54
55static int report_moac_info(
56 struct X400msMessage *mp
57);
58
59static void show_4406_certificate (struct X400msMessage *mp);
60static void show_certificate (struct X400msMessage *mp);
61static int report_4406_info(
62 struct X400msMessage *mp
63);
64
65static void print_sec_label(
66 char slab_buffer[],
67 unsigned int length
68);
69
73int
74main(
75 int argc,
76 char **argv)
77{
78 char buffer[BUFSIZ];
79 char pa[BUFSIZ];
80 char orn[BUFSIZ];
81 int status;
82 int nummsg;
83 struct X400msSession *sp;
84 int contype;
85 char *def_oraddr;
86 char *def_dn;
87 char *def_pa;
88
89 if (get_args(argc, argv, optstr)) {
90 usage();
91 exit(-1);
92 }
93
94 printf("Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [%d]: ", x400_contype);
95 contype = ic_fgetc(x400_contype, stdin);
96 if (contype != 10)
97 ic_fgetc(x400_contype, stdin);
98
99 if ( contype < '0' || '2' < contype )
100 contype = x400_contype;
101 else
102 contype -= '0';
103
104 if (contype == 0) {
105 def_oraddr = x400_ms_user_addr;
106 def_dn = x400_ms_user_dn;
107 def_pa = x400_ms_presentation_address;
108 }
109 else {
110 def_oraddr = x400_mta_user_addr;
111 def_dn = x400_mta_user_dn;
112 def_pa = x400_mta_presentation_address;
113 }
114
115 printf("Your ORAddress [%s] > ", def_oraddr);
116 ic_fgets(orn, sizeof orn, stdin);
117
118 if (orn[strlen(orn) - 1] == '\n')
119 orn[strlen(orn) - 1] = '\0';
120
121 if (orn[0] == '\0')
122 strcpy(orn, def_oraddr);
123
124 /* Prompt for password; note: reflected. */
125 printf("Password [%s]: ",
126 contype == 0 ? x400_p7_password : x400_p3_password);
127 if (ic_fgets(buffer, sizeof buffer, stdin) == NULL)
128 exit(1);
129
130 if (buffer[strlen(buffer) - 1] == '\n')
131 buffer[strlen(buffer) - 1] = '\0';
132 if (buffer[0] == '\0')
133 strcpy(buffer, contype == 0 ? x400_p7_password : x400_p3_password);
134
135 printf("Presentation Address [%s] > ", def_pa);
136 ic_fgets(pa, sizeof pa, stdin);
137
138 if (pa[strlen(pa) - 1] == '\n')
139 pa[strlen(pa) - 1] = '\0';
140
141 if (pa[0] == '\0')
142 strcpy(pa, def_pa);
143
144 status = X400msOpen(contype, orn, def_dn, buffer, pa, &nummsg, &sp);
145 if (status != X400_E_NOERROR) {
146 fprintf(stderr, "Error in Open: %s\n", X400msError(status));
147 exit(status);
148 }
149
150#ifdef USING_ALERTS
151 /* If we register the alert auto-action, we will get an alert indication
152 when a message is delivered. So there is no need to poll at
153 short intervals within X400ms_Wait - we can do a slow background
154 poll and rely on the Alert indication to wake the code up instead */
156#endif
157
158 /* setup logging from $(ETCDIR)x400api.xml or $(SHAREDIR)x400api.xml */
160
161 if (contype == 0) {
162#ifdef WANT_AUTOFORWARDING
163 struct X400msAutoActionParameter *aa_param;
164
165 /* Register an Autoforwarding Autoaction. */
166 aa_param = X400msNewAutoActionParameter();
167
168 /* Add mandatory things to AutoAction parameter for auto-forwarding:
169 i.e. recipient address */
170 X400RecipNew(0, &rp);
171
173 strlen(def_oraddr));
174
176
179 "AF contentid", -1);
180
182
185 1);
186
189 1);
190
193 1);
194
196
199 "This message was autoforwarded",
200 -1);
201
204 "This is a cover note", -1);
205
208 "AutoForwarded:", -1);
209
211 4, aa_param);
212 if (status != X400_E_NOERROR) {
213 fprintf(stderr,
214 "Error in RegisterAutoAction: %s\n", X400msError(status));
215 /* tidily close the session */
216 status = X400msClose(sp);
217 exit(status);
218 }
219 printf("Registered AutoForwarding autoaction (id = 4) OK\n");
221#endif
222
223#ifdef USING_ALERTS
224 /* No parameter needed for Alert autoaction - we do not support
225 configuration of requested-attributes in this API yet. */
226 status = X400msRegisterAutoAction(sp, X400_AUTO_ALERT, 9, NULL);
227 if (status != X400_E_NOERROR) {
228 fprintf(stderr, "Error in RegisterAutoAction: %s\n",
229 X400msError(status));
230 /* tidily close the session */
231 status = X400msClose(sp);
232 exit(status);
233 }
234 printf("Registered AutoAlert autoaction (id = 9) OK\n");
235#endif
236
237 /* Just test the register and deregister functions */
238 status = X400msRegisterAutoAction(sp, X400_AUTO_ALERT, 10, NULL);
239 if (status != X400_E_NOERROR) {
240 fprintf(stderr, "Error in RegisterAutoAction: %s\n",
241 X400msError(status));
242 /* tidily close the session */
243 status = X400msClose(sp);
244 exit(status);
245 }
246 printf("Registered AutoAlert autoaction (id = 10) OK\n");
247
248 /* Lets do a deregistration of the action we just registered */
250 if (status != X400_E_NOERROR) {
251 fprintf(stderr, "Error in DeregisterAutoAction: %s\n",
252 X400msError(status));
253 /* tidily close the session */
254 status = X400msClose(sp);
255 exit(status);
256 }
257 printf("Deregistered AutoAlert autoaction (id = 10) OK\n");
258 }
259
260 if (nummsg == 0) {
261 printf ("no messages - waiting 60 seconds for a message to be delivered.....\n");
262 }
263 else {
264 printf("%d messages waiting\n", nummsg);
265 }
266
267 status = get_msg(sp);
268 if (status != X400_E_NOERROR) {
269 fprintf(stderr, "Error in getting msg: %s\n",
270 X400msError(status));
271 exit(status);
272 }
273 fprintf(stderr, "got first\n");
274 status = get_msg(sp);
275 if (status != X400_E_NOERROR) {
276 fprintf(stderr, "Error in getting msg: %s\n",
277 X400msError(status));
278 exit(status);
279 }
280 fprintf(stderr, "got second\n");
281
282 status = get_msg(sp);
283 if (status != X400_E_NOERROR) {
284 fprintf(stderr, "Error in getting msg: %s\n",
285 X400msError(status));
286 exit(status);
287 }
288 fprintf(stderr, "got third\n");
289
290 status = get_msg(sp);
291 if (status != X400_E_NOERROR) {
292 fprintf(stderr, "Error in getting msg: %s\n",
293 X400msError(status));
294 exit(status);
295 }
296 fprintf(stderr, "got third\n");
297
298 status = get_msg(sp);
299 if (status != X400_E_NOERROR) {
300 fprintf(stderr, "Error in getting msg: %s\n",
301 X400msError(status));
302 exit(status);
303 }
304 fprintf(stderr, "got third\n");
305
306 status = get_msg(sp);
307 if (status != X400_E_NOERROR) {
308 fprintf(stderr, "Error in getting msg: %s\n",
309 X400msError(status));
310 exit(status);
311 }
312 fprintf(stderr, "got third\n");
313
314 status = X400msClose(sp);
315 printf("%d num_unsigned_rcvd\n", num_unsigned_rcvd);
316 printf("%d num_unverified_rcvd\n", num_unverified_rcvd);
317 printf("%d num_verified_rcvd\n", num_verified_rcvd);
318 return(status);
319}
320
321
322static int get_msg(
323 struct X400msSession *sp
324)
325{
326 char buffer[BUFSIZ];
327 int status, sig_status;
328 int nummsg;
329 int type;
330 int seqn;
331 struct X400msMessage *mp;
332 struct X400Recipient *rp;
333 int n;
334 size_t length;
335 int intparam;
336 char recipient_str[BUFSIZ];
337
338 printf("Waiting for new messages for 10 seconds\n");
339 status = X400msWait(sp, 10, &nummsg);
340 if (status != X400_E_NOERROR) {
341 fprintf(stderr, "Error from Wait: %s\n", X400msError(status));
342 /* tidily close the session */
343 status = X400msClose(sp);
344 exit(status);
345 }
346 printf("------------- New Message ----------------\n");
347
348 /* Set up the security environment.
349 *
350 * In R15.0 this need only be the name of a trusted certificate directory.
351 *
352 * Prior to R15.0, the ID is specified as a pathname, in which the
353 * subdirectory "x509" is expected to contain one or more PKCS12
354 * files. The appropriate Digital Identity is determined from the
355 * DN of the subject, and the passphrase is used to decrypt the
356 * private key. NB even though we're not going to use our cert,
357 * (as we're going to use the cert in the message to check the MOAC
358 * we need to do this due to a limitation in the underlying X.509
359 * layer.
360 */
361 if (use_new_sec_env) {
362 setup_default_new_sec_env(sp, trusted_ca_certs_dir);
363 } else {
364 setup_default_old_sec_env(sp, security_id, identity_dn, passphrase);
365 }
366
367
368 /* Turn off legacy bahaviour in which MOAC verification failure
369 * returns X400_E_NOERROR.
370 * We will now get X400_E_X509_VERIFY_FAILURE from MsgGet
371 * if/when the verification fails
372 */
374
375 if (x400_default_recipient != NULL)
376 printf("Getting message\n");
377 status = X400msMsgGet(sp, 0, &mp, &type, &seqn);
378 switch (status) {
379 case X400_E_NOERROR:
380 fprintf(stderr, "MsgGet successfully got message\n");
381 break;
382 default :
383 fprintf(stderr, "Error from MsgGet: %s\n", X400msError(status));
384 /* tidily close the session */
385 status = X400msClose(sp);
386 exit(status);
387 break;
388 }
389
390 if (type != X400_MSG_MESSAGE) {
391 fprintf(stderr, "Got a report (printing only some attributes)\n");
392
393 /* The ORADDRESS in the message is the (envelope) originator */
395 buffer, sizeof buffer, &length);
396 if (status != X400_E_NOERROR) {
397 fprintf(stderr, "Error from MsgGetStrParam: %s\n",
398 X400msError(status));
399 /* tidily close the session */
400 status = X400msClose(sp);
401 exit(status);
402 }
403 printf("Subject Identifier: %.*s\n", (int)length, buffer);
404
405 /* Get the primary recipients */
406 for (n = 1;; n++) {
407 status = X400msRecipGet(mp, X400_RECIP_REPORT, n, &rp);
408 if (status == X400_E_NO_RECIP)
409 break;
410 if (status != X400_E_NOERROR) {
411 fprintf(stderr, "Error from RecipGet: %s\n",
412 X400msError(status));
413 /* tidily close the session */
414 status = X400msClose(sp);
415 exit(status);
416 }
417
418 /* Note: recipient may not actually have an O/R address */
420 recipient_str,
421 sizeof recipient_str, &length);
422 if (status != X400_E_NOERROR) {
423 fprintf(stderr, "Error from RecipGetStrParam: %s\n",
424 X400msError(status));
425 /* tidily close the session */
426 status = X400msClose(sp);
427 exit(status);
428 }
429 /* print out the O/R Address of the report */
430 printf("Positive Delivery Report for recipient %d: %.*s\n", n,
431 (int)length, recipient_str);
432
433 /* The original message delivery time, if this attribute exists,
434 * then the report is a positive Delivery Report */
436 buffer, sizeof buffer, &length);
437 if (status == X400_E_NOERROR) {
438 /* Positive Delivery Report */
439 printf("Delivery Time: %.*s\n", (int)length, buffer);
440 }
441 else {
442 /* Negative Delivery Report */
443 printf("Negative Delivery Report for recipient %d: %s\n", n,
444 recipient_str);
445
446 /* Supplementary Info to the report */
448 buffer, sizeof buffer,
449 &length);
450 if (status != X400_E_NOERROR) {
451 fprintf(stderr, "Error from RecipGetStrParam: %s\n",
452 X400msError(status));
453 buffer[0] = '\0';
454 }
455 printf("Supplementary Info: %.*s\n", (int)length, buffer);
456
457 /* The reason why the message was not delivered */
458 status =
460 &intparam);
461 if (status != X400_E_NOERROR) {
462 fprintf(stderr, "Error from MsgGetIntParam: %s\n",
463 X400msError(status));
464 }
465 printf("Non-Delivery Reason: %d\n", intparam);
466
467 /* The diagnostics of the report for this recipient */
468 status =
470 &intparam);
471 if (status != X400_E_NOERROR) {
472 fprintf(stderr, "Error from MsgGetIntParam: %s\n",
473 X400msError(status));
474 }
475 printf("Non-Delivery Diagnostic: %d\n", intparam);
476 }
477 }
478
479 num_unsigned_rcvd++ ;
480 status = X400msMsgDelete(mp, 0);
481 if (status != X400_E_NOERROR) {
482 fprintf(stderr, "Error from X400msMsgDelete: %s\n",
483 X400msError(status));
484 }
485 return (status);
486 }
487
488 /* report information about the MOAC in the message */
489 (void) report_moac_info(mp);
490
491 /* report information about the 4406 in the message */
492 sig_status = report_4406_info(mp);
493
494 /* X.411 security label */
496 buffer, sizeof buffer, &length);
497 if (status == X400_E_NOERROR) {
498 printf("X.411 Security Label returned OK (%d chars)\n", (int)length);
499 print_sec_label(buffer, length);
500 } else {
501 printf("X.411 Security Label not returned (%d) (%s)\n", status,
502 X400msError(status));
503 }
504
505 /* content type */
506 status = X400msMsgGetIntParam(mp, X400_N_CONTENT_TYPE, &intparam);
507 if (status == X400_E_NOERROR) {
508 printf ("Content type : P%d\n", intparam);
509 } else {
510 fprintf(stderr, "No content type: Error from MsgGetStrParam: %s\n",
511 X400msError(status));
512 }
513
514 /* external content type */
516 buffer, sizeof buffer, &length);
517 if (status == X400_E_NOERROR) {
518 printf("External Content Type: %.*s\n", (int)length, buffer);
519 } else {
520 fprintf(stderr, "No content type: Error from MsgGetStrParam: %s\n",
521 X400msError(status));
522 }
523
524
525 /* The message identifier */
527 buffer, sizeof buffer, &length);
528 if (status != X400_E_NOERROR) {
529 fprintf(stderr, "Error from MsgGetStrParam: %s\n",
530 X400msError(status));
531 /* tidily close the session */
532 status = X400msClose(sp);
533 exit(status);
534 }
535 printf("Message Identifier: %.*s\n", (int)length, buffer);
536
537 /* The ORADDRESS in the message is the (envelope) originator */
539 buffer, sizeof buffer, &length);
540 if (status != X400_E_NOERROR) {
541 fprintf(stderr, "Error from MsgGetStrParam: %s\n",
542 X400msError(status));
543 /* tidily close the session */
544 status = X400msClose(sp);
545 exit(status);
546 }
547 printf("Originator: %.*s\n", (int)length, buffer);
548
549 if (sig_status == X400_E_S4406_TRIPLE_WRAPPED) {
550 /* can't do much more with an encrypted message ... */
551 printf("Deleting triple wrapped message\n");
552
553 /* Deletes message in message store as well as internal copy */
554 status = X400msMsgDelete(mp, 0);
555 return status;
556 }
557
558 /* Get the primary recipients */
559 for (n = 1;; n++) {
560 status = X400msRecipGet(mp, X400_RECIP_PRIMARY, n, &rp);
561 if (status == X400_E_NO_RECIP)
562 break;
563 if (status != X400_E_NOERROR) {
564 fprintf(stderr, "Error from RecipGet: %s\n", X400msError(status));
565 /* tidily close the session */
566 status = X400msClose(sp);
567 exit(status);
568 }
569
570 /* Note: recipient may not actually have an O/R address */
572 buffer, sizeof buffer, &length);
573 if (status == X400_E_NOERROR) {
574 printf("Recipient %d: %.*s\n", n, (int)length, buffer);
575 }
576
577 status = X400msRecipGetIntParam(rp, X400_N_PRECEDENCE, &intparam);
578 if (status == X400_E_NOERROR) {
579 printf("Primary Recipient Precedence %d\n", intparam);
580 } else {
581 fprintf(stderr, "Error from RecipGet: %s\n", X400msError(status));
582 }
583
584 }
585
586 /* Subject is optional */
588 buffer, sizeof buffer, &length);
589 if (status == X400_E_NOERROR)
590 printf("Subject: %.*s\n", (int)length, buffer);
591
592 /* external content type */
594 buffer, sizeof buffer, &length);
595 if (status == X400_E_NOERROR)
596 printf("External Content Type: %.*s\n", (int)length, buffer);
597
598 /* And message text (or it could be another type) */
600 buffer, sizeof buffer, &length);
601 if (status == X400_E_NOERROR) {
602 printf("\nIA5 Text:\n%.*s\n\n", (int)length, buffer);
603 } else {
604 fprintf (stderr, "No IA5 text in message");
605 fprintf (stderr, "X400msMsgGetStrParam returned error: %s\n",
606 X400msError (status));
607 }
608
609 /* get all the attachments */
610 printf("Getting body parts\n");
611 get_body_parts(mp);
612
613 /* Deletes message in message store as well as internal copy */
614 status = X400msMsgDelete(mp, 0);
615
616 return status;
617}
618
619/*
620 * Recommended function to setup security env for verification.
621 * No digitial ID required - just a directory which contains
622 * trust anchors which are read as DER file (certificate.crt).
623 *
624 * The certificate (containing public key) is obtained from the message
625 * which is referenced in the message.
626 */
627
628static void setup_default_new_sec_env(
629 struct X400msSession *sp,
630 char *trusted_ca_certs_directory
631)
632{
633 int status;
634
635 /* Directory containing trusted CA Certificates */
636 printf("Adding %s as trusted CA cert dir\n", trusted_ca_certs_directory);
638 trusted_ca_certs_directory, -1);
639 if ( status != X400_E_NOERROR ) {
640 fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
641 X400msError (status));
642 exit (status);
643 }
644
645 return;
646}
647
648/*
649 * Obsolete function to use to set up the security environment. This provides a
650 * directory in which PKCS12 files are checked to find one whose subject DN
651 * matches that of this client.
652 *
653 * Any self signed certificates found in the directory are treated as
654 * trusted.
655 */
656
657static void setup_default_old_sec_env(
658 struct X400msSession *sp,
659 char *id,
660 char *dn,
661 char *pw /* passphrase for private key in pkcs12 file */
662)
663{
664 int status;
665
666 /* first set a default security identity. This passes in the name of a
667 * directory, which contains an x509 subdirectory in which all Identities
668 * are held */
669 /* X400msSetStrDefault(sp, X400_S_SEC_IDENTITY, "/var/isode/dsa-db/", -1);
670 * */
672
673 /* select by DN which Identity is to be used (if there are several)
674 * Currently these must be PKCS12 files */
675 status = X400msSetStrDefault (sp, X400_S_SEC_IDENTITY_DN, dn, -1);
676 if ( status != X400_E_NOERROR ) {
677 fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
678 X400msError (status));
679 exit (status);
680 }
681
682 /* passphrase used to open the Identity */
684 if ( status != X400_E_NOERROR ) {
685 fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
686 X400msError (status));
687 exit (status);
688 }
689 return;
690}
691
692
693static int report_moac_info(
694 struct X400msMessage *mp
695)
696{
697 int status;
698 int intparam;
699
700 /* Check the MOAC */
701 status = X400msMsgGetIntParam(mp, X400_N_MOAC_STATUS, &intparam);
702 switch ( status ) {
703 case X400_E_NO_VALUE:
704 num_unverified_rcvd++ ;
705 fprintf (stderr, "No MOAC in message\n");
706 break;
707
708 default:
709 num_unverified_rcvd++ ;
710 fprintf (stderr, "Unexpected error getting MOAC status: %s\n",
711 X400msError (status));
712 break;
713
714 case X400_E_NOERROR:
715 fprintf (stderr, "Have MOAC in message (%d)\n", intparam);
716 switch (intparam) {
717 case X400_E_NOERROR:
718 fprintf(stderr,
719 "MsgGet successfully verified signature in message\n");
720 show_certificate (mp);
721 fprintf(stderr, "continuing ...\n");
722 num_verified_rcvd++ ;
723 break;
725 fprintf(stderr,
726 "MOAC validation cannot take place because the security environment is invalid (%d):\n",
727 intparam);
728 /* other values will not be available */
729 break;
730 case X400_E_X509_INIT:
731 case X400_E_X509_ENV:
732 fprintf(stderr,
733 "MOAC validation cannot take place because the security environment is invalid (%d):\n",
734 intparam);
735 /* other values will not be available */
736 break;
738 fprintf(stderr, "Verification Error from MsgGet: %s\n",
739 X400msError(intparam));
740 show_certificate (mp);
741 fprintf(stderr, "continuing ...\n");
742 num_unverified_rcvd++ ;
743 break;
745 fprintf(stderr, "Verification Error from MsgGet: %s\n",
746 X400msError(intparam));
747 fprintf(stderr, "continuing ...\n");
748 num_unverified_rcvd++ ;
749 break;
751 fprintf(stderr, "Verification Error from MsgGet: %s\n",
752 X400msError(intparam));
753 show_certificate (mp);
754 fprintf(stderr, "continuing ...\n");
755 num_unverified_rcvd++ ;
756 break;
758 fprintf(stderr, "Verification Error from MsgGet: %s\n",
759 X400msError(intparam));
760 show_certificate (mp);
761 fprintf(stderr, "continuing ...\n");
762 num_unverified_rcvd++ ;
763 break;
765 fprintf(stderr, "Verification Error from MsgGet: %s\n",
766 X400msError(intparam));
767 show_certificate (mp);
768 fprintf(stderr, "continuing ...\n");
769 num_unverified_rcvd++ ;
770 break;
772 fprintf(stderr, "Verification Error from MsgGet: %s\n",
773 X400msError(intparam));
774 show_certificate (mp);
775 fprintf(stderr, "continuing ...\n");
776 num_unverified_rcvd++ ;
777 break;
779 fprintf(stderr, "Verification Error from MsgGet: %s\n",
780 X400msError(intparam));
781 show_certificate (mp);
782 fprintf(stderr, "continuing ...\n");
783 num_unverified_rcvd++ ;
784 break;
785 default :
786 fprintf(stderr,
787 "Unexpected verification error from MsgGet(%d): %s\n",
788 intparam,
789 X400msError(intparam));
790 show_certificate (mp);
791 fprintf(stderr, "continuing ...\n");
792 num_unverified_rcvd++ ;
793 break;
794 }
795 }
796 return X400_E_NOERROR;
797}
798
799
800static int report_4406_info(
801 struct X400msMessage *mp
802)
803{
804 int status;
805 int intparam;
806 size_t length;
807 char buffer[BUFSIZ];
808
809 /* Check the 4406 signatures */
810 status = X400msMsgGetIntParam(mp, X400_N_S4406_STATUS, &intparam);
811 switch ( status ) {
812 case X400_E_NO_VALUE:
813 num_unverified_rcvd++ ;
814 fprintf (stderr, "No 4406 signature in message\n");
815 return X400_E_NOERROR;
816
817 default:
818 num_unverified_rcvd++ ;
819 fprintf (stderr, "Unexpected error getting 4406 signature status: %s\n",
820 X400msError (status));
821 break;
822
823 case X400_E_NOERROR:
824 fprintf (stderr, "Have 4406 signature in message (%d)\n", intparam);
825 switch (intparam) {
826 case X400_E_NOERROR:
827 fprintf(stderr,
828 "MsgGet successfully verified signature in message\n");
829 show_4406_certificate (mp);
830 fprintf(stderr, "continuing ...\n");
831 num_verified_rcvd++ ;
832 break;
834 fprintf(stderr,
835 "4406 signature validation cannot take place because the security environment is invalid (%d):\n",
836 intparam);
837 /* other values will not be available */
838 break;
839 case X400_E_X509_INIT:
840 case X400_E_X509_ENV:
841 fprintf(stderr,
842 "4406 signature validation cannot take place because the security environment is invalid (%d):\n",
843 intparam);
844 /* other values will not be available */
845 break;
847 fprintf(stderr, "Verification Error from MsgGet: %s\n",
848 X400msError(intparam));
849 show_4406_certificate (mp);
850 fprintf(stderr, "continuing ...\n");
851 num_unverified_rcvd++ ;
852 break;
854 fprintf(stderr, "Verification Error from MsgGet: %s\n",
855 X400msError(intparam));
856 fprintf(stderr, "continuing ...\n");
857 num_unverified_rcvd++ ;
858 break;
860 fprintf(stderr, "Verification Error from MsgGet: %s\n",
861 X400msError(intparam));
862 show_4406_certificate (mp);
863 fprintf(stderr, "continuing ...\n");
864 num_unverified_rcvd++ ;
865 break;
867 fprintf(stderr, "Verification Error from MsgGet: %s\n",
868 X400msError(intparam));
869 show_4406_certificate (mp);
870 fprintf(stderr, "continuing ...\n");
871 num_unverified_rcvd++ ;
872 break;
874 fprintf(stderr, "Verification Error from MsgGet: %s\n",
875 X400msError(intparam));
876 show_4406_certificate (mp);
877 fprintf(stderr, "continuing ...\n");
878 num_unverified_rcvd++ ;
879 break;
881 fprintf(stderr, "Verification Error from MsgGet: %s\n",
882 X400msError(intparam));
883 show_4406_certificate (mp);
884 fprintf(stderr, "continuing ...\n");
885 num_unverified_rcvd++ ;
886 break;
888 fprintf(stderr, "Verification Error from MsgGet: %s\n",
889 X400msError(intparam));
890 show_4406_certificate (mp);
891 fprintf(stderr, "continuing ...\n");
892 num_unverified_rcvd++ ;
893 break;
895 fprintf(stderr, "Verification Error from MsgGet: %s\n",
896 X400msError(intparam));
897 show_certificate (mp);
898 fprintf(stderr, "continuing ...\n");
899 num_unverified_rcvd++ ;
901 default :
902 fprintf(stderr, "Unexpected verification error from MsgGet: %s\n",
903 X400msError(intparam));
904 show_4406_certificate (mp);
905 fprintf(stderr, "continuing ...\n");
906 num_unverified_rcvd++ ;
907 break;
908 }
909 }
910
911 /* 4406 security label */
912 printf("------------- 4406 Info ----------------\n");
914 buffer, sizeof buffer, &length);
915 if (status == X400_E_NOERROR) {
916 printf("4406 Security Label returned OK (%d chars)\n", (int)length);
917 print_sec_label(buffer, length);
918 } else {
919 printf("4406 Security Label not returned (%d) (%s)\n", status,
920 X400msError(status));
921 }
922
923 /* 4406 signing time */
925 buffer, sizeof buffer, &length);
926 if (status == X400_E_NOERROR)
927 printf("4406 signing time returned OK\n%.*s\n", (int)length, buffer);
928 else
929 printf("4406 signing time not returned (%d) (%s)\n", status,
930 X400msError(status));
931
932 printf("------------ End 4406 Info -----------\n");
933 return X400_E_NOERROR;
934}
935
936static void show_certificate (struct X400msMessage *mp)
937{
938 int status;
939 struct X400Certificate *cert;
940 char buffer[BUFSIZ];
941 size_t length;
942 int paramval;
943
944 status = X400msMsgGetCert (mp, X400_N_CERT_MOAC, &cert);
945 if ( status != X400_E_NOERROR ) {
946 fprintf (stderr, "Error getting MOAC certificate: %s\n",
947 X400msError (status));
948 return;
949 }
950
952 buffer, sizeof buffer, &length);
953 if (status != X400_E_NOERROR) {
954 fprintf(stderr, "Error from CertGetStrParam: %s\n",
955 X400msError(status));
956 return;
957 }
958 fprintf(stderr,
959 "subject DN of originator certificate '%.*s'\n", (int)length, buffer);
961 buffer, sizeof buffer, &length);
962 if (status != X400_E_NOERROR) {
963 fprintf(stderr, "Error from CertGetStrParam: %s\n",
964 X400msError(status));
965 return;
966 }
967 fprintf(stderr,
968 "issuer DN of originator certificate '%.*s'\n", (int)length, buffer);
969
971 buffer, sizeof buffer, &length);
972 if (status != X400_E_NOERROR) {
973 if ( status == X400_E_NO_VALUE ) {
974 fprintf(stderr, "No ORaddress subject alt. name\n");
975 } else {
976 fprintf(stderr, "Error from CertGetStrParam: %s\n",
977 X400msError(status));
978 return;
979 }
980 } else {
981 fprintf(stderr, "ORaddress subject alt name: '%.*s'\n", (int)length, buffer);
982 }
983
984 status = X400CertGetIntParam(cert, X400_N_CERT_ORADDRESS_STATUS, &paramval);
985
986 if (status != X400_E_NOERROR) {
987 fprintf(stderr, "Error from CertGetStrParam: %s\n",
988 X400msError(status));
989 return;
990 }
991
992 fprintf(stderr, "ORaddress subject alt name status: %s\n",
993 X400msError (paramval));
994}
995
996
997static void show_4406_certificate (struct X400msMessage *mp)
998{
999 int status;
1000 struct X400Certificate *cert;
1001 char buffer[BUFSIZ];
1002 size_t length;
1003 int paramval;
1004
1005 status = X400msMsgGetCert (mp, X400_N_S4406_CERTIFICATE, &cert);
1006 if ( status != X400_E_NOERROR ) {
1007 fprintf (stderr, "Error getting 4406 certificate: %s\n",
1008 X400msError (status));
1009 return;
1010 }
1011
1013 buffer, sizeof buffer, &length);
1014 if (status != X400_E_NOERROR) {
1015 fprintf(stderr, "Error from CertGetStrParam: %s\n",
1016 X400msError(status));
1017 return;
1018 }
1019 fprintf(stderr, "subject DN of originator certificate '%.*s'\n",
1020 (int)length, buffer);
1022 buffer, sizeof buffer, &length);
1023 if (status != X400_E_NOERROR) {
1024 fprintf(stderr, "Error from CertGetStrParam: %s\n",
1025 X400msError(status));
1026 return;
1027 }
1028 fprintf(stderr, "issuer DN of originator certificate '%.*s'\n",
1029 (int)length, buffer);
1030
1032 buffer, sizeof buffer, &length);
1033 if (status != X400_E_NOERROR) {
1034 if ( status == X400_E_NO_VALUE ) {
1035 fprintf(stderr, "No ORaddress subject alt. name\n");
1036 } else {
1037 fprintf(stderr, "Error from CertGetStrParam: %s\n",
1038 X400msError(status));
1039 return;
1040 }
1041 } else {
1042 fprintf(stderr, "ORaddress subject alt name: '%.*s'\n",
1043 (int)length, buffer);
1044 }
1045
1046 status = X400CertGetIntParam(cert, X400_N_CERT_ORADDRESS_STATUS, &paramval);
1047
1048 if (status != X400_E_NOERROR) {
1049 fprintf(stderr, "Error from CertGetStrParam: %s\n",
1050 X400msError(status));
1051 return;
1052 }
1053
1054 fprintf(stderr, "ORaddress subject alt name status: %s\n",
1055 X400msError (paramval));
1056 return;
1057}
1058
1059
1060static void print_sec_label(
1061 char slab_buffer[],
1062 unsigned int length
1063)
1064{
1065
1066#define XML_BUFSIZE 1024
1067
1068 char xml_buffer[XML_BUFSIZE];
1069 int status;
1070
1071 status = SecLabelInit("Example program");
1072 if (status != SECLABEL_E_NOERROR) {
1073 fprintf(stderr, "SecLabelInit returned error %d\n", status);
1074 return ;
1075 }
1076
1077 status = SecLabelPrint((const unsigned char *) slab_buffer,
1078 length,
1079 xml_buffer,
1080 XML_BUFSIZE);
1081
1082 if (status != SECLABEL_E_NOERROR) {
1083 fprintf(stderr, "SecLabelParse returned error %d\n", status);
1084 return ;
1085 }
1086
1087 /* You could now write out the XML file, or parse it in memory..*/
1088 printf("Got security label:\n%s\n", xml_buffer);
1089 return;
1090}
1091
1092
1093static void usage(void) {
1094 printf("usage: %s\n", optstr);
1095 printf("\t where:\n");
1096 printf("\t -u : Don't prompt to override defaults \n");
1097 printf("\t -3 : Use P3 connection \n");
1098 printf("\t -7 : Use P7 connection \n");
1099 printf("\t -m : OR Address in P7 bind arg \n");
1100 printf("\t -d : DN in P7 bind arg \n");
1101 printf("\t -p : Presentation Address of P7 Store \n");
1102 printf("\t -w : P7 password of P7 user \n");
1103 printf("\t -M : OR Address in P3 bind arg \n");
1104 printf("\t -D : DN in P3 bind arg \n");
1105 printf("\t -P : Presentation Address of P3 server\n");
1106 printf("\t -W : P3 password of P3 user \n");
1107 printf("\t -e : Security Environment (dir with x509 subdir): obsolete, use -Y <p12file>\n");
1108 printf("\t -x : DN of X.509 Digital Identity\n");
1109 printf("\t -b : Passphrase for private key in PKCS12 file\n");
1110 printf("\t -Y : Filename of PKCS12 file containing Digital Identity\n");
1111 return;
1112}
#define X400_N_CERT_ORADDRESS_STATUS
Definition x400_att.h:1561
#define X400_S_CERT_ISSUER_DN
Definition x400_att.h:1555
#define X400_S_CERT_SUBJECT_DN
Definition x400_att.h:1552
#define X400_N_CERT_MOAC
Definition x400_att.h:1528
int X400RecipNew(int type, struct X400Recipient **rpp)
Create a new recipient object.
int X400CertGetStrParam(struct X400Certificate *cp, int paramtype, char *buffer, size_t buflen, size_t *paramlenp)
Return a string-valued parameter from the certificate object.
int X400RecipAddStrParam(struct X400Recipient *rp, int paramtype, const char *value, size_t length)
Add string-valued parameter to the recipient.
int X400CertGetIntParam(struct X400Certificate *cp, int paramtype, int *valp)
Return a integer-valued parameter from the certificate object.
int X400msMsgGetCert(struct X400msMessage *mp, int certtype, struct X400Certificate **certp)
Get certificate object from message This returns a certificate which was used to sign an object in th...
int X400msAutoActionParameterAddIntParam(struct X400msAutoActionParameter *aap, int paramtype, int value)
Add integer-valued parameter to the autoaction parameter.
int X400msRecipGet(struct X400msMessage *mp, int type, int number, struct X400Recipient **rpp)
Get recipient object from message.
void X400msFreeAutoActionParameter(struct X400msAutoActionParameter *aa_param)
Free an autoaction parameter.
int X400msMsgGetStrParam(struct X400msMessage *mp, int paramtype, char *buffer, size_t buflen, size_t *paramlenp)
Return a string-valued parameter from the message object.
int X400msAutoActionParameterAddRecip(struct X400msAutoActionParameter *aap, int reciptype, struct X400Recipient *recip)
Add a receipient to the autoaction parameter.
int X400msRecipGetStrParam(struct X400Recipient *rp, int paramtype, char *buffer, size_t buflen, size_t *paramlenp)
Return a string-valued parameter from the recipient object.
int X400msWait(struct X400msSession *sp, int seconds, int *count)
Wait for messages to be ready to be read.
int X400msMsgGet(struct X400msSession *sp, int number, struct X400msMessage **mpp, int *typep, int *seqp)
Get message object for transfer out from MS or MTA via P3.
const char * X400msError(int error)
Obtain a string describing the meaning of the given error code.
int X400msRegisterAutoAction(struct X400msSession *sp, int type, int id, struct X400msAutoActionParameter *aa_param)
Register an autoaction with the Message Store.
int X400msSetIntDefault(struct X400msSession *sp, int paramtype, int value)
Set a default integer parameter value in a session.
struct X400msAutoActionParameter * X400msNewAutoActionParameter(void)
Create a new (empty) autoaction parameter structure.
int X400msRecipGetIntParam(struct X400Recipient *rp, int paramtype, int *valp)
Return a integer-valued parameter from the recipient object.
int X400msMsgDelete(struct X400msMessage *mp, int retain)
Delete message object.
int X400msAutoActionParameterAddStrParam(struct X400msAutoActionParameter *aap, int paramtype, const char *value, size_t length)
Add string-valued parameter to the autoaction parameter.
int X400msDeregisterAutoAction(struct X400msSession *sp, int type, int id)
Deregister an autoaction from the Message Store.
int X400msClose(struct X400msSession *sp)
Close a X400 Session.
int X400msSetStrDefault(struct X400msSession *sp, int paramtype, const char *value, size_t length)
Set a default string parameter value in a session.
int X400msOpen(int type, const char *oraddr, const char *dirname, const char *credentials, const char *pa, int *messages, struct X400msSession **spp)
Open a session to a Message Store (P7) or MTA (P3) in synchronous mode.
int X400msMsgGetIntParam(struct X400msMessage *mp, int paramtype, int *valp)
Return a integer-valued parameter from the message object.
#define X400_S_OR_ADDRESS
Definition x400_att.h:349
#define X400_AUTO_ALERT
Definition x400_att.h:1356
#define X400_AUTO_FORWARDING
Definition x400_att.h:1359
#define X400_S_SUBJECT
Definition x400_att.h:749
#define X400_T_IA5TEXT
Definition x400_att.h:825
#define X400_N_WAIT_INTERVAL
Definition x400_att.h:1109
#define X400_B_RETURN_VERIFICATION_ERRORS
Definition x400_att.h:1123
#define X400_S_LOG_CONFIGURATION_FILE
Definition x400_att.h:1116
#define X400_N_PRIORITY
Definition x400_att.h:433
#define X400_S_MESSAGE_DELIVERY_TIME
Definition x400_att.h:451
#define X400_S_CONTENT_IDENTIFIER
Definition x400_att.h:425
#define X400_N_IMPLICIT_CONVERSION_PROHIBITED
Definition x400_att.h:439
#define X400_N_CONTENT_TYPE
Definition x400_att.h:419
#define X400_N_CONTENT_RETURN_REQUEST
Definition x400_att.h:445
#define X400_N_DISCLOSURE
Definition x400_att.h:436
#define X400_N_ALTERNATE_RECIPIENT_ALLOWED
Definition x400_att.h:442
#define X400_S_EXTERNAL_CONTENT_TYPE
Definition x400_att.h:456
#define X400_S_MESSAGE_IDENTIFIER
Definition x400_att.h:416
#define X400_S_SECURITY_LABEL
Definition x400_att.h:1370
#define X400_E_X509_CERT_INVALID
Definition x400_att.h:199
#define X400_E_X509_VERIFY_FAIL
Definition x400_att.h:196
#define X400_E_SIGN_NO_IDENTITY
Definition x400_att.h:205
#define X400_E_X509_ITEM_INVALID
Definition x400_att.h:202
#define X400_E_X509_ENV
Definition x400_att.h:175
#define X400_E_NOERROR
Definition x400_att.h:46
#define X400_E_NO_VALUE
Definition x400_att.h:100
#define X400_E_X509_VERIFY_FAIL_NO_CERT
Definition x400_att.h:184
#define X400_E_X509_VERIFY_FAIL_UNSUPPORTED_ALG
Definition x400_att.h:193
#define X400_E_X509_VERIFY_FAIL_NO_PUBKEY
Definition x400_att.h:187
#define X400_E_S4406_TRIPLE_WRAPPED
Definition x400_att.h:235
#define X400_E_X509_VERIFY_FAIL_INCOMPAT_ALG
Definition x400_att.h:190
#define X400_E_X509_INIT
Definition x400_att.h:181
#define X400_E_NO_RECIP
Definition x400_att.h:109
#define X400_S_COVER_NOTE
Definition x400_att.h:1266
#define X400_S_AUTO_FORWARDING_COMMENT
Definition x400_att.h:1262
#define X400_S_THIS_IPM_PREFIX
Definition x400_att.h:1269
#define X400_MSG_MESSAGE
Definition x400_att.h:29
#define X400_N_PRECEDENCE
Definition x400_att.h:712
#define X400_RECIP_PRIMARY
Definition x400_att.h:296
#define X400_RECIP_STANDARD
Definition x400_att.h:341
#define X400_RECIP_REPORT
Definition x400_att.h:314
#define X400_S_SUPPLEMENTARY_INFO
Definition x400_att.h:1067
#define X400_S_SUBJECT_IDENTIFIER
Definition x400_att.h:1064
#define X400_N_NON_DELIVERY_REASON
Definition x400_att.h:1076
#define X400_N_NON_DELIVERY_DIAGNOSTIC
Definition x400_att.h:1079
#define X400_N_S4406_STATUS
Definition x400_att.h:635
#define X400_N_S4406_CERTIFICATE
Definition x400_att.h:651
#define X400_N_MOAC_STATUS
Definition x400_att.h:594
#define X400_S_SEC_IDENTITY_DN
Definition x400_att.h:572
#define X400_S_SEC_TRUSTED_CERTS_DIR
Definition x400_att.h:603
#define X400_S_S4406_SIGNING_TIME
Definition x400_att.h:656
#define X400_S_SEC_IDENTITY
Definition x400_att.h:563
#define X400_S_S4406_SECURITY_LABEL
Definition x400_att.h:646
#define X400_S_SEC_IDENTITY_PASSPHRASE
Definition x400_att.h:569
X400 MA/MS (P3/P7) Interface.

All rights reserved © 2002 - 2024 Isode Ltd.