x400_msrcv_msg_tok_sign.c
1 /* Copyright (c) 2009-2024, 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  *
15  * Simple example program for receiving a message from a store.
16  * The security environment is set up so that signed messages
17  * will have per message MOAC signatures and recipient Message Token
18  * signatures verified.
19  *
20  * Note that a valid Digital Identity is no longer required in order to
21  * perform verification. Instead the name of a directory containing trusted,
22  * self signed certificates in DER form can be passed in.
23  */
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <x400_msapi.h>
28 #include "example.h"
29 #include "ms_example.h"
30 #include <seclabel_api.h> /* For security labels */
31 #include <isode/base/compat.h>
32 
33 #define XML_BUFSIZE 1024
34 
35 int num_unsigned_rcvd;
36 int num_unverified_rcvd;
37 int num_verified_rcvd;
38 int num_messages_rcvd ;
39 int num_reports_rcvd ;
40 int num_ipns_rcvd ;
41 
42 static char *optstr = "u37m:d:p:w:M:D:P:W:e:b:x:EY:U:I";
43 
44 static void usage(void);
45 
46 
47 static int get_msg(
48  struct X400msSession *sp
49 );
50 
51 static void setup_default_new_sec_env(
52  struct X400msSession *sp,
53  char *sec_trusted_cert_dir
54 );
55 
56 static void setup_default_old_sec_env(
57  struct X400msSession *sp,
58  char *id,
59  char *dn,
60  char *pw /* passphrase for private key in pkcs12 file */
61 );
62 
63 static void report_msg_token_info(
64  struct X400Recipient *rp
65 );
66 
67 static int get_sec_label(
68  struct X400msMessage *mp
69 );
70 
71 static void print_sec_label(
72  unsigned char slab_buffer[],
73  unsigned int length
74 );
75 
76 static int get_cic(
77  struct X400Recipient *rp
78 );
79 
80 static int get_4406_info(
81  struct X400msMessage *mp
82 );
83 
84 static void show_recip_certificate (
85  struct X400Recipient *rp,
86  int certtype,
87  const char *tag);
88 
89 static void show_message_certificate (
90  struct X400msMessage *mp,
91  const char *tag);
92 
93 static void show_certificate (
94  struct X400Certificate *cert,
95  const char *tag);
96 
97 static int handle_ipn(
98  struct X400msMessage *mp
99 );
100 
101 static int handle_msg(
102  struct X400msSession *sp,
103  struct X400msMessage *mp
104 );
105 
106 static int send_ipn(
107  struct X400msSession *sp,
108  struct X400msMessage *mp,
109  struct X400msMessage **ipn
110 );
111 
112 static int do_report(
113  struct X400msSession *sp,
114  struct X400msMessage *mp
115 );
116 
120 int
121 main(
122  int argc,
123  char **argv)
124 {
125  char buffer[BUFSIZ];
126  char pa[BUFSIZ];
127  char orn[BUFSIZ];
128  int status;
129  int nummsg;
130  struct X400msSession *sp;
131  int contype;
132  char *def_oraddr;
133  char *def_dn;
134  char *def_pa;
135 
136  if (get_args(argc, argv, optstr)) {
137  usage();
138  exit(-1);
139  }
140 
141  printf("Connection type (0 = P7, 1 = P3 submit only, 2 = P3 both directions) [%d]: ", x400_contype);
142  contype = ic_fgetc(x400_contype, stdin);
143  if (contype != 10)
144  ic_fgetc(x400_contype, stdin);
145 
146  if ( contype < '0' || '2' < contype )
147  contype = x400_contype;
148  else
149  contype -= '0';
150 
151  if (contype == 0) {
152  def_oraddr = x400_ms_user_addr;
153  def_dn = x400_ms_user_dn;
154  def_pa = x400_ms_presentation_address;
155  }
156  else {
157  def_oraddr = x400_mta_user_addr;
158  def_dn = x400_mta_user_dn;
159  def_pa = x400_mta_presentation_address;
160  }
161 
162  printf("Your ORAddress [%s] > ", def_oraddr);
163  ic_fgets(orn, sizeof orn, stdin);
164 
165  if (orn[strlen(orn) - 1] == '\n')
166  orn[strlen(orn) - 1] = '\0';
167 
168  if (orn[0] == '\0')
169  strcpy(orn, def_oraddr);
170 
171  /* Prompt for password; note: reflected. */
172  printf("Password [%s]: ",
173  contype == 0 ? x400_p7_password : x400_p3_password);
174  if (ic_fgets(buffer, sizeof buffer, stdin) == NULL)
175  exit(1);
176 
177  if (buffer[strlen(buffer) - 1] == '\n')
178  buffer[strlen(buffer) - 1] = '\0';
179  if (buffer[0] == '\0')
180  strcpy(buffer, contype == 0 ? x400_p7_password : x400_p3_password);
181 
182  printf("Presentation Address [%s] > ", def_pa);
183  ic_fgets(pa, sizeof pa, stdin);
184 
185  if (pa[strlen(pa) - 1] == '\n')
186  pa[strlen(pa) - 1] = '\0';
187 
188  if (pa[0] == '\0')
189  strcpy(pa, def_pa);
190 
191  status = X400msOpen(contype, orn, def_dn, buffer, pa, &nummsg, &sp);
192  if (status != X400_E_NOERROR) {
193  fprintf(stderr, "Error in Open: %s\n", X400msError(status));
194  exit(status);
195  }
196 
197  /* setup logging from $(ETCDIR)x400api.xml or $(SHAREDIR)x400api.xml */
198  X400msSetStrDefault(sp, X400_S_LOG_CONFIGURATION_FILE, "x400api.xml", 0);
199 
200  if (nummsg == 0) {
201  printf ("no messages - waiting for a message to be delivered.....\n");
202  }
203  else {
204  printf("%d messages waiting\n", nummsg);
205  }
206 
207  status = get_msg(sp);
208  if (status != X400_E_NOERROR) {
209  fprintf(stderr, "Error in getting msg: %s\n",
210  X400msError(status));
211  exit(status);
212  }
213  fprintf(stderr, "got first\n");
214 
215  do {
216  fprintf(stderr, "================================================\n");
217  status = get_msg(sp);
218  if (status != X400_E_NOERROR) {
219  fprintf(stderr, "Error in getting msg: %s\n",
220  X400msError(status));
221  exit(status);
222  }
223  } while (until_no_more_msgs);
224 
225  status = X400msClose(sp);
226  printf("%d num_messages_rcvd\n", num_messages_rcvd);
227  printf("%d num_reports_rcvd\n", num_reports_rcvd);
228  printf("%d num_unsigned_rcvd\n", num_unsigned_rcvd);
229  printf("%d num_unverified_rcvd\n", num_unverified_rcvd);
230  printf("%d num_verified_rcvd\n", num_verified_rcvd);
231  printf("%d num_ipns_rcvd\n", num_ipns_rcvd);
232  return(status);
233 }
234 
235 
236 static int get_msg(
237  struct X400msSession *sp
238 )
239 {
240  int status;
241  int nummsg;
242  int type;
243  int seqn;
244  struct X400msMessage *mp;
245  int intparam;
246 
247  printf("Waiting for new messages for 10 seconds\n");
248  status = X400msWait(sp, 10, &nummsg);
249  if (status != X400_E_NOERROR) {
250  fprintf(stderr, "Error from Wait: %s\n", X400msError(status));
251  /* tidily close the session */
252  status = X400msClose(sp);
253  printf("%d num_messagese_rcvd\n", num_messages_rcvd);
254  printf("%d num_reports_rcvd\n", num_reports_rcvd);
255  printf("%d num_unsigned_rcvd\n", num_unsigned_rcvd);
256  printf("%d num_unverified_rcvd\n", num_unverified_rcvd);
257  printf("%d num_verified_rcvd\n", num_verified_rcvd);
258  exit(status);
259  }
260 
261  /* Set up the security environment.
262  *
263  * In R15.0 this need only be the name of a trusted certificate directory.
264  *
265  * Prior to R15.0, the ID is specified as a pathname, in which the
266  * subdirectory "x509" is expected to contain one or more PKCS12
267  * files. The appropriate Digital Identity is determined from the
268  * DN of the subject, and the passphrase is used to decrypt the
269  * private key. NB even though we're not going to use our cert,
270  * (as we're going to use the cert in the message to check the MOAC
271  * we need to do this due to a limitation in the underlying X.509
272  * layer.
273  */
274  if (use_new_sec_env) {
275  setup_default_new_sec_env(sp, trusted_ca_certs_dir);
276  } else {
277  setup_default_old_sec_env(sp, security_id, identity_dn, passphrase);
278  }
279 
280  /* Turn off legacy bahaviour in which MOAC verification failure
281  * returns X400_E_NOERROR.
282  * We will now get X400_E_X509_VERIFY_FAILURE from MsgGet
283  * if/when the verification fails
284  */
286 
287  printf("Getting message\n");
288 
289  status = X400msMsgGet(sp, 0, &mp, &type, &seqn);
290  switch (status) {
291  case X400_E_NOERROR:
292  fprintf(stderr, "MsgGet successfully got message\n");
293  break;
294  default :
295  fprintf(stderr, "Error from MsgGet: %s\n", X400msError(status));
296  /* tidily close the session */
297  status = X400msClose(sp);
298  exit(status);
299  break;
300  }
301 
302  if (type != X400_MSG_MESSAGE) {
303  /**********************************/
304  /* Report on the received Report */
305  /**********************************/
306  status = do_report(sp, mp);
307  return (status);
308  }
309 
310  /**********************************/
311  /* Report on the received Message */
312  /**********************************/
313 
314  status = X400msMsgGetIntParam(mp, X400_N_IS_IPN, &intparam);
315  if (status != X400_E_NOERROR) {
316  fprintf(stderr, "Error from MsgGetIntParam (X400_N_IS_IPN): %s\n",
317  X400msError(status));
318  } else {
319  printf("Type of Message: %d\n", intparam);
320  if (intparam != 0) {
321  /**********************************/
322  /* Report on the received IPN */
323  /**********************************/
324  printf("Received an IPN\n");
325  num_ipns_rcvd++;
326  handle_ipn(mp);
327  status = X400msMsgDelete(mp, 0);
328  return status;
329  }
330  }
331  /* we have received a message */
332  num_messages_rcvd++ ;
333  status = handle_msg(sp, mp);
334  if (status != X400_E_NOERROR) {
335  fprintf(stderr, "Error from handle_msg: %s\n",
336  X400msError(status));
337  return status;
338  }
339  if (gen_ipn) {
340  struct X400msMessage *ipn;
341  status = send_ipn(sp, mp, &ipn);
342  if (status != X400_E_NOERROR) {
343  fprintf(stderr, "Error from send_ipn: %s\n",
344  X400msError(status));
345  }
346  /* Deletes message in message store as well as internal copy */
347  status = X400msMsgDelete(mp, 0);
348  if (status != X400_E_NOERROR) {
349  fprintf(stderr, "Error from X400msMsgDelete (subject message)%s\n",
350  X400msError(status));
351  }
352 
353  status = X400msMsgDelete(ipn, 0);
354  if (status != X400_E_NOERROR) {
355  fprintf(stderr, "Error from X400msMsgDelete (IPN)%s\n",
356  X400msError(status));
357  }
358  return status;
359  } else {
360  /* Deletes message in message store as well as internal copy */
361  status = X400msMsgDelete(mp, 0);
362  if (status != X400_E_NOERROR) {
363  fprintf(stderr, "Error from X400msMsgDelete (IPN)%s\n",
364  X400msError(status));
365  }
366  return status;
367  }
368  return X400_E_NOERROR;
369 }
370 
371 static int do_report(
372  struct X400msSession *sp,
373  struct X400msMessage *mp
374 )
375 {
376  char buffer[BUFSIZ];
377  size_t length;
378  int intparam;
379  char recipient_str[BUFSIZ];
380  int status;
381  int n;
382  struct X400Recipient *rp;
383 
384  /**********************************/
385  /* Report on the received Report */
386  /**********************************/
387  num_reports_rcvd++ ;
388  fprintf(stderr, "Got a report (printing only some attributes)\n");
389 
390  /* Get the Message Identifier of the Subject message */
392  buffer, sizeof buffer, &length);
393  if (status != X400_E_NOERROR) {
394  fprintf(stderr, "Error from MsgGetStrParam: %s\n",
395  X400msError(status));
396  /* tidily close the session */
397  status = X400msClose(sp);
398  exit(status);
399  }
400  printf("Subject Identifier: %.*s\n", (int)length, buffer);
401 
402  /* Get the primary recipients */
403  for (n = 1;; n++) {
404  status = X400msRecipGet(mp, X400_RECIP_REPORT, n, &rp);
405  if (status == X400_E_NO_RECIP)
406  break;
407  if (status != X400_E_NOERROR) {
408  fprintf(stderr, "Error from RecipGet: %s\n",
409  X400msError(status));
410  /* tidily close the session */
411  status = X400msClose(sp);
412  exit(status);
413  }
414 
415  /* Note: recipient may not actually have an O/R address */
417  recipient_str,
418  sizeof recipient_str, &length);
419  if (status != X400_E_NOERROR) {
420  fprintf(stderr, "Error from RecipGetStrParam: %s\n",
421  X400msError(status));
422  /* tidily close the session */
423  status = X400msClose(sp);
424  exit(status);
425  }
426  /* print out the O/R Address of the report */
427  printf("Delivery Report for recipient %d: %.*s\n", n,
428  (int)length, recipient_str);
429 
430  /* The original message delivery time, if this attribute exists,
431  * then the report is a positive Delivery Report */
433  buffer, sizeof buffer, &length);
434 
435  if (status == X400_E_NOERROR) {
436  /* Positive Delivery Report */
437  printf("Delivery Time: %.*s\n", (int)length, buffer);
438  }
439  else {
440  /* Negative Delivery Report */
441  printf("Negative Delivery Report for recipient %d: %.*s\n", n,
442  (int)length, recipient_str);
443 
444  /* Supplementary Info to the report */
446  buffer, sizeof buffer,
447  &length);
448  if (status != X400_E_NOERROR) {
449  fprintf(stderr, "Error from RecipGetStrParam: %s\n",
450  X400msError(status));
451  buffer[0] = '\0';
452  }
453  printf("Supplementary Info: %.*s\n", (int)length, buffer);
454 
455  /* The reason why the message was not delivered */
456  status =
458  &intparam);
459  if (status != X400_E_NOERROR) {
460  fprintf(stderr, "Error from RecipGetIntParam: %s\n",
461  X400msError(status));
462  }
463  printf("Non-Delivery Reason: %d\n", intparam);
464 
465  /* The diagnostics of the report for this recipient */
466  status =
468  &intparam);
469  if (status != X400_E_NOERROR) {
470  fprintf(stderr, "Error from RecipGetIntParam: %s\n",
471  X400msError(status));
472  }
473  printf("Non-Delivery Diagnostic: %d\n", intparam);
474  }
475  }
476 
477  status = X400msMsgDelete(mp, 0);
478  if (status != X400_E_NOERROR) {
479  fprintf(stderr, "Error from X400msMsgDelete: %s\n",
480  X400msError(status));
481  }
482  return status;
483 }
484 
485 static int handle_ipn(
486  struct X400msMessage *mp
487 )
488 {
489  struct X400Recipient *rp;
490  int status;
491  char buffer[BUFSIZ];
492  size_t length;
493  int intparam;
494 
495 
496  /* The X400_S_OR_ADDRESS in the message is the IPN originator */
497  /* not clear why X400_ORIGINATOR doesn;t work */
499  buffer, sizeof buffer, &length);
500  if (status != X400_E_NOERROR) {
501  fprintf(stderr, "Error from MsgGetStrParam (X400_S_OR_ADDRESS): %s\n",
502  X400msError(status));
503  } else {
504  printf("IPN Originator: %.*s\n", (int)length, buffer);
505  }
506 
507  /* Obtain the envelope recipient address */
508  status = X400msRecipGet (mp, X400_RECIP_ENVELOPE, 1, &rp);
509  if ( status != X400_E_NOERROR ) {
510  fprintf(stderr, "Error from X400msRecipGet (X400_RECIP_ENVELOPE): %s\n",
511  X400msError(status));
512  } else {
514  buffer, sizeof buffer, &length);
515  if ( status != X400_E_NOERROR ) {
516  fprintf(stderr, "Error from X400RecipGetStrParam (X400_S_OR_ADDRESS): %s\n",
517  X400msError(status));
518  } else {
519 
520  buffer[length] = '\0';
521  printf("IPN Recipient: %.*s\n", (int)length, buffer);
522  }
523  }
524 
525 
526  /* The subject message identifier */
528  buffer, sizeof buffer, &length);
529  if (status != X400_E_NOERROR) {
530  fprintf(stderr, "Error from MsgGetStrParam (X400_S_SUBJECT_IPM): %s\n",
531  X400msError(status));
532  } else {
533  printf("Subject Message Identifier: %.*s\n", (int)length, buffer);
534  }
535 
536  /* The conversion EITs */
538  buffer, sizeof buffer, &length);
539  if (status != X400_E_NOERROR) {
540  fprintf(stderr, "Error from MsgGetStrParam (X400_S_CONVERSION_EITS): %s\n", X400msError(status));
541  } else {
542  printf("conversion EITs: %.*s\n", (int)length, buffer);
543  }
544 
545  /* non-receipt reason */
547  &intparam);
548  if (status == X400_E_NOERROR) {
549  printf(" non-receipt reason: %d\n", intparam);
550  } else {
551  fprintf(stderr, "Error getting non-receipt reason: %s\n",
552  X400msError(status));
553  }
554 
555  /* discard reason */
557  &intparam);
558  if (status == X400_E_NOERROR) {
559  printf("discard reason: %d\n", intparam);
560  } else {
561  fprintf(stderr, "Error getting discard reason: %s\n",
562  X400msError(status));
563  }
564 
565  /* Autoforward comment */
567  buffer, sizeof buffer, &length);
568  if (status != X400_E_NOERROR) {
569  fprintf(stderr, "Error from MsgGetStrParam (X400_S_AUTOFORWARD_COMMENT): %s\n",
570  X400msError(status));
571  } else {
572  printf("autoforward comment: %.*s\n", (int)length, buffer);
573  }
574 
575  /* Time of receipt: UTCTime format */
577  buffer, sizeof buffer, &length);
578  if (status != X400_E_NOERROR) {
579  fprintf(stderr, "Error from MsgGetStrParam(X400_S_RECEIPT_TIME): %s\n",
580  X400msError(status));
581  } else {
582  printf(" Time of receipt: (UTCTime format): %.*s\n", (int)length, buffer);
583  }
584 
585  /* Acknowledgement mode: 0 - manual; 1 -automatic */
587  &intparam);
588  if (status == X400_E_NOERROR) {
589  printf(" Acknowledgement mode: (0 - manual; 1 -automatic): %d\n",
590  intparam);
591  } else {
592  fprintf(stderr, "Error getting Acknowledgement mode: %s\n",
593  X400msError(status));
594  }
595 
596  /* Supplementary information associated with IPN */
598  buffer, sizeof buffer, &length);
599  if (status != X400_E_NOERROR) {
600  fprintf(stderr, "Error from MsgGetStrParam (X400_S_SUPP_RECEIPT_INFO): %s\n",
601  X400msError(status));
602  /* tidily close the session */
603  /* status = X400msClose(sp);
604  exit(status);
605  */
606  } else {
607  printf(" Supplementary information: %.*s\n", (int)length, buffer);
608  }
609  status = X400msMsgGetIntParam(mp, X400_N_CONTENT_TYPE, &intparam);
610  if (status != X400_E_NOERROR) {
611  fprintf(stderr,
612  "Error from MsgGetIntParam (X400_N_CONTENT_TYPE,): %s\n",
613  X400msError(status));
614  } else {
615  printf("Content Type: %d\n", intparam);
616  }
617 
618 
619 
620  return X400_E_NOERROR;
621 }
622 
623 
624 static int handle_msg(
625  struct X400msSession *sp,
626  struct X400msMessage *mp
627 )
628 {
629  int status;
630  int intparam;
631  size_t length;
632  char buffer[BUFSIZ];
633  struct X400Recipient *rp;
634  int n;
635 
636  /* Size */
637  status =
639  &intparam);
640  if (status != X400_E_NOERROR) {
641  fprintf(stderr, "Error from MsgGetIntParam: %s\n",
642  X400msError(status));
643  }
644  printf("Size of Message: %d\n", intparam);
645 
646  /* content type */
647  status = X400msMsgGetIntParam(mp, X400_N_CONTENT_TYPE, &intparam);
648  if (status != X400_E_NOERROR) {
649  fprintf(stderr,
650  "Error from MsgGetIntParam (X400_N_CONTENT_TYPE,): %s\n",
651  X400msError(status));
652  } else {
653  printf("Content Type: %d\n", intparam);
654  }
655 
656  /* The external content type */
658  buffer, sizeof buffer, &length);
659  if (status != X400_E_NOERROR) {
660  fprintf(stderr, "Error from MsgGetStrParam (X400_S_EXTERNAL_CONTENT_TYPE): %s\n",
661  X400msError(status));
662  } else {
663  printf("External Content Type: %.*s\n", (int)length, buffer);
664  }
665 
666  /* The message identifier */
668  buffer, sizeof buffer, &length);
669  if (status != X400_E_NOERROR) {
670  fprintf(stderr, "Error from MsgGetStrParam: %s\n",
671  X400msError(status));
672  /* tidily close the session */
673  status = X400msClose(sp);
674  exit(status);
675  }
676  printf("Message Identifier: %.*s\n", (int)length, buffer);
677 
678  /* display any PCT info available */
679  get_4406_info(mp);
680 
681  /* The ORADDRESS in the message is the (envelope) originator */
683  buffer, sizeof buffer, &length);
684  if (status != X400_E_NOERROR) {
685  fprintf(stderr, "Error from MsgGetStrParam: %s\n",
686  X400msError(status));
687  /* tidily close the session */
688  status = X400msClose(sp);
689  exit(status);
690  }
691  printf("Originator: %.*s\n", (int)length, buffer);
692 
693  /* Get the envelope recipients */
694  for (n = 1;; n++) {
695  status = X400msRecipGet(mp, X400_RECIP_ENVELOPE, n, &rp);
696  if (status == X400_E_NO_RECIP)
697  break;
698  if (status != X400_E_NOERROR) {
699  fprintf(stderr, "Error from RecipGet (envelope): %s\n",
700  X400msError(status));
701  /* tidily close the session */
702  status = X400msClose(sp);
703  exit(status);
704  }
705 
706  /* Note: recipient may not actually have an O/R address */
708  buffer, sizeof buffer, &length);
709  if (status == X400_E_NOERROR) {
710  printf("Env Recipient %d: %.*s\n", n, (int)length, buffer);
711  }
712 
713  /* get back status of the Proof Of Del Request in the recipient */
715  &intparam);
716  if (status == X400_E_NOERROR) {
717  printf("Recipient proof of delivery request is %d\n", intparam);
718  } else {
719  fprintf(stderr, "Error getting proof of delivery request: %s\n",
720  X400msError(status));
721  }
722 
723  /* report content integrity check info if available */
724  get_cic(rp);
725 
726  /* return MessageToken info if available */
727  report_msg_token_info(rp);
728 
729  /* get and display the seccurity label if available */
730  get_sec_label(mp);
731  }
732 
733  /* Get the primary recipients */
734  for (n = 1;; n++) {
735  status = X400msRecipGet(mp, X400_RECIP_PRIMARY, n, &rp);
736  if (status == X400_E_NO_RECIP)
737  break;
738  if (status != X400_E_NOERROR) {
739  fprintf(stderr, "Error from RecipGet (primary): %s\n", X400msError(status));
740  /* This is allowed, so continue reading the message */
741  break;
742  }
743 
744  /* Note: recipient may not actually have an O/R address */
746  buffer, sizeof buffer, &length);
747  if (status == X400_E_NOERROR) {
748  printf("Primary Recipient %d: %.*s\n", n, (int)length, buffer);
749  }
750 
751  status = X400msRecipGetIntParam(rp, X400_N_PRECEDENCE, &intparam);
752  if (status == X400_E_NOERROR) {
753  printf("Primary Recipient Precedence %d\n", intparam);
754  } else {
755  fprintf(stderr, "Error getting Primary Recipient Precedence : %s\n", X400msError(status));
756  }
757 
758  }
759 
760  /* Subject is optional */
762  buffer, sizeof buffer, &length);
763  if (status == X400_E_NOERROR)
764  printf("Subject: %.*s\n", (int)length, buffer);
765 
766  /* And message text (or it could be another type) */
768  buffer, sizeof buffer, &length);
769  if (status == X400_E_NOERROR)
770  printf("Text:\n%.*s\n", (int)length, buffer);
771  else
772  printf("No IA5 Text content (%d: %s)\n", status, X400msError(status));
773 
774  /* get all the attachments */
775  printf("Getting body parts\n");
776  get_body_parts(mp);
777 
778  return X400_E_NOERROR;
779 }
780 
781 
782 static int send_ipn(
783  struct X400msSession *sp,
784  struct X400msMessage *mp,
785  struct X400msMessage **ipn
786 )
787 {
788  int status;
789  status = X400msMsgNew (sp, X400_MSG_MESSAGE, ipn);
790  if ( status != X400_E_NOERROR ) {
791  fprintf (stderr, "x400msMsgNew returned error: %s\n",
792  X400msError (status));
793  return (status);
794  }
795 
796  status = X400msMakeIPN(mp, -1, ipn);
797  if (status != X400_E_NOERROR) {
798  fprintf(stderr, "Error from X400msMakeIPN: %s\n",
799  X400msError(status));
800  return status;
801  }
802 
803  /* submit */
804  status = X400msMsgSend (*ipn);
805  if ( status != X400_E_NOERROR ) {
806  fprintf (stderr, "x400msMsgSend returned error: %s\n",
807  X400msError (status));
808  return (status);
809  } else {
810  printf("IPN submitted successfully\n");
811  }
812 
813  return status;
814 }
815 /*
816  * Recommended function to setup security env for verification.
817  * No digitial ID required - just a directory which contains
818  * trust anchors which are read as DER file (certificate.crt).
819  *
820  * The certificate (containing public key) is obtained from the message
821  * which is referenced in the message.
822  */
823 
824 static void setup_default_new_sec_env(
825  struct X400msSession *sp,
826  char *local_trusted_ca_certs_dir
827 )
828 {
829  int status;
830 
831  /* Directory containing trusted CA Certificates */
832  printf(" Adding %s as trusted CA cert dir\n", trusted_ca_certs_dir);
834  local_trusted_ca_certs_dir, -1);
835  if ( status != X400_E_NOERROR ) {
836  fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
837  X400msError (status));
838  exit (status);
839  }
840 
841  return;
842 }
843 
844 /*
845  * Obsolete function to use to set up the security environment. This provides a
846  * directory in which PKCS12 files are checked to find one whose subject DN
847  * matches that of this client.
848  *
849  * Any self signed certificates found in the directory are treated as
850  * trusted.
851  */
852 
853 static void setup_default_old_sec_env(
854  struct X400msSession *sp,
855  char *id,
856  char *dn,
857  char *pw /* passphrase for private key in pkcs12 file */
858 )
859 {
860  int status;
861 
862  /* first set a default security identity. This passes in the name of a
863  * directory, which contains an x509 subdirectory in which all Identities
864  * are held */
865  /* X400msSetStrDefault(sp, X400_S_SEC_IDENTITY, "/var/isode/dsa-db/", -1);
866  * */
868 
869  /* select by DN which Identity is to be used (if there are several)
870  * Currently these must be PKCS12 files */
871  status = X400msSetStrDefault (sp, X400_S_SEC_IDENTITY_DN, dn, -1);
872  if ( status != X400_E_NOERROR ) {
873  fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
874  X400msError (status));
875  exit (status);
876  }
877 
878  /* passphrase used to open the Identity */
880  if ( status != X400_E_NOERROR ) {
881  fprintf (stderr, "X400msSetStrDefault returned error: %s\n",
882  X400msError (status));
883  exit (status);
884  }
885  return;
886 }
887 
888 static void report_msg_token_info(
889  struct X400Recipient *rp
890 )
891 {
892  char buffer[BUFSIZ];
893  int status;
894  int param;
895  size_t length;
896 
897  status = X400msRecipGetIntParam(rp,
898  X400_N_MSGTOK_STATUS, &param);
899  if (status == X400_E_NO_VALUE) {
900  fprintf(stderr, "No MessageToken present in recipient\n");
901  /* no further information available */
902  return ;
903  } else if (status != X400_E_NOERROR) {
904  fprintf(stderr, "Error from RecipGetIntParam: %s (%d)\n",
905  X400msError(status),
907  fprintf(stderr, "Message Token status not available\n");
908  } else {
909  fprintf(stderr,
910  "Message Token status %d \n", param);
911  }
912 
913  switch (param) {
914  case X400_E_NOERROR:
915  fprintf(stderr, "Token OK (%d)\n", param);
916  break;
917  case X400_E_X509_ENV:
918  case X400_E_X509_INIT:
919  fprintf(stderr,
920  "Message Token validation cannot take place because the security environment is invalid (%d):\n",
921  param);
922  /* other values will not be available */
923  return ;
931  fprintf(stderr,
932  "Message Token validation failed (%d): %s\n",
933  param, X400msError(param));
934  break;
935  default:
936  fprintf(stderr,
937  "Unexpected Message Token validation result (%d): %s\n",
938  param, X400msError(param));
939  break;
940 
941  }
942 
943  //show_certificate (rp, X400_N_CERT_MSGTOK, "message-token");
944  show_recip_certificate (rp, X400_N_CERT_MSGTOK, "message-token");
945 
946  status = X400msRecipGetStrParam(rp,
948  buffer, sizeof buffer, &length);
949  if (status != X400_E_NOERROR) {
950  fprintf(stderr, "Error from RecipGetStrParam: %s\n",
951  X400msError(status));
952 
953  fprintf(stderr, "recipient in token not available\n");
954  } else {
955  fprintf(stderr,
956  "Message Token(%u): recipient in Token '%.*s'\n",
957  (unsigned)length, (int)length, buffer);
958  }
959 
960  status = X400msRecipGetStrParam(rp,
962  buffer, sizeof buffer, &length);
963  if (status != X400_E_NOERROR) {
964  fprintf(stderr, "Error from RecipGetStrParam: %s (%d)\n",
965  X400msError(status),
967  fprintf(stderr, "Message Token DER not available\n");
968  } else {
969  fprintf(stderr,
970  "Message Token DER available (%u bytes)\n", (unsigned)length);
971  }
972 
973  status = X400msRecipGetIntParam(rp,
974  X400_N_MSGTOK_SEQ_NUM, &param);
975  if (status != X400_E_NOERROR) {
976  fprintf(stderr, "Error from RecipGetStrParam: %s (%d)\n",
977  X400msError(status),
979  fprintf(stderr, "Message Token seq num not available\n");
980  } else {
981  fprintf(stderr,
982  "Message Token seq num %d \n", param);
983  }
984 
985  status = X400msRecipGetStrParam(rp,
987  buffer, sizeof buffer, &length);
988  if (status != X400_E_NOERROR) {
989  fprintf(stderr, "Error from RecipGetStrParam: %s (%d)\n",
990  X400msError(status),
992  fprintf(stderr, "Message Token Security Label DER not available\n");
993  } else {
994  fprintf(stderr,
995  "Message Token Security Label DER available (%u bytes)\n", (unsigned)length);
996  fprintf(stderr, "Security Label from Message Token is:\n");
997  print_sec_label((unsigned char *)buffer, length);
998  }
999 
1000  /* get back status of the Content Integrity Check in the message token */
1002  &param);
1003  if (status == X400_E_NO_VALUE) {
1004  printf("No Content Integrity Check in token\n");
1005  } else if (status != X400_E_NOERROR) {
1006  printf("Error from RecipGetIntParam: %s\n", X400msError(status));
1007 
1008  } else {
1009 
1010  /* report CIC information */
1011  switch (param) {
1012  case X400_E_NOERROR:
1013  printf("Content Integrity Check in token succeeded\n");
1014  break;
1015  default:
1016  printf("Content Integrity Check in token error (%d): %s\n",
1017  param, X400msError(param));
1018  break;
1019  }
1020 
1021  status = X400msRecipGetStrParam(rp,
1023  buffer, sizeof buffer, &length);
1024  if (status != X400_E_NOERROR) {
1025  fprintf(stderr, "Error from RecipGetStrParam: %s (%d)\n",
1026  X400msError(status),
1028  fprintf(stderr, "Message Token Content Integrity Check DER not available\n");
1029  } else {
1030  fprintf(stderr,
1031  "Message Token Content Integrity Check DER available (%u bytes)\n",
1032  (unsigned)length);
1033  }
1034 
1035  //show_certificate (rp, X400_N_CERT_MSGTOK_CIC, "token CIC");
1036  show_recip_certificate (rp, X400_N_CERT_MSGTOK_CIC, "token CIC");
1037  }
1038 
1039  status = X400msRecipGetIntParam(rp,
1040  X400_N_MSGTOK_PODR_STATUS, &param);
1041  if (status != X400_E_NOERROR) {
1042  fprintf(stderr, "Error from RecipGetStrParam: %s (%d)\n",
1043  X400msError(status),
1045  fprintf(stderr, "Message Token proof of delivery status not available\n");
1046  } else {
1047  fprintf(stderr,
1048  "Message Token proof of delivery status %d \n", param);
1049  }
1050 
1051  status = X400msRecipGetIntParam(rp,
1053  if (status != X400_E_NOERROR) {
1054  fprintf(stderr, "Error from RecipGetStrParam: %s (%d)\n",
1055  X400msError(status),
1057  fprintf(stderr, "Message Token security label status not available\n");
1058  } else {
1059  fprintf(stderr,
1060  "Message Token security label status %d \n", param);
1061  }
1062 
1063  status = X400msRecipGetIntParam(rp,
1064  X400_N_MSGTOK_RECIP_STATUS, &param);
1065  if (status != X400_E_NOERROR) {
1066  fprintf(stderr, "Error from RecipGetStrParam: %s (%d)\n",
1067  X400msError(status),
1069  fprintf(stderr, "Message Token recip status not available\n");
1070  } else {
1071  fprintf(stderr,
1072  "Message Token recip status %d \n", param);
1073  }
1074 
1075 
1076  return;
1077 }
1078 
1079 
1080 static int get_sec_label(
1081  struct X400msMessage *mp
1082 )
1083 {
1084  unsigned char slab_buffer[XML_BUFSIZE];
1085  int status;
1086  size_t length;
1087 
1088  status = X400msMsgGetStrParam(mp,
1090  (char*)slab_buffer,
1091  XML_BUFSIZE,
1092  &length);
1093  if (status == X400_E_NO_VALUE) {
1094  printf("No security label\n");
1095  } else if (status != X400_E_NOERROR) {
1096  fprintf(stderr,"Failed to fetch security label: %d",status);
1097  return (status);
1098  } else {
1099  fprintf(stderr, "Security Label from envelope is:\n");
1100  print_sec_label(slab_buffer, length);
1101  }
1102  return X400_E_NOERROR;
1103 }
1104 
1105 static void print_sec_label(
1106  unsigned char slab_buffer[],
1107  unsigned int length
1108 )
1109 {
1110 
1111  char xml_buffer[XML_BUFSIZE];
1112  int status;
1113 
1114  status = SecLabelInit("Example program");
1115  if (status != SECLABEL_E_NOERROR) {
1116  fprintf(stderr, "SecLabelInit returned error %d\n", status);
1117  return ;
1118  }
1119 
1120  status = SecLabelPrint(slab_buffer,
1121  length,
1122  xml_buffer,
1123  XML_BUFSIZE);
1124 
1125  if (status != SECLABEL_E_NOERROR) {
1126  fprintf(stderr, "SecLabelParse returned error %d\n", status);
1127  return ;
1128  }
1129 
1130  /* You could now write out the XML file, or parse it in memory..*/
1131  printf("Got security label:%s\n", xml_buffer);
1132  return;
1133 }
1134 
1135 static int get_cic(
1136  struct X400Recipient *rp
1137 )
1138 {
1139  char buffer[BUFSIZ];
1140  int status, cic_status;
1141  int intparam;
1142  size_t length;
1143 
1144  /* get back status of the Content Integrity Check in the recipient */
1146  &intparam);
1147  if (cic_status == X400_E_NO_VALUE) {
1148  printf("No Content Integrity Check in recipient\n");
1149  return X400_E_NOERROR;
1150  } else if (cic_status != X400_E_NOERROR) {
1151  printf("Error from RecipGetIntParam: %s\n", X400msError(cic_status));
1152  return cic_status;
1153  }
1154 
1155  /* report CIC information */
1156  switch (intparam) {
1157  case X400_E_NOERROR:
1158  printf("Content Integrity Check succeeded\n");
1159  break;
1160  default:
1161  printf("Content Integrity Check error (%d): %s\n",
1162  intparam, X400msError(intparam));
1163  break;
1164  }
1165 
1166  /* Return the Content Integrity Check */
1168  buffer, sizeof buffer, &length);
1169  if (status != X400_E_NOERROR) {
1170  fprintf(stderr, "Error getting recipient cic: %s\n",
1171  X400msError(status));
1172  } else {
1173  printf("Content Integrity Check found in recipient (%d)\n",
1174  (int)length);
1175  }
1176 
1177  //show_certificate (rp, X400_N_CERT_RECIP_CIC, "recipient CIC");
1178  show_recip_certificate (rp, X400_N_CERT_RECIP_CIC, "recipient CIC");
1179 
1180  return X400_E_NOERROR;
1181 }
1182 
1183 
1184 
1185 static int get_4406_info(
1186  struct X400msMessage *mp
1187 )
1188 {
1189  int status;
1190  int intparam;
1191  size_t length;
1192  char buffer[BUFSIZ];
1193 
1194  /* get the 4406 status which tells us if it's PCT or not */
1195  status = X400msMsgGetIntParam(mp, X400_N_S4406_STATUS, &intparam);
1196  if (status == X400_E_NO_VALUE ) {
1197  printf("4406 Status (X400_N_S4406_STATUS) absent so not PCT: %s\n", X400msError(status));
1198  return X400_E_NOERROR;
1199  }
1200  if (status != X400_E_NOERROR) {
1201  fprintf(stderr, "Error from MsgGetIntParam (X400_N_S4406_STATUS): %s\n",
1202  X400msError(status));
1203  } else {
1204  printf("4406 Status(X400_N_S4406_STATUS): %d\n", intparam);
1205  }
1206 
1207 
1208  /* get the 4406 security elements */
1209  status = X400msMsgGetIntParam(mp, X400_N_S4406, &intparam);
1210  if (status == X400_E_NO_VALUE ) {
1211  printf("4406 absent: %s\n", X400msError(status));
1212  }
1213  if (status != X400_E_NOERROR) {
1214  fprintf(stderr, "Error from MsgGetIntParam (X400_N_S4406): %s\n",
1215  X400msError(status));
1216  } else {
1217  printf("4406 (X400_N_S4406): %d\n", intparam);
1218  }
1219 
1220  /* Get the Message Identifier of the Subject message */
1222  buffer, sizeof buffer, &length);
1223  if (status != X400_E_NOERROR) {
1224  fprintf(stderr, "Error from MsgGetStrParam (X400_S_S4406_STATUS_DETAIL): %s\n",
1225  X400msError(status));
1226  return (status);
1227  }
1228  printf("S4406 Status Detail (X400_S_S4406_STATUS_DETAIL): %.*s\n", (int)length, buffer);
1229 
1230  show_message_certificate (mp, "S4406");
1231 
1232  return X400_E_NOERROR;
1233 }
1234 
1235 
1236 static void show_message_certificate (
1237  struct X400msMessage *mp,
1238  const char *tag ARGNOTUSED)
1239 {
1240  int status;
1241  struct X400Certificate *cert;
1242 
1243  status = X400msMsgGetCert (mp, X400_N_S4406_CERTIFICATE, &cert);
1244  if ( status != X400_E_NOERROR ) {
1245  fprintf (stderr, "Error getting S4406 certificate: %s\n",
1246  X400msError (status));
1247  return;
1248  }
1249  show_certificate(cert, "X400_N_S4406_CERTIFICATE");
1250  return;
1251 }
1252 
1253 static void show_recip_certificate (
1254  struct X400Recipient *rp,
1255  int certtype,
1256  const char *tag)
1257 {
1258  int status;
1259  struct X400Certificate *cert;
1260 
1261  status = X400RecipGetCert (rp, certtype, &cert);
1262  if ( status != X400_E_NOERROR ) {
1263  fprintf (stderr, "Error getting %s certificate: %s\n",
1264  tag, X400msError (status));
1265  return;
1266  }
1267  show_certificate(cert, tag);
1268  return;
1269 }
1270 
1271 static void show_certificate (
1272  struct X400Certificate *cert,
1273  const char *tag)
1274 {
1275  int status;
1276  char buffer[BUFSIZ];
1277  size_t length;
1278  int paramval;
1279 
1280  /* Return the subject DN from Orig cert */
1282  buffer, sizeof buffer, &length);
1283  if (status != X400_E_NOERROR) {
1284  fprintf(stderr, "Error getting subject of cert used for %s: %s\n",
1285  tag, X400msError(status));
1286  } else {
1287  printf("Subject of Cert used to verify %s (%.*s)\n",
1288  tag, (int)length, buffer);
1289  }
1290 
1291  /* Return the issuer DN from Orig cert */
1293  buffer, sizeof buffer, &length);
1294  if (status != X400_E_NOERROR) {
1295  fprintf(stderr, "Error getting issuer of cert used for %s: %s\n",
1296  tag, X400msError(status));
1297  } else {
1298  printf("Issuer of Cert used to verify %s (%.*s)\n",
1299  tag, (int)length, buffer);
1300  }
1301 
1302  /* Return the serial number from Orig cert used to verify the
1303  * Content Integrity Check */
1305  buffer, sizeof buffer, &length);
1306  if (status != X400_E_NOERROR) {
1307  fprintf(stderr, "Error getting serial num of cert used for %s: %s\n",
1308  tag, X400msError(status));
1309  } else {
1310  printf("Serial Num of Cert used to verify %s (%.*s)\n",
1311  tag, (int)length, buffer);
1312  }
1313 
1314  /* Return the Orig cert used to verify the Content Integrity Check */
1315  status = X400CertGetStrParam(cert, X400_S_CERT_BER,
1316  buffer, sizeof buffer, &length);
1317  if (status != X400_E_NOERROR) {
1318  fprintf(stderr, "Error getting cert der used for %s: %s\n",
1319  tag, X400msError(status));
1320  } else {
1321  printf(
1322  "Returned Cert used to verify %s (%d)\n",
1323  tag, (int)length);
1324  }
1325 
1326  /* Find any ORaddress subject alt name and its status */
1327  status = X400CertGetStrParam(cert, X400_S_OR_ADDRESS,
1328  buffer, sizeof buffer, &length);
1329  if (status != X400_E_NOERROR) {
1330  if ( status == X400_E_NO_VALUE ) {
1331  fprintf(stderr, "No ORaddress subject alt. name\n");
1332  } else {
1333  fprintf(stderr, "Error from CertGetStrParam: %s\n",
1334  X400msError(status));
1335  return;
1336  }
1337  } else {
1338  fprintf(stderr, "ORaddress subject alt name: '%.*s'\n",
1339  (int)length, buffer);
1340  }
1341 
1342  status = X400CertGetIntParam(cert, X400_N_CERT_ORADDRESS_STATUS, &paramval);
1343 
1344  if (status != X400_E_NOERROR) {
1345  fprintf(stderr, "Error from CertGetStrParam: %s\n",
1346  X400msError(status));
1347  return;
1348  }
1349 
1350  fprintf(stderr, "ORaddress subject alt name status: %s\n",
1351  X400msError (paramval));
1352 }
1353 
1354 static void usage(void) {
1355  printf("usage: %s\n", optstr);
1356  printf("\t where:\n");
1357  printf("\t -u : Don't prompt to override defaults \n");
1358  printf("\t -3 : Use P3 connection \n");
1359  printf("\t -7 : Use P7 connection \n");
1360  printf("\t -m : OR Address in P7 bind arg \n");
1361  printf("\t -d : DN in P7 bind arg \n");
1362  printf("\t -p : Presentation Address of P7 Store \n");
1363  printf("\t -w : P7 password of P7 user \n");
1364  printf("\t -M : OR Address in P3 bind arg \n");
1365  printf("\t -D : DN in P3 bind arg \n");
1366  printf("\t -P : Presentation Address of P3 server\n");
1367  printf("\t -W : P3 password of P3 user \n");
1368  printf("\t -e : Security Environment (dir with x509 subdir): obsolete, use -Y <p12file>\n");
1369  printf("\t -x : DN of X.509 Digital Identity\n");
1370  printf("\t -b : Passphrase for private key in PKCS12 file\n");
1371  printf("\t -E : Fetch messages until all read\n");
1372  printf("\t -Y : Filename of PKCS12 file containing Digital Identity\n");
1373  printf("\t -U : Directory containing trust anchors\n");
1374  printf("\t -I : Generate IPN from message received\n");
1375  return;
1376 }
#define X400_S_LOG_CONFIGURATION_FILE
Definition: x400_att.h:1092
#define X400_S_CERT_ISSUER_DN
Definition: x400_att.h:1529
#define X400_S_MSGTOK_RECIP
Definition: x400_att.h:1446
int X400msMsgSend(struct X400msMessage *mp)
Send message object.
#define X400_N_S4406_CERTIFICATE
Definition: x400_att.h:624
#define X400_S_RECIP_CIC
Definition: x400_att.h:1478
int X400RecipGetCert(struct X400Recipient *rp, int certtype, struct X400Certificate **certp)
Get certificate object from recipient This returns a certificate which was used to sign an object in ...
#define X400_N_MSGTOK_SEC_LAB_STATUS
Definition: x400_att.h:1455
#define X400_N_S4406_STATUS
Definition: x400_att.h:608
#define X400_S_CONVERSION_EITS
Definition: x400_att.h:1011
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.
#define X400_S_AUTOFORWARD_COMMENT
Definition: x400_att.h:1022
#define X400_S_S4406_STATUS_DETAIL
Definition: x400_att.h:614
int X400RecipGetStrParam(struct X400Recipient *rp, int paramtype, char *buffer, size_t buflen, size_t *paramlenp)
Return a string-valued parameter from the recipient object.
#define X400_S_SEC_IDENTITY
Definition: x400_att.h:554
#define X400_S_RECEIPT_TIME
Definition: x400_att.h:1025
int X400msSetStrDefault(struct X400msSession *sp, int paramtype, const char *value, size_t length)
Set a default string parameter value in a session.
#define X400_E_X509_CERT_INVALID
Definition: x400_att.h:199
#define X400_E_X509_ENV
Definition: x400_att.h:175
#define X400_N_MSGTOK_STATUS
Definition: x400_att.h:1437
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...
#define X400_E_X509_VERIFY_FAIL_NO_CERT
Definition: x400_att.h:184
#define X400_E_X509_VERIFY_FAIL_NO_PUBKEY
Definition: x400_att.h:187
#define X400_N_MSGTOK_RECIP_STATUS
Definition: x400_att.h:1458
#define X400_E_NO_RECIP
Definition: x400_att.h:109
#define X400_N_RECIP_CIC_STATUS
Definition: x400_att.h:1475
#define X400_S_MSGTOK_CIC
Definition: x400_att.h:1464
#define X400_S_SECURITY_LABEL
Definition: x400_att.h:1348
#define X400_N_NON_RECEIPT_REASON
Definition: x400_att.h:1014
int X400msClose(struct X400msSession *sp)
Close a X400 Session.
#define X400_E_NO_VALUE
Definition: x400_att.h:100
#define X400_N_ACK_MODE
Definition: x400_att.h:1028
#define X400_S_CERT_BER
Definition: x400_att.h:1523
int X400msRecipGetIntParam(struct X400Recipient *rp, int paramtype, int *valp)
Return a integer-valued parameter from the recipient object.
#define X400_S_MSGTOK_SEC_LAB
Definition: x400_att.h:1449
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.
#define X400_S_MESSAGE_DELIVERY_TIME
Definition: x400_att.h:442
#define X400_E_X509_ITEM_INVALID
Definition: x400_att.h:202
#define X400_S_MSGTOK_DER
Definition: x400_att.h:1440
#define X400_N_CERT_MSGTOK_CIC
Definition: x400_att.h:1513
const char * X400msError(int error)
Obtain a string describing the meaning of the given error code.
#define X400_T_IA5TEXT
Definition: x400_att.h:799
#define X400_S_SUPP_RECEIPT_INFO
Definition: x400_att.h:1031
#define X400_S_SEC_IDENTITY_DN
Definition: x400_att.h:563
#define X400_N_IS_IPN
Definition: x400_att.h:1005
int X400msMsgNew(struct X400msSession *sp, int type, struct X400msMessage **mpp)
Creates new message.
int X400msWait(struct X400msSession *sp, int seconds, int *count)
Wait for messages to be ready to be read.
#define X400_S_MESSAGE_IDENTIFIER
Definition: x400_att.h:405
#define X400_S_SEC_IDENTITY_PASSPHRASE
Definition: x400_att.h:560
#define X400_N_PROOF_OF_DEL_REQ
Definition: x400_att.h:978
#define X400_E_NOERROR
Definition: x400_att.h:46
#define X400_S_SUBJECT_IDENTIFIER
Definition: x400_att.h:1039
int X400msRecipGet(struct X400msMessage *mp, int type, int number, struct X400Recipient **rpp)
Get recipient object from message.
int X400msRecipGetStrParam(struct X400Recipient *rp, int paramtype, char *buffer, size_t buflen, size_t *paramlenp)
Return a string-valued parameter from the recipient object.
#define X400_S_EXTERNAL_CONTENT_TYPE
Definition: x400_att.h:447
X400 MA/MS (P3/P7) Interface.
#define X400_E_X509_VERIFY_FAIL_UNSUPPORTED_ALG
Definition: x400_att.h:193
#define X400_E_X509_VERIFY_FAIL
Definition: x400_att.h:196
#define X400_N_CERT_ORADDRESS_STATUS
Definition: x400_att.h:1535
int X400msMsgGetIntParam(struct X400msMessage *mp, int paramtype, int *valp)
Return a integer-valued parameter from the message object.
#define X400_N_CONTENT_LENGTH
Definition: x400_att.h:411
#define X400_N_MSGTOK_SEQ_NUM
Definition: x400_att.h:1443
#define X400_RECIP_PRIMARY
Definition: x400_att.h:296
#define X400_E_X509_VERIFY_FAIL_INCOMPAT_ALG
Definition: x400_att.h:190
#define X400_N_S4406
Definition: x400_att.h:599
#define X400_S_CERT_SERIAL_NUM
Definition: x400_att.h:1532
int X400msSetIntDefault(struct X400msSession *sp, int paramtype, int value)
Set a default integer parameter value in a session.
#define X400_N_NON_DELIVERY_DIAGNOSTIC
Definition: x400_att.h:1054
#define X400_N_NON_DELIVERY_REASON
Definition: x400_att.h:1051
#define X400_S_SUBJECT
Definition: x400_att.h:723
#define X400_B_RETURN_VERIFICATION_ERRORS
Definition: x400_att.h:1099
#define X400_N_CERT_MSGTOK
Definition: x400_att.h:1507
#define X400_S_CERT_SUBJECT_DN
Definition: x400_att.h:1526
int X400msMsgGetStrParam(struct X400msMessage *mp, int paramtype, char *buffer, size_t buflen, size_t *paramlenp)
Return a string-valued parameter from the message object.
#define X400_S_SUBJECT_IPM
Definition: x400_att.h:1008
#define X400_S_SUPPLEMENTARY_INFO
Definition: x400_att.h:1042
#define X400_E_X509_INIT
Definition: x400_att.h:181
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 X400msMakeIPN(struct X400msMessage *mp, int non_receipt_reason, struct X400msMessage **mpp)
Make an IPN based on the subject IPM.
#define X400_S_SEC_TRUSTED_CERTS_DIR
Definition: x400_att.h:581
#define X400_N_PRECEDENCE
Definition: x400_att.h:686
#define X400_MSG_MESSAGE
Definition: x400_att.h:29
#define X400_N_MSGTOK_PODR_STATUS
Definition: x400_att.h:1452
#define X400_N_DISCARD_REASON
Definition: x400_att.h:1017
#define X400_N_CERT_RECIP_CIC
Definition: x400_att.h:1510
#define X400_N_CONTENT_TYPE
Definition: x400_att.h:408
#define X400_S_OR_ADDRESS
Definition: x400_att.h:349
int X400msMsgDelete(struct X400msMessage *mp, int retain)
Delete message object.
#define X400_RECIP_REPORT
Definition: x400_att.h:314
#define X400_N_MSGTOK_CIC_STATUS
Definition: x400_att.h:1461
#define X400_RECIP_ENVELOPE
Definition: x400_att.h:335