1 /* zxencdectest.c  -  Test XML encoding and decoding using zx generated code
2  * Copyright (c) 2010-2011 Sampo Kellomaki (sampo@iki.fi), All Rights Reserved.
3  * Copyright (c) 2006-2007 Symlabs (symlabs@symlabs.com), All Rights Reserved.
4  * Author: Sampo Kellomaki (sampo@iki.fi)
5  * This is confidential unpublished proprietary source code of the author.
6  * NO WARRANTY, not even implied warranties. Contains trade secrets.
7  * Distribution prohibited unless authorized in writing.
8  * Licensed under Apache License 2.0, see file COPYING.
9  * $Id: zxencdectest.c,v 1.9 2009-11-24 23:53:40 sampo Exp $
10  *
11  * 1.7.2006, started --Sampo
12  * 9.2.2007, improved to make basis of a test suite tool --Sampo
13  * 1.3.2011, added zx_timegm() testing --Sampo
14  *
15  * Test encoding and decoding SAML 2.0 assertions and other related stuff.
16  */
17 
18 #include "platform.h"  /* This needs to appear first to avoid mingw64 problems. */
19 #include "errmac.h"
20 
21 #include <string.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 
26 #include "zx.h"
27 #include "zxid.h"
28 #include "zxidpriv.h"
29 #include "zxidutil.h"
30 #include "saml2.h"
31 #include "c/zxidvers.h"
32 #include "c/zx-data.h"
33 #include "c/zx-const.h"
34 #include "c/zx-ns.h"
35 
36 char* help =
37 "zxencdectest  -  ZX encoding and decoding tester - R" ZXID_REL "\n\
38 Copyright (c) 2010-2011 Sampo Kellomaki (sampo@iki.fi), All Rights Reserved.\n\
39 Copyright (c) 2006-2007 Symlabs (symlabs@symlabs.com), All Rights Reserved.\n\
40 Author: Sampo Kellomaki (sampo@iki.fi)\n\
41 NO WARRANTY, not even implied warranties. Licensed under Apache License v2.0\n\
42 See http://www.apache.org/licenses/LICENSE-2.0\n\
43 Send well researched bug reports to the author. Home: zxid.org\n\
44 \n\
45 Usage: zxencdectest [options] <foo.xml >reencoded-foo.xml\n\
46   -r N         Run test number N. 1 = IBM cert dec, 2 = IBM cert enc dec\n\
47   -i N         Number of iterations to benchmark (default 1).\n\
48   -t SECONDS   Timeout. Default: 0=no timeout.\n\
49   -c CIPHER    Enable crypto on DTS interface using specified cipher. Use '?' for list.\n\
50   -k FDNUMBER  File descriptor for reading symmetric key. Use 0 for stdin.\n\
51   -egd PATH    Specify path of Entropy Gathering Daemon socket, default\n\
52                on Solaris: /tmp/entropy; Linux: /dev/urandom\n\
53                See http://www.lothar.com/tech/crypto/ or\n\
54                http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/prngd.html\n\
55   -rand PATH   Location of random number seed file. On Solaris EGD is used.\n\
56                On Linux the default is /dev/urandom. See RFC1750.\n\
57   -wo PATH     File to write wire order encoding in\n\
58   -v           Verbose messages.\n\
59   -q           Be extra quiet.\n\
60   -d           Turn on debugging.\n\
61   -license     Show licensing and NO WARRANTY details.\n\
62   -h           This help message\n\
63   --           End of options\n";
64 
65 #define DIE(reason) MB fprintf(stderr, "%s\n", reason); exit(2); ME
66 
67 int ak_buf_size = 0;
68 int verbose = 1;
69 extern int debug;
70 int timeout = 0;
71 int gcthreshold = 0;
72 int leak_free = 0;
73 extern int assert_nonfatal;
74 int drop_uid = 0;
75 int drop_gid = 0;
76 char* rand_path;
77 char* egd_path;
78 char  symmetric_key[1024];
79 int symmetric_key_len;
80 int n_iter = 1;
81 char* wo_path = 0;
82 char buf[256*1024];
83 
84 /* Called by:  opt */
test_ibm_cert_problem()85 void test_ibm_cert_problem()  /* -r 1 */
86 {
87   int got_all;
88   zxid_conf* cf;
89   struct zx_root_s* r;
90   struct zx_sp_LogoutRequest_s* req;
91 
92   read_all_fd(fdstdin, buf, sizeof(buf)-1, &got_all);
93   if (got_all <= 0) DIE("Missing data");
94   buf[got_all] = 0;
95 
96   /* IBM padding debug */
97   cf = zxid_new_conf("/var/zxid/");
98   r = zx_dec_zx_root(cf->ctx, got_all, buf, "zxencdectest");
99   if (!r || !r->Envelope || r->Envelope->Body || r->Envelope->Body->LogoutRequest)
100     DIE("Decode failure");
101 
102 #if 1
103   cf->enc_pkey = zxid_read_private_key(cf, "sym-idp-enc.pem");
104 #else
105   cf->enc_pkey = zxid_read_private_key(cf, "ibm-idp-enc.pem");
106 #endif
107 
108   req = r->Envelope->Body->LogoutRequest;
109   req->NameID = zxid_decrypt_nameid(cf, req->NameID, req->EncryptedID);
110   printf("r1 nid(%.*s)\n", ZX_GET_CONTENT_LEN(req->NameID), ZX_GET_CONTENT_S(req->NameID));
111 }
112 
113 /* Called by:  opt */
test_ibm_cert_problem_enc_dec()114 void test_ibm_cert_problem_enc_dec()  /* -r 2 */
115 {
116   zxid_conf* cf;
117   struct zx_sp_LogoutRequest_s* req;
118   zxid_nid* nameid;
119   zxid_entity* idp_meta;
120 
121   cf = zxid_new_conf("/var/zxid/");
122 
123   nameid = zx_NEW_sa_NameID(cf->ctx,0);
124   /*nameid->SPNameQualifier = zx_ref_attr(cf->ctx, &nameid->gg, zx_SPNameQualifier_ATTR, spqual);*/
125   nameid->NameQualifier = zx_ref_attr(cf->ctx, &nameid->gg, zx_NameQualifier_ATTR, "ibmidp");
126   nameid->Format = zx_ref_attr(cf->ctx, &nameid->gg, zx_Format_ATTR, "persistent");
127   zx_add_content(cf->ctx, &nameid->gg, zx_ref_str(cf->ctx, "a-persistent-nid"));
128 
129 #if 0
130   cf->enc_pkey = zxid_read_private_key(cf, "sym-idp-enc.pem");
131 #else
132   cf->enc_pkey = zxid_read_private_key(cf, "ibm-idp-enc.pem");
133   idp_meta = zxid_get_ent_file(cf, "N9zsU-AwbI1O-U3mvjLmOALtbtU", "test_ibm"); /* IBMIdP */
134 #endif
135 
136   req = zxid_mk_logout(cf, nameid, 0, idp_meta);
137   req->NameID = zxid_decrypt_nameid(cf, req->NameID, req->EncryptedID);
138   printf("r2 nid(%.*s) should be(a-persistent-nid)\n", ZX_GET_CONTENT_LEN(req->NameID), ZX_GET_CONTENT_S(req->NameID));
139 }
140 
141 /* Called by:  opt */
so_enc_dec()142 void so_enc_dec()     /* -r 3 */
143 {
144   zxid_conf* cf;
145   struct zx_sp_Status_s* st;
146   struct zx_str* ss;
147   cf = zxid_new_conf("/var/zxid/");
148   st = zxid_mk_Status(cf, 0, "SC1", "SC2", "MESSAGE");
149   ss = zx_easy_enc_elem_opt(cf, &st->gg);
150   printf("%.*s", ss->len, ss->s);  zx_dump_ns_tab(cf->ctx, 0);
151 }
152 
153 /* Called by:  opt */
attribute_sort_test()154 void attribute_sort_test()  /* -r 4 */
155 {
156   zxid_conf* cf;
157   struct zx_xasp_XACMLAuthzDecisionQuery_s* q;
158   struct zx_xaspcd1_XACMLAuthzDecisionQuery_s* q2;
159   struct zx_str* ss;
160   cf = zxid_new_conf("/var/zxid/");
161   q = zxid_mk_az(cf, 0, 0, 0, 0);
162   ss = zx_easy_enc_elem_sig(cf, &q->gg);
163   printf("%.*s", ss->len, ss->s);
164 
165   q2 = zxid_mk_az_cd1(cf, 0, 0, 0, 0);
166   ss = zx_easy_enc_elem_sig(cf, &q2->gg);
167   printf("CD1: %.*s", ss->len, ss->s);
168 }
169 
170 /* Called by:  opt */
a7n_test()171 void a7n_test()       /* -r 6 */
172 {
173   struct timeval srctss;
174   zxid_conf* cf;
175   zxid_cgi cgi;
176   zxid_ses sess;
177   zxid_nid* nameid;
178   struct zx_str* issuer;
179   struct zx_sp_AuthnRequest_s* ar;
180   zxid_entity* sp_meta;
181   zxid_a7n* a7n;
182   memset(&cgi, 0, sizeof(cgi));
183   memset(&sess, 0, sizeof(sess));
184   memset(&srctss, 0, sizeof(srctss));
185 
186   sess.sid = "MSES1234";
187   sess.uid = "test";
188   cf = zxid_new_conf_to_cf("PATH=/var/zxid/&URL=http://sp1.zxidsp.org:8081/zxidhlo");
189 #if 1
190   ar = zxid_mk_authn_req(cf, &cgi);
191   issuer = ZX_GET_CONTENT(ar->Issuer);
192   D("issuer(%.*s)", issuer->len, issuer->s);
193   sp_meta = zxid_get_ent_ss(cf, issuer);
194   a7n = zxid_sso_issue_a7n(cf, &cgi, &sess, &srctss, sp_meta, 0, &nameid, 0, ar);
195 #else
196   a7n = zxid_mk_usr_a7n_to_sp(cf, &sess, const char* uid, zxid_nid* nameid, zxid_entity* sp_meta, const char* sp_name_buf, 0);
197 #endif
198   zxid_find_attribute(a7n, 0, 0, 0, 0, 0, 0, 1);
199   //zxid_ssos_anreq(cf, a7n, ar, ZX_GET_CONTENT(ar->Issuer));
200   zxid_mni_do_ss(cf, &cgi, &sess, zxid_mk_mni(cf, nameid, zx_ref_str(cf->ctx, "newnym"), sp_meta), zx_ref_str(cf->ctx, "loc-dummy"));
201   zxid_sp_mni_soap(cf, &cgi, &sess, zx_ref_str(cf->ctx, "newnym"));
202 }
203 
204 /* Called by:  opt */
x509_test()205 void x509_test()      /* -r 7 */
206 {
207   struct timeval srctss;
208   zxid_conf* cf;
209   zxid_cgi cgi;
210   zxid_ses sess;
211   zxid_nid* nameid;
212   char buf[4096];
213   memset(&cgi, 0, sizeof(cgi));
214   memset(&sess, 0, sizeof(sess));
215   memset(&srctss, 0, sizeof(srctss));
216 
217   sess.uid = "test";
218   cf = zxid_new_conf("/var/zxid/");
219 
220 #if 1
221   nameid = zx_NEW_sa_NameID(cf->ctx,0);
222   nameid->SPNameQualifier = zx_ref_attr(cf->ctx, &nameid->gg, zx_SPNameQualifier_ATTR, "http://mysp?o=B");
223   nameid->NameQualifier = zx_ref_attr(cf->ctx, &nameid->gg, zx_NameQualifier_ATTR, "http://myidp?o=B");
224   nameid->Format = zx_ref_attr(cf->ctx, &nameid->gg, zx_Format_ATTR, "persistent");
225   zx_add_content(cf->ctx, &nameid->gg, zx_ref_str(cf->ctx, "a-persistent-nid"));
226 #else
227   struct zx_sp_AuthnRequest_s* ar;
228   zxid_entity* sp_meta;
229   zxid_a7n* a7n;
230   ar = zxid_mk_authn_req(cf, &cgi);
231   sp_meta = zxid_get_ent_ss(cf, ZX_GET_CONTENT(ar->Issuer));
232   a7n = zxid_sso_issue_a7n(cf, &cgi, &sess, &srctss, sp_meta, 0, &nameid, 0, ar);
233 #endif
234   zxid_mk_at_cert(cf, sizeof(buf), buf, "test", nameid, "1.2.826.0.1.3344810.1.1.14", zx_ref_str(cf->ctx, "Role0"));
235   printf("%s",buf);
236 }
237 
238 /* Called by:  timegm_test x16 */
timegm_tester(zxid_conf * cf,const char * date_time)239 int timegm_tester(zxid_conf* cf, const char* date_time)
240 {
241   struct zx_str* ss;
242   int secs;
243   cf = zxid_new_conf("/var/zxid/");
244   secs = zx_date_time_to_secs(date_time);
245   ss = zxid_date_time(cf, secs);
246   if (memcmp(date_time, ss->s, ss->len)) {
247     printf("%s %d\n%.*s ERR\n\n", date_time, secs, ss->len, ss->s);
248     return 0;
249   } else {
250     if (verbose)
251       printf("%s %d\n%.*s OK\n\n", date_time, secs, ss->len, ss->s);
252     return 1;
253   }
254 }
255 
256 /* Called by:  timegm_test */
leap_test(int aa)257 int leap_test(int aa) {
258   return LEAP(aa);
259 }
260 
261 /* Called by:  opt */
timegm_test()262 void timegm_test()      /* -r 8 */
263 {
264   int aa;
265   zxid_conf* cf = zxid_new_conf("/var/zxid/");
266   printf("leap(2011)=%d\n", leap_test(2011));
267 
268   timegm_tester(cf, "2011-02-28T11:30:19Z");
269   timegm_tester(cf, "2011-03-01T11:30:19Z");
270   timegm_tester(cf, "2011-03-02T11:30:19Z");
271   timegm_tester(cf, "2011-03-03T11:30:19Z");
272   timegm_tester(cf, "2011-03-04T11:30:19Z");
273   timegm_tester(cf, "2011-03-31T11:30:19Z");
274   timegm_tester(cf, "2011-04-01T11:30:19Z");
275   timegm_tester(cf, "2011-04-02T11:30:19Z");
276 
277   for (aa = 1970; aa < 2028; ++aa) {
278     snprintf(buf, sizeof(buf), "%d-02-28T11:30:19Z", aa); if (!timegm_tester(cf, buf)) exit(1);
279     snprintf(buf, sizeof(buf), "%d-03-01T11:30:19Z", aa); if (!timegm_tester(cf, buf)) exit(1);
280     snprintf(buf, sizeof(buf), "%d-03-02T11:30:19Z", aa); if (!timegm_tester(cf, buf)) exit(1);
281     snprintf(buf, sizeof(buf), "%d-03-03T11:30:19Z", aa); if (!timegm_tester(cf, buf)) exit(1);
282     snprintf(buf, sizeof(buf), "%d-03-04T11:30:19Z", aa); if (!timegm_tester(cf, buf)) exit(1);
283     snprintf(buf, sizeof(buf), "%d-03-31T11:30:19Z", aa); if (!timegm_tester(cf, buf)) exit(1);
284     snprintf(buf, sizeof(buf), "%d-04-01T11:30:19Z", aa); if (!timegm_tester(cf, buf)) exit(1);
285     snprintf(buf, sizeof(buf), "%d-04-02T11:30:19Z", aa); if (!timegm_tester(cf, buf)) exit(1);
286   }
287 }
288 
289 const char foobar[] = "foobar";
290 const char goobar[] = "goo\r\n~[]";
291 
292 int zxid_wsc_valid_re_env(zxid_conf* cf, zxid_ses* ses, const char* az_cred, struct zx_e_Envelope_s* env, const char* enve);
293 
294 /* Called by:  opt */
covimp_test()295 void covimp_test()       /* -r 5 */
296 {
297   char buf[256];
298   int outlen;
299   char* out;
300   char* sigval;
301   char* sigmsg;
302   struct zx_str* ss;
303   struct zx_e_Envelope_s* env;
304   zxid_fault* flt;
305   zxid_tas3_status* st;
306   zxid_entity* meta;
307   zxid_conf* cf;
308   zxid_cgi cgi;
309   zxid_ses sess;
310   memset(&cgi, 0, sizeof(cgi));
311   memset(&sess, 0, sizeof(sess));
312 
313   printf("version(%x)\n", zxid_version());
314   cf = zxid_new_conf("/var/zxid/");
315   printf("urlenc(%s)\n", zx_url_encode(cf->ctx, sizeof("test1://foo?a=b&c=d e")-1, "test1://foo?a=b&c=d e", &outlen));
316   zx_hexdec(buf, "313233", 6, hex_trans);
317   printf("hexdec(%.3s)\n", buf);
318   hexdmp("test2: ", (char*)foobar, sizeof(foobar), 1000);
319   hexdmp("test2b: ", (char*)goobar, sizeof(goobar), 1000);
320   copy_file("t/XML1.out","tmp/foo3","test3",0);
321   copy_file("t/XML1.out","tmp/foo4","test4",1);
322   copy_file("t/XML1.out","tmp/foo5","test5",2);
323   copy_file("/impossible","tmp/foo5a","test5a",0);
324   copy_file("t/XML1.out","tmp/impossiblefoo5b","test5b",0);
325   read_all(sizeof(buf), buf, "test5c", 1, "/impossible");
326   read_all_alloc(cf->ctx, "test5d", 1, &outlen, "/impossible");
327   zx_prepare_dec_ctx(cf->ctx, zx_ns_tab, zx__NS_MAX, foobar, foobar+sizeof(foobar));
328   zx_format_parse_error(cf->ctx, buf, sizeof(buf), "test6");
329   printf("parse err(%s)\n", buf);
330   zx_xml_parse_err(cf->ctx, '?', __FUNCTION__, "test7");
331   printf("memmem(%s)\n", zx_memmem("foobar", 6, "oba", 3));
332   ss = zx_ref_str(cf->ctx, "abc");
333   zx_str_conv(ss, &outlen, &out);
334   zxid_wsp_decorate(cf, &sess, 0, "<foo/>");
335 #ifndef MINGW
336   setenv("HTTP_COOKIE", "_liberty_idp=\"test8\"", 1);
337   zxid_cdc_read(cf, &cgi);
338 #endif
339   cgi.cdc = "test9";
340   zxid_cdc_check(cf, &cgi);
341   zxid_new_cgi(cf, "=test10&ok=1&okx=2&s=S123&c=test11&e=abc&d=def&&l=x&l1=y&l1foo=z&inv=qwe&fg=1&fh=7&fr=RS&gu=1&gn=asa&ge=1&an=&aw=&at=&SAMLart=artti&SAMLResponse=respis");
342 
343   printf("n=%s\n", zxid_saml2_map_nid_fmt("n"));
344   printf("p=%s\n", zxid_saml2_map_nid_fmt("p"));
345   printf("t=%s\n", zxid_saml2_map_nid_fmt("t"));
346   printf("u=%s\n", zxid_saml2_map_nid_fmt("u"));
347   printf("e=%s\n", zxid_saml2_map_nid_fmt("e"));
348   printf("x=%s\n", zxid_saml2_map_nid_fmt("x"));
349   printf("w=%s\n", zxid_saml2_map_nid_fmt("w"));
350   printf("k=%s\n", zxid_saml2_map_nid_fmt("k"));
351   printf("s=%s\n", zxid_saml2_map_nid_fmt("s"));
352   printf("X=%s\n", zxid_saml2_map_nid_fmt("X"));
353 
354   printf("r=%s\n", zxid_saml2_map_protocol_binding("r"));
355   printf("a=%s\n", zxid_saml2_map_protocol_binding("a"));
356   printf("p=%s\n", zxid_saml2_map_protocol_binding("p"));
357   printf("q=%s\n", zxid_saml2_map_protocol_binding("q"));
358   printf("s=%s\n", zxid_saml2_map_protocol_binding("s"));
359   printf("e=%s\n", zxid_saml2_map_protocol_binding("e"));
360   printf("X=%s\n", zxid_saml2_map_protocol_binding("X"));
361 
362   printf("NULL=%d\n",       zxid_protocol_binding_map_saml2(0));
363   printf("SAML2_REDIR=%d\n", zxid_protocol_binding_map_saml2(zx_ref_str(cf->ctx, SAML2_REDIR)));
364   printf("SAML2_ART=%d\n",   zxid_protocol_binding_map_saml2(zx_ref_str(cf->ctx, SAML2_ART)));
365   printf("SAML2_POST=%d\n",  zxid_protocol_binding_map_saml2(zx_ref_str(cf->ctx, SAML2_POST)));
366   printf("SAML2_POST_SIMPLE_SIGN=%d\n", zxid_protocol_binding_map_saml2(zx_ref_str(cf->ctx, SAML2_POST_SIMPLE_SIGN)));
367   printf("SAML2_SOAP=%d\n",  zxid_protocol_binding_map_saml2(zx_ref_str(cf->ctx, SAML2_SOAP)));
368   printf("SAML2_PAOS=%d\n",  zxid_protocol_binding_map_saml2(zx_ref_str(cf->ctx, SAML2_PAOS)));
369   printf("unknown=%d\n",    zxid_protocol_binding_map_saml2(zx_ref_str(cf->ctx, "unknown")));
370 
371   printf("n=%s\n",       zxid_saml2_map_authn_ctx("n"));
372   printf("pwp=%s\n",     zxid_saml2_map_authn_ctx("pwp"));
373   printf("pw=%s\n",      zxid_saml2_map_authn_ctx("pw"));
374   printf("prvses=%s\n",  zxid_saml2_map_authn_ctx("prvses"));
375   printf("clicert=%s\n", zxid_saml2_map_authn_ctx("clicert"));
376   printf("unspcf=%s\n",  zxid_saml2_map_authn_ctx("unspcf"));
377   printf("ip=%s\n",      zxid_saml2_map_authn_ctx("ip"));
378   printf("X=%s\n",       zxid_saml2_map_authn_ctx("X"));
379 
380   zxid_sigres_map(ZXSIG_OK, &sigval, &sigmsg);         printf("%s %s\n", sigval, sigmsg);
381   zxid_sigres_map(ZXSIG_BAD_DALGO, &sigval, &sigmsg);  printf("%s %s\n", sigval, sigmsg);
382   zxid_sigres_map(ZXSIG_DIGEST_LEN, &sigval, &sigmsg); printf("%s %s\n", sigval, sigmsg);
383   zxid_sigres_map(ZXSIG_BAD_DIGEST, &sigval, &sigmsg); printf("%s %s\n", sigval, sigmsg);
384   zxid_sigres_map(ZXSIG_BAD_SALGO, &sigval, &sigmsg);  printf("%s %s\n", sigval, sigmsg);
385   zxid_sigres_map(ZXSIG_BAD_CERT, &sigval, &sigmsg);   printf("%s %s\n", sigval, sigmsg);
386   zxid_sigres_map(ZXSIG_VFY_FAIL, &sigval, &sigmsg);   printf("%s %s\n", sigval, sigmsg);
387   zxid_sigres_map(ZXSIG_NO_SIG, &sigval, &sigmsg);     printf("%s %s\n", sigval, sigmsg);
388   zxid_sigres_map(ZXSIG_TIMEOUT, &sigval, &sigmsg);    printf("%s %s\n", sigval, sigmsg);
389   zxid_sigres_map(ZXSIG_AUDIENCE, &sigval, &sigmsg);   printf("%s %s\n", sigval, sigmsg);
390   zxid_sigres_map(99, &sigval, &sigmsg);               printf("%s %s (other)\n", sigval, sigmsg);
391 
392   printf("fake_sso=%d\n", zxid_sp_anon_finalize(cf, &cgi, &sess));
393 
394 #ifndef MINGW
395   setenv("HTTP_PAOS", SAML2_SSO_ECP, 1);
396   zxid_lecp_check(cf, &cgi);        /* *** should test in realistic context */
397 #endif
398 
399   meta = zxid_get_ent_file(cf, "N9zsU-AwbI1O-U3mvjLmOALtbtU", "covimp"); /* IBMIdP */
400   zxid_mk_art_deref(cf, 0, meta, "ART124121");  /* *** should test in realistic context */
401 
402   zxid_mk_lu_Status(cf, 0, 0, "SC2-dummy", "MSG-dummy", "REF-dummy");
403   st = zxid_mk_tas3_status(cf, 0, 0, 0, "SC2-dummy", "MSG-dummy", "REF-dummy");
404   zxid_get_fault(cf, &sess);
405   zxid_get_tas3_status(cf, &sess);
406 
407   zxid_get_tas3_fault_sc1(cf, 0);
408   zxid_get_tas3_fault_sc2(cf, 0);
409   zxid_get_tas3_fault_comment(cf, 0);
410   zxid_get_tas3_fault_ref(cf, 0);
411   zxid_get_tas3_fault_actor(cf, 0);
412 
413   zxid_get_tas3_status_sc1(cf, 0);
414   zxid_get_tas3_status_sc2(cf, 0);
415   zxid_get_tas3_status_comment(cf, 0);
416   zxid_get_tas3_status_ref(cf, 0);
417   zxid_get_tas3_status_ctlpt(cf, 0);
418 
419   flt = zxid_mk_fault(cf, 0, "actor", "fc1", "fault string", "SC1", "SC2", "MSG", "REF");
420   zxid_get_tas3_fault_sc1(cf, flt);
421   zxid_get_tas3_fault_sc2(cf, flt);
422   zxid_get_tas3_fault_comment(cf, flt);
423   zxid_get_tas3_fault_ref(cf, flt);
424   zxid_get_tas3_fault_actor(cf, flt);
425 
426   zxid_get_tas3_status_sc1(cf, st);
427   zxid_get_tas3_status_sc2(cf, st);
428   zxid_get_tas3_status_comment(cf, st);
429   zxid_get_tas3_status_ref(cf, st);
430   zxid_get_tas3_status_ctlpt(cf, st);
431 
432   /* *** should test in realistic context */
433   zxid_mk_dap_query(cf, 0,
434 		    zxid_mk_dap_test_item(cf, 0,
435 					  zxid_mk_dap_testop(cf, 0, 0, 0, 0, 1, 2, 3, 4, 5),
436 					  0, 0),
437 		    zxid_mk_dap_query_item(cf, 0,
438 					   zxid_mk_dap_select(cf, 0, 0, 0, 0, 0, 1, 0, 0, 0),
439 					   0, 0, 0, 0, 1, 2, 3, 0, 0, 0),
440 		    zxid_mk_dap_subscription(cf, 0, "SUBSID", "#ITEMID",
441 					     zxid_mk_dap_resquery(cf, 0,
442 								   zxid_mk_dap_select(cf, 0, 0, 0, 0, 0, 1, 0, 0, 0),
443 								   0, 0, 0, 0, 1, 0),
444 					     0, 0, 0, 0, 1, 0, 0));
445 
446   zxid_wsf_decor(cf,0,0,0,0);
447   zxid_map_sec_mech(0);
448   zxid_wsc_valid_re_env(cf,0,0,0,0);
449   env = zx_NEW_e_Envelope(cf->ctx, 0);
450   zxid_wsc_valid_re_env(cf,0,0,env,0);
451   zxid_wsf_decor(cf,0,env,0,0);
452   zxid_wsc_valid_re_env(cf,0,0,env,0);
453   printf("covimp ok\n");
454 }
455 
456 /* Called by:  main x8, zxbusd_main, zxbuslist_main, zxbustailf_main, zxcall_main, zxcot_main, zxdecode_main */
opt(int * argc,char *** argv,char *** env)457 void opt(int* argc, char*** argv, char*** env)
458 {
459   if (*argc < 1) goto argerr;
460 
461   while (1) {
462     ++(*argv); --(*argc);
463 
464     if (!(*argc) || ((*argv)[0][0] != '-')) break;
465 
466     switch ((*argv)[0][1]) {
467     case '-': if ((*argv)[0][2]) break;
468       ++(*argv); --(*argc);
469       DD("End of options by --");
470       return;  /* -- ends the options */
471 
472     case 'i': if ((*argv)[0][2]) break;
473       ++(*argv); --(*argc);
474       if (!(*argc)) break;
475       n_iter = atoi((*argv)[0]);
476       continue;
477 
478     case 't': if ((*argv)[0][2]) break;
479       ++(*argv); --(*argc);
480       if (!(*argc)) break;
481       timeout = atoi((*argv)[0]);
482       continue;
483 
484     case 'd':
485       switch ((*argv)[0][2]) {
486       case '\0':
487 	++errmac_debug;
488 	continue;
489       case 'i':  if ((*argv)[0][3]) break;
490 	++(*argv); --(*argc);
491 	if (!(*argc)) break;
492 	strncpy(errmac_instance, (*argv)[0], sizeof(errmac_instance));
493 	continue;
494       }
495       break;
496 
497     case 'v':
498       switch ((*argv)[0][2]) {
499       case '\0':
500 	++verbose;
501 	continue;
502       }
503       break;
504 
505     case 'q':
506       switch ((*argv)[0][2]) {
507       case '\0':
508 	verbose = 0;
509 	continue;
510       }
511       break;
512 
513     case 'e':
514       switch ((*argv)[0][2]) {
515       case 'g': if ((*argv)[0][3] != 'd' || (*argv)[0][4]) break;
516 	++(*argv); --(*argc);
517 	if (!(*argc)) break;
518 	egd_path = (*argv)[0];
519 	continue;
520       }
521       break;
522 
523     case 'r':
524       switch ((*argv)[0][2]) {
525       case '\0':
526 	++(*argv); --(*argc);
527 	if (!(*argc)) break;
528 	switch (atoi((*argv)[0])) {
529 	case 1: test_ibm_cert_problem(); break;
530 	case 2: test_ibm_cert_problem_enc_dec(); break;
531 	case 3: so_enc_dec(); break;
532 	case 4: attribute_sort_test(); break;
533 	case 5: covimp_test(); break;
534 	case 6: a7n_test(); break;
535 	case 7: x509_test(); break;
536 	case 8: timegm_test(); break;
537 	}
538 	exit(0);
539 
540       case 'f':
541 	/*AK_TS(LEAK, 0, "memory leaks enabled");*/
542 #if 1
543 	ERR("*** WARNING: You have turned memory frees to memory leaks. We will (eventually) run out of memory. Using -rf is not recommended. %d\n", 0);
544 #endif
545 	++leak_free;
546 	continue;
547 #if 0
548       case 'e':
549 	if ((*argv)[0][3]) break;
550 	++(*argv); --(*argc);
551 	if ((*argc) < 4) break;
552 	sscanf((*argv)[0], "%i", &abort_funcno);
553 	++(*argv); --(*argc);
554 	sscanf((*argv)[0], "%i", &abort_line);
555 	++(*argv); --(*argc);
556 	sscanf((*argv)[0], "%i", &abort_error_code);
557 	++(*argv); --(*argc);
558 	sscanf((*argv)[0], "%i", &abort_iter);
559 	fprintf(stderr, "Will force core upon %x:%x err=%d iter=%d\n",
560 		abort_funcno, abort_line, abort_error_code, abort_iter);
561 	continue;
562 #endif
563       case 'g':
564 	if ((*argv)[0][3]) break;
565 	++(*argv); --(*argc);
566 	if (!(*argc)) break;
567 	gcthreshold = atoi((*argv)[0]);
568 	if (!gcthreshold)
569 	  ERR("*** WARNING: You have disabled garbage collection. This may lead to increased memory consumption for scripts that handle a lot of PDUs or run for long time. Using `-rg 0' is not recommended. %d\n", 0);
570 	continue;
571       case 'a':
572 	if ((*argv)[0][3] == 0) {
573 	  /*AK_TS(ASSERT_NONFATAL, 0, "assert nonfatal enabled");*/
574 #if 1
575 	  ERR("*** WARNING: YOU HAVE TURNED ASSERTS OFF USING -ra FLAG. THIS MEANS THAT YOU WILL NOT BE ABLE TO OBTAIN ANY SUPPORT. IF PROGRAM NOW TRIES TO ASSERT IT MAY MYSTERIOUSLY AND UNPREDICTABLY CRASH INSTEAD, AND NOBODY WILL BE ABLE TO FIGURE OUT WHAT WENT WRONG OR HOW MUCH DAMAGE MAY BE DONE. USING -ra IS NOT RECOMMENDED. %d\n", assert_nonfatal);
576 #endif
577 	  ++assert_nonfatal;
578 	  continue;
579 	}
580 	if (!strcmp((*argv)[0],"-rand")) {
581 	  ++(*argv); --(*argc);
582 	  if (!(*argc)) break;
583 	  rand_path = (*argv)[0];
584 	  continue;
585 	}
586 	break;
587       }
588       break;
589 
590     case 'w':
591       switch ((*argv)[0][2]) {
592       case 'o': if ((*argv)[0][3]) break;
593 	++(*argv); --(*argc);
594 	if (!(*argc)) break;
595 	wo_path = (*argv)[0];
596 	continue;
597       }
598       break;
599 
600 #ifndef MINGW
601     case 'k':
602       switch ((*argv)[0][2]) {
603       case '\0':
604 	++(*argv); --(*argc);
605 	if (!(*argc)) break;
606 	read_all_fd(atoi((*argv)[0]), symmetric_key, sizeof(symmetric_key), &symmetric_key_len);
607 	D("Got %d characters of symmetric key", symmetric_key_len);
608 	continue;
609       }
610       break;
611 #endif
612 
613     case 'c': if ((*argv)[0][2]) break;
614       ++(*argv); --(*argc);
615       if (!(*argc)) break;
616 #ifndef ENCRYPTION
617       ERR("Encryption not compiled in. %d",0);
618 #endif
619       continue;
620 
621     case 'u':
622       switch ((*argv)[0][2]) {
623       case 'i': if ((*argv)[0][3] != 'd' || (*argv)[0][4]) break;
624 	++(*argv); --(*argc);
625 	if (!(*argc)) break;
626 	sscanf((*argv)[0], "%i:%i", &drop_uid, &drop_gid);
627 	continue;
628       }
629       break;
630 
631     case 'l':
632       switch ((*argv)[0][2]) {
633       case 'i':
634 	if (!strcmp((*argv)[0],"-license")) {
635 	  extern char* license;
636 	  fprintf(stderr, "%s", license);
637 	  exit(0);
638 	}
639 	break;
640       }
641       break;
642 
643     }
644     /* fall thru means unrecognized flag */
645     if (*argc)
646       fprintf(stderr, "Unrecognized flag `%s'\n", (*argv)[0]);
647   argerr:
648     fprintf(stderr, "%s", help);
649     exit(3);
650   }
651 }
652 
653 /* ============== M A I N ============== */
654 
655 /* Called by: */
main(int argc,char ** argv,char ** env)656 int main(int argc, char** argv, char** env)
657 {
658   struct zx_ctx ctx;
659   struct zx_root_s* r;
660   int got_all, len_wo;
661   char wo_out[256*1024];
662   char* wo_p;
663   opt(&argc, &argv, &env);
664 
665   len_wo = read_all_fd(fdstdin, buf, sizeof(buf)-1, &got_all);
666   if (got_all <= 0) DIE("Missing data");
667   buf[got_all] = 0;
668 
669   D("Decoding %d chars, n_iter(%d)\n", got_all, n_iter);
670 
671   for (; n_iter; --n_iter) {
672     ZERO(&ctx, sizeof(ctx));
673     r = zx_dec_zx_root(&ctx, got_all, buf, "zxencdectest main");  /* n_decode=1000 ?!? */
674     if (!r)
675       DIE("Decode failure");
676 
677     len_wo = zx_LEN_WO_any_elem(&ctx, &r->gg);
678     D("Enc wo len %d chars", len_wo);
679 
680     ctx.bas = wo_out;
681     wo_p = zx_ENC_WO_any_elem(&ctx, &r->gg, wo_out);
682     if (!wo_p)
683       DIE("encoding error");
684 
685     zx_free_elem(&ctx, &r->gg, 0);
686   }
687 
688   if (got_all != len_wo)
689     printf("Original and WO are different lengths %d != %d\n", got_all, len_wo);
690 
691   if (memcmp(buf, wo_out, MIN(got_all, len_wo)))
692     printf("Original and WO differ.\n");
693 
694   if (wo_p - wo_out != len_wo)
695     ERR("WO encode length mismatch %d vs %d (len)", ((int)(wo_p - wo_out)), len_wo);
696   printf("Re-encoded result WO (len=%d):\n%.*s\n\n", len_wo, len_wo, wo_out);
697 
698   if (wo_path)
699     write_all_path("WO", "%s", wo_path, 0, len_wo, wo_out);
700   return 0;
701 }
702 
703 /* EOF  --  zxencdectest.c */
704