Browse Source

Import upstream version 10

Nathaniel McCallum 3 years ago
commit
1472d5ebaa
100 changed files with 48697 additions and 0 deletions
  1. 175 0
      COPYING
  2. 4 0
      Makefile.am
  3. 860 0
      Makefile.in
  4. 10528 0
      aclocal.m4
  5. 27 0
      cmd/Makefile.am
  6. 735 0
      cmd/Makefile.in
  7. 151 0
      cmd/alg.c
  8. 32 0
      cmd/b64/b64.h
  9. 95 0
      cmd/b64/dec.c
  10. 94 0
      cmd/b64/enc.c
  11. 695 0
      cmd/fmt.c
  12. 537 0
      cmd/jose.c
  13. 113 0
      cmd/jose.h
  14. 219 0
      cmd/jwe/dec.c
  15. 344 0
      cmd/jwe/enc.c
  16. 180 0
      cmd/jwe/fmt.c
  17. 59 0
      cmd/jwe/jwe.h
  18. 77 0
      cmd/jwe/pwd.h
  19. 70 0
      cmd/jwk/eql.c
  20. 144 0
      cmd/jwk/exc.c
  21. 114 0
      cmd/jwk/gen.c
  22. 38 0
      cmd/jwk/jwk.h
  23. 107 0
      cmd/jwk/pub.c
  24. 188 0
      cmd/jwk/thp.c
  25. 198 0
      cmd/jwk/use.c
  26. 154 0
      cmd/jws/fmt.c
  27. 112 0
      cmd/jws/jws.h
  28. 244 0
      cmd/jws/sig.c
  29. 172 0
      cmd/jws/ver.c
  30. 348 0
      compile
  31. 1476 0
      config.guess
  32. 1836 0
      config.sub
  33. 14785 0
      configure
  34. 65 0
      configure.ac
  35. 791 0
      depcomp
  36. 28 0
      doc/Makefile.am
  37. 594 0
      doc/Makefile.in
  38. 207 0
      doc/doxygen/man/man3/jose_b64.3
  39. 158 0
      doc/doxygen/man/man3/jose_cfg.3
  40. 219 0
      doc/doxygen/man/man3/jose_io.3
  41. 97 0
      doc/doxygen/man/man3/jose_io_t.3
  42. 514 0
      doc/doxygen/man/man3/jose_jwe.3
  43. 237 0
      doc/doxygen/man/man3/jose_jwk.3
  44. 233 0
      doc/doxygen/man/man3/jose_jws.3
  45. 48 0
      doc/ronn/jose-alg.1
  46. 51 0
      doc/ronn/jose-b64-dec.1
  47. 51 0
      doc/ronn/jose-b64-enc.1
  48. 262 0
      doc/ronn/jose-fmt.1
  49. 111 0
      doc/ronn/jose-jwe-dec.1
  50. 141 0
      doc/ronn/jose-jwe-enc.1
  51. 101 0
      doc/ronn/jose-jwe-fmt.1
  52. 92 0
      doc/ronn/jose-jwk-exc.1
  53. 112 0
      doc/ronn/jose-jwk-gen.1
  54. 66 0
      doc/ronn/jose-jwk-pub.1
  55. 95 0
      doc/ronn/jose-jwk-thp.1
  56. 111 0
      doc/ronn/jose-jwk-use.1
  57. 101 0
      doc/ronn/jose-jws-fmt.1
  58. 141 0
      doc/ronn/jose-jws-sig.1
  59. 106 0
      doc/ronn/jose-jws-ver.1
  60. 98 0
      doc/ronn/jose.1
  61. 501 0
      install-sh
  62. 12 0
      jose.pc.in
  63. 10 0
      jose/Makefile.am
  64. 578 0
      jose/Makefile.in
  65. 138 0
      jose/b64.h
  66. 137 0
      jose/cfg.h
  67. 198 0
      jose/io.h
  68. 43 0
      jose/jose.h
  69. 43 0
      jose/jose.h.in
  70. 446 0
      jose/jwe.h
  71. 198 0
      jose/jwk.h
  72. 197 0
      jose/jws.h
  73. 45 0
      jose/openssl.h
  74. 57 0
      lib/Makefile.am
  75. 807 0
      lib/Makefile.in
  76. 390 0
      lib/b64.c
  77. 133 0
      lib/cfg.c
  78. 62 0
      lib/hooks.c
  79. 186 0
      lib/hooks.h
  80. 79 0
      lib/hsh.c
  81. 82 0
      lib/hsh.h
  82. 332 0
      lib/io.c
  83. 527 0
      lib/jwe.c
  84. 490 0
      lib/jwk.c
  85. 317 0
      lib/jws.c
  86. 71 0
      lib/libjose.map
  87. 49 0
      lib/misc.c
  88. 32 0
      lib/misc.h
  89. 443 0
      lib/openssl/aescbch.c
  90. 380 0
      lib/openssl/aesgcm.c
  91. 276 0
      lib/openssl/aesgcmkw.c
  92. 268 0
      lib/openssl/aeskw.c
  93. 239 0
      lib/openssl/compat.c
  94. 75 0
      lib/openssl/compat.h
  95. 106 0
      lib/openssl/dir.c
  96. 77 0
      lib/openssl/ec.c
  97. 139 0
      lib/openssl/ecdh.c
  98. 483 0
      lib/openssl/ecdhes.c
  99. 310 0
      lib/openssl/ecdsa.c
  100. 0 0
      lib/openssl/ecmr.c

+ 175 - 0
COPYING

@@ -0,0 +1,175 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.

+ 4 - 0
Makefile.am

@@ -0,0 +1,4 @@
+SUBDIRS = . jose lib cmd tests doc
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = jose.pc

+ 860 - 0
Makefile.in

@@ -0,0 +1,860 @@
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
+	$(am__configure_deps) $(am__DIST_COMMON)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES = jose.pc
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
+DATA = $(pkgconfig_DATA)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/jose.pc.in COPYING \
+	compile config.guess config.sub install-sh ltmain.sh missing
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+GZIP_ENV = --best
+DIST_ARCHIVES = $(distdir).tar.bz2
+DIST_TARGETS = dist-bzip2
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+JOSE_CFLAGS = @JOSE_CFLAGS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENMP_CFLAGS = @OPENMP_CFLAGS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+jansson_CFLAGS = @jansson_CFLAGS@
+jansson_LIBS = @jansson_LIBS@
+libcrypto_CFLAGS = @libcrypto_CFLAGS@
+libcrypto_LIBS = @libcrypto_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+zlib_CFLAGS = @zlib_CFLAGS@
+zlib_LIBS = @zlib_LIBS@
+SUBDIRS = . jose lib cmd tests doc
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = jose.pc
+all: all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+	@:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	$(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+jose.pc: $(top_builddir)/config.status $(srcdir)/jose.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+install-pkgconfigDATA: $(pkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+	fi; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
+	done
+
+uninstall-pkgconfigDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+	test ! -s cscope.files \
+	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
+	$(am__post_remove_distdir)
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__post_remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	$(am__post_remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	$(am__post_remove_distdir)
+
+dist-tarZ: distdir
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__post_remove_distdir)
+
+dist-shar: distdir
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+	shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
+	$(am__post_remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__post_remove_distdir)
+
+dist dist-all:
+	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+	$(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+	*.tar.xz*) \
+	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
+	chmod a-w $(distdir)
+	test -d $(distdir)/_build || exit 0; \
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && am__cwd=`pwd` \
+	  && $(am__cd) $(distdir)/_build/sub \
+	  && ../../configure \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	    --srcdir=../.. --prefix="$$dc_install_base" \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+	  && cd "$$am__cwd" \
+	  || exit 1
+	$(am__post_remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile $(DATA)
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool \
+	distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-pkgconfigDATA
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-pkgconfigDATA
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+	am--refresh check check-am clean clean-cscope clean-generic \
+	clean-libtool cscope cscopelist-am ctags ctags-am dist \
+	dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
+	dist-xz dist-zip distcheck distclean distclean-generic \
+	distclean-libtool distclean-tags distcleancheck distdir \
+	distuninstallcheck dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-pkgconfigDATA install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic \
+	mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am uninstall-pkgconfigDATA
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

File diff suppressed because it is too large
+ 10528 - 0
aclocal.m4


+ 27 - 0
cmd/Makefile.am

@@ -0,0 +1,27 @@
+AM_CFLAGS = @JOSE_CFLAGS@ @jansson_CFLAGS@ -I$(top_srcdir) -I$(top_builddir)
+LDFLAGS += ../lib/libjose.la @jansson_LIBS@
+
+bin_PROGRAMS = jose
+jose_SOURCES = \
+    jose.c jose.h \
+    b64/b64.h \
+    b64/dec.c \
+    b64/enc.c \
+    jwk/jwk.h \
+    jwk/eql.c \
+    jwk/exc.c \
+    jwk/gen.c \
+    jwk/pub.c \
+    jwk/thp.c \
+    jwk/use.c \
+    jws/jws.h \
+    jws/fmt.c \
+    jws/sig.c \
+    jws/ver.c \
+    jwe/jwe.h \
+    jwe/pwd.h \
+    jwe/fmt.c \
+    jwe/dec.c \
+    jwe/enc.c \
+    alg.c \
+    fmt.c

+ 735 - 0
cmd/Makefile.in

@@ -0,0 +1,735 @@
+# Makefile.in generated by automake 1.15.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2017 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+  if test -z '$(MAKELEVEL)'; then \
+    false; \
+  elif test -n '$(MAKE_HOST)'; then \
+    true; \
+  elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+    true; \
+  else \
+    false; \
+  fi; \
+}
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+bin_PROGRAMS = jose$(EXEEXT)
+subdir = cmd
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+PROGRAMS = $(bin_PROGRAMS)
+am__dirstamp = $(am__leading_dot)dirstamp
+am_jose_OBJECTS = jose.$(OBJEXT) b64/dec.$(OBJEXT) b64/enc.$(OBJEXT) \
+	jwk/eql.$(OBJEXT) jwk/exc.$(OBJEXT) jwk/gen.$(OBJEXT) \
+	jwk/pub.$(OBJEXT) jwk/thp.$(OBJEXT) jwk/use.$(OBJEXT) \
+	jws/fmt.$(OBJEXT) jws/sig.$(OBJEXT) jws/ver.$(OBJEXT) \
+	jwe/fmt.$(OBJEXT) jwe/dec.$(OBJEXT) jwe/enc.$(OBJEXT) \
+	alg.$(OBJEXT) fmt.$(OBJEXT)
+jose_OBJECTS = $(am_jose_OBJECTS)
+jose_LDADD = $(LDADD)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 = 
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo "  CC      " $@;
+am__v_CC_1 = 
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo "  CCLD    " $@;
+am__v_CCLD_1 = 
+SOURCES = $(jose_SOURCES)
+DIST_SOURCES = $(jose_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+JOSE_CFLAGS = @JOSE_CFLAGS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@ ../lib/libjose.la @jansson_LIBS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OPENMP_CFLAGS = @OPENMP_CFLAGS@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+jansson_CFLAGS = @jansson_CFLAGS@
+jansson_LIBS = @jansson_LIBS@
+libcrypto_CFLAGS = @libcrypto_CFLAGS@
+libcrypto_LIBS = @libcrypto_LIBS@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+zlib_CFLAGS = @zlib_CFLAGS@
+zlib_LIBS = @zlib_LIBS@
+AM_CFLAGS = @JOSE_CFLAGS@ @jansson_CFLAGS@ -I$(top_srcdir) -I$(top_builddir)
+jose_SOURCES = \
+    jose.c jose.h \
+    b64/b64.h \
+    b64/dec.c \
+    b64/enc.c \
+    jwk/jwk.h \
+    jwk/eql.c \
+    jwk/exc.c \
+    jwk/gen.c \
+    jwk/pub.c \
+    jwk/thp.c \
+    jwk/use.c \
+    jws/jws.h \
+    jws/fmt.c \
+    jws/sig.c \
+    jws/ver.c \
+    jwe/jwe.h \
+    jwe/pwd.h \
+    jwe/fmt.c \
+    jwe/dec.c \
+    jwe/enc.c \
+    alg.c \
+    fmt.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign cmd/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign cmd/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+	fi; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p \
+	 || test -f $$p1 \
+	  ; then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' \
+	    -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' \
+	`; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+	@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+b64/$(am__dirstamp):
+	@$(MKDIR_P) b64
+	@: > b64/$(am__dirstamp)
+b64/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) b64/$(DEPDIR)
+	@: > b64/$(DEPDIR)/$(am__dirstamp)
+b64/dec.$(OBJEXT): b64/$(am__dirstamp) b64/$(DEPDIR)/$(am__dirstamp)
+b64/enc.$(OBJEXT): b64/$(am__dirstamp) b64/$(DEPDIR)/$(am__dirstamp)
+jwk/$(am__dirstamp):
+	@$(MKDIR_P) jwk
+	@: > jwk/$(am__dirstamp)
+jwk/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) jwk/$(DEPDIR)
+	@: > jwk/$(DEPDIR)/$(am__dirstamp)
+jwk/eql.$(OBJEXT): jwk/$(am__dirstamp) jwk/$(DEPDIR)/$(am__dirstamp)
+jwk/exc.$(OBJEXT): jwk/$(am__dirstamp) jwk/$(DEPDIR)/$(am__dirstamp)
+jwk/gen.$(OBJEXT): jwk/$(am__dirstamp) jwk/$(DEPDIR)/$(am__dirstamp)
+jwk/pub.$(OBJEXT): jwk/$(am__dirstamp) jwk/$(DEPDIR)/$(am__dirstamp)
+jwk/thp.$(OBJEXT): jwk/$(am__dirstamp) jwk/$(DEPDIR)/$(am__dirstamp)
+jwk/use.$(OBJEXT): jwk/$(am__dirstamp) jwk/$(DEPDIR)/$(am__dirstamp)
+jws/$(am__dirstamp):
+	@$(MKDIR_P) jws
+	@: > jws/$(am__dirstamp)
+jws/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) jws/$(DEPDIR)
+	@: > jws/$(DEPDIR)/$(am__dirstamp)
+jws/fmt.$(OBJEXT): jws/$(am__dirstamp) jws/$(DEPDIR)/$(am__dirstamp)
+jws/sig.$(OBJEXT): jws/$(am__dirstamp) jws/$(DEPDIR)/$(am__dirstamp)
+jws/ver.$(OBJEXT): jws/$(am__dirstamp) jws/$(DEPDIR)/$(am__dirstamp)
+jwe/$(am__dirstamp):
+	@$(MKDIR_P) jwe
+	@: > jwe/$(am__dirstamp)
+jwe/$(DEPDIR)/$(am__dirstamp):
+	@$(MKDIR_P) jwe/$(DEPDIR)
+	@: > jwe/$(DEPDIR)/$(am__dirstamp)
+jwe/fmt.$(OBJEXT): jwe/$(am__dirstamp) jwe/$(DEPDIR)/$(am__dirstamp)
+jwe/dec.$(OBJEXT): jwe/$(am__dirstamp) jwe/$(DEPDIR)/$(am__dirstamp)
+jwe/enc.$(OBJEXT): jwe/$(am__dirstamp) jwe/$(DEPDIR)/$(am__dirstamp)
+
+jose$(EXEEXT): $(jose_OBJECTS) $(jose_DEPENDENCIES) $(EXTRA_jose_DEPENDENCIES) 
+	@rm -f jose$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(jose_OBJECTS) $(jose_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+	-rm -f b64/*.$(OBJEXT)
+	-rm -f jwe/*.$(OBJEXT)
+	-rm -f jwk/*.$(OBJEXT)
+	-rm -f jws/*.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alg.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jose.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@b64/$(DEPDIR)/dec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@b64/$(DEPDIR)/enc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@jwe/$(DEPDIR)/dec.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@jwe/$(DEPDIR)/enc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@jwe/$(DEPDIR)/fmt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@jwk/$(DEPDIR)/eql.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@jwk/$(DEPDIR)/exc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@jwk/$(DEPDIR)/gen.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@jwk/$(DEPDIR)/pub.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@jwk/$(DEPDIR)/thp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@jwk/$(DEPDIR)/use.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@jws/$(DEPDIR)/fmt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@jws/$(DEPDIR)/sig.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@jws/$(DEPDIR)/ver.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+	for dir in "$(DESTDIR)$(bindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-rm -f b64/$(DEPDIR)/$(am__dirstamp)
+	-rm -f b64/$(am__dirstamp)
+	-rm -f jwe/$(DEPDIR)/$(am__dirstamp)
+	-rm -f jwe/$(am__dirstamp)
+	-rm -f jwk/$(DEPDIR)/$(am__dirstamp)
+	-rm -f jwk/$(am__dirstamp)
+	-rm -f jws/$(DEPDIR)/$(am__dirstamp)
+	-rm -f jws/$(am__dirstamp)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR) b64/$(DEPDIR) jwe/$(DEPDIR) jwk/$(DEPDIR) jws/$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR) b64/$(DEPDIR) jwe/$(DEPDIR) jwk/$(DEPDIR) jws/$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+	clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \
+	ctags ctags-am distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-binPROGRAMS \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-am uninstall uninstall-am uninstall-binPROGRAMS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:

+ 151 - 0
cmd/alg.c

@@ -0,0 +1,151 @@
+/* vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: */
+/*
+ * Copyright 2016 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jose.h"
+#include "../lib/hooks.h"
+#include <string.h>
+
+#define SUMMARY "Lists all supported algorithms"
+
+typedef struct {
+    json_t *kinds;
+} jcmd_opt_t;
+
+static const char *prefix = "jose alg [-k KIND]\n\n" SUMMARY;
+
+static const struct {
+    const char *name;
+    jose_hook_alg_kind_t kind;
+} kinds[] = {
+    { "hash", JOSE_HOOK_ALG_KIND_HASH },
+    { "sign", JOSE_HOOK_ALG_KIND_SIGN },
+    { "wrap", JOSE_HOOK_ALG_KIND_WRAP },
+    { "encr", JOSE_HOOK_ALG_KIND_ENCR },
+    { "comp", JOSE_HOOK_ALG_KIND_COMP },
+    { "exch", JOSE_HOOK_ALG_KIND_EXCH },
+    {}
+};
+
+static jose_hook_alg_kind_t
+name2kind(const char *name)
+{
+    for (size_t i = 0; name && kinds[i].name; i++) {
+        if (strcmp(name, kinds[i].name) == 0)
+            return kinds[i].kind;
+    }
+
+    return JOSE_HOOK_ALG_KIND_NONE;
+}
+
+static bool
+opt_set_kind(const jcmd_cfg_t *cfg, void *vopt, const char *arg)
+{
+    json_t **all = vopt;
+
+    if (!*all)
+        *all = json_array();
+
+    if (strcmp(arg, "?") == 0) {
+        for (size_t i = 0; kinds[i].name; i++)
+            fprintf(stdout, "%s\n", kinds[i].name);
+
+        exit(EXIT_SUCCESS);
+    }
+
+    if (name2kind(arg) == JOSE_HOOK_ALG_KIND_NONE)
+        return false;
+
+    return json_array_append_new(*all, json_string(arg)) >= 0;
+}
+
+static const jcmd_doc_t doc_kind[] = {
+    { .arg = "KIND", .doc = "Restrict algorithm list to a certain kind" },
+    { .arg = "?",    .doc = "List valid algorithm kinds" },
+    {}
+};
+
+static const jcmd_cfg_t cfgs[] = {
+    {
+        .opt = { "kind", required_argument, .val = 'k' },
+        .off = offsetof(jcmd_opt_t, kinds),
+        .set = opt_set_kind,
+        .doc = doc_kind
+    },
+    {}
+};
+
+static void
+jcmd_opt_cleanup(jcmd_opt_t *opt)
+{
+    json_decref(opt->kinds);
+}
+
+static int
+cmp(const void *a, const void *b)
+{
+    const char *const *aa = a;
+    const char *const *bb = b;
+    return strcasecmp(*aa, *bb);
+}
+
+static bool
+filter(const jcmd_opt_t *opt, jose_hook_alg_kind_t kind)
+{
+    size_t size = 0;
+
+    size = json_array_size(opt->kinds);
+    if (size == 0)
+        return true;
+
+    for (size_t i = 0; i < size; i++) {
+        if (kind == name2kind(json_string_value(json_array_get(opt->kinds, i))))
+            return true;
+    }
+
+    return false;
+}
+
+static int
+jcmd_alg(int argc, char *argv[])
+{
+    jcmd_opt_auto_t opt = {};
+    size_t len = 0;
+
+    if (!jcmd_opt_parse(argc, argv, cfgs, &opt, prefix))
+        return EXIT_FAILURE;
+
+    for (const jose_hook_alg_t *a = jose_hook_alg_list(); a; a = a->next) {
+        if (filter(&opt, a->kind))
+            len++;
+    }
+
+    const char *names[len];
+
+    for (const jose_hook_alg_t *a = jose_hook_alg_list(); a; a = a->next) {
+        if (filter(&opt, a->kind))
+            names[--len] = a->name;
+    }
+
+    qsort(names, sizeof(names) / sizeof(*names), sizeof(*names), cmp);
+
+    for (size_t i = 0; i < sizeof(names) / sizeof(*names); i++)
+        fprintf(stdout, "%s\n", names[i]);
+
+    return EXIT_SUCCESS;
+}
+
+JCMD_REGISTER(SUMMARY, jcmd_alg, "alg")

+ 32 - 0
cmd/b64/b64.h

@@ -0,0 +1,32 @@
+/* vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: */
+/*
+ * Copyright 2017 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../jose.h"
+
+#define jcmd_b64_opt_auto_t __JCMD_AUTO(jcmd_b64_opt)
+
+typedef struct {
+    FILE *input;
+    FILE *output;
+} jcmd_b64_opt_t;
+
+static inline void
+jcmd_b64_opt_cleanup(jcmd_b64_opt_t *opt)
+{
+    jcmd_file_cleanup(&opt->input);
+    jcmd_file_cleanup(&opt->output);
+}

+ 95 - 0
cmd/b64/dec.c

@@ -0,0 +1,95 @@
+/* vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: */
+/*
+ * Copyright 2017 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "b64.h"
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+
+#define SUMMARY "Decodes URL-safe Base64 data to binary"
+
+static const char *prefix = "jose b64 dec -i B64 [-O BIN]\n\n" SUMMARY;
+
+static const jcmd_doc_t doc_input[] = {
+    { .arg = "FILE", .doc="Read Base64 (URL-safe) data from FILE" },
+    { .arg = "-",    .doc="Read Base64 (URL-safe) data from standard input" },
+    {}
+};
+
+static const jcmd_doc_t doc_output[] = {
+    { .arg = "FILE", .doc="Write binary data to FILE" },
+    { .arg = "-",    .doc="Write binary data to standard output" },
+    {}
+};
+
+static const jcmd_cfg_t cfgs[] = {
+    {
+        .opt = { "base64", required_argument, .val = 'i' },
+        .off = offsetof(jcmd_b64_opt_t, input),
+        .set = jcmd_opt_set_ifile,
+        .doc = doc_input,
+    },
+    {
+        .opt = { "binary", required_argument, .val = 'O' },
+        .off = offsetof(jcmd_b64_opt_t, output),
+        .set = jcmd_opt_set_ofile,
+        .doc = doc_output,
+        .def = "-",
+    },
+    {}
+};
+
+static int
+jcmd_b64_dec(int argc, char *argv[])
+{
+    jcmd_b64_opt_auto_t opt = {};
+    jose_io_auto_t *b64 = NULL;
+    jose_io_auto_t *out = NULL;
+
+    if (!jcmd_opt_parse(argc, argv, cfgs, &opt, prefix))
+        return EXIT_FAILURE;
+
+    if (!opt.input) {
+        fprintf(stderr, "Input not specified!\n");
+        return EXIT_FAILURE;
+    }
+
+    out = jose_io_file(NULL, opt.output);
+    if (!out)
+        return EXIT_FAILURE;
+
+    b64 = jose_b64_dec_io(out);
+    if (!b64)
+        return EXIT_FAILURE;
+
+    for (int c = fgetc(opt.input); c != EOF; c = fgetc(opt.input)) {
+        uint8_t b = c;
+
+        if (isspace(c))
+            continue;
+
+        if (!b64->feed(b64, &b, sizeof(b)))
+            return EXIT_FAILURE;
+    }
+
+    if (!b64->done(b64))
+        return EXIT_FAILURE;
+
+    return EXIT_SUCCESS;
+}
+
+JCMD_REGISTER(SUMMARY, jcmd_b64_dec, "b64", "dec")

+ 94 - 0
cmd/b64/enc.c

@@ -0,0 +1,94 @@
+/* vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: */
+/*
+ * Copyright 2017 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "b64.h"
+#include <string.h>
+#include <unistd.h>
+
+#define SUMMARY "Encodes binary data to URL-safe Base64"
+
+static const char *prefix = "jose b64 enc -I BIN [-o B64]\n\n" SUMMARY;
+
+static const jcmd_doc_t doc_input[] = {
+    { .arg = "FILE", .doc="Read binary data from FILE" },
+    { .arg = "-",    .doc="Read binary data from standard input" },
+    {}
+};
+
+static const jcmd_doc_t doc_output[] = {
+    { .arg = "FILE", .doc="Write Base64 (URL-safe) to FILE" },
+    { .arg = "-",    .doc="Write Base64 (URL-safe) to standard output" },
+    {}
+};
+
+static const jcmd_cfg_t cfgs[] = {
+    {
+        .opt = { "binary", required_argument, .val = 'I' },
+        .off = offsetof(jcmd_b64_opt_t, input),
+        .set = jcmd_opt_set_ifile,
+        .doc = doc_input,
+    },
+    {
+        .opt = { "base64", required_argument, .val = 'o' },
+        .off = offsetof(jcmd_b64_opt_t, output),
+        .set = jcmd_opt_set_ofile,
+        .doc = doc_output,
+        .def = "-",
+    },
+    {}
+};
+
+static int
+jcmd_b64_enc(int argc, char *argv[])
+{
+    jcmd_b64_opt_auto_t opt = {};
+    jose_io_auto_t *b64 = NULL;
+    jose_io_auto_t *out = NULL;
+
+    if (!jcmd_opt_parse(argc, argv, cfgs, &opt, prefix))
+        return EXIT_FAILURE;
+
+    if (!opt.input) {
+        fprintf(stderr, "Input not specified!\n");
+        return EXIT_FAILURE;
+    }
+
+    out = jose_io_file(NULL, opt.output);
+    if (!out)
+        return EXIT_FAILURE;
+
+    b64 = jose_b64_enc_io(out);
+    if (!b64)
+        return EXIT_FAILURE;
+
+    for (int c = fgetc(opt.input); c != EOF; c = fgetc(opt.input)) {
+        uint8_t b = c;
+
+        if (!b64->feed(b64, &b, sizeof(b)))
+            return EXIT_FAILURE;
+    }
+
+    if (!b64->done(b64))
+        return EXIT_FAILURE;
+
+    if (isatty(fileno(opt.output)))
+        fprintf(opt.output, "\n");
+
+    return EXIT_SUCCESS;
+}
+
+JCMD_REGISTER(SUMMARY, jcmd_b64_enc, "b64", "enc")

+ 695 - 0
cmd/fmt.c

@@ -0,0 +1,695 @@
+/* vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: */
+/*
+ * Copyright 2017 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jose.h"
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <ctype.h>
+
+#define SUMMARY "Converts JSON between serialization formats"
+#define JAIN json_array_insert_new
+
+#ifdef __MINGW32__
+#define sscanf __mingw_sscanf
+#endif
+
+static const char *prefix = "jose fmt [OPTIONS]\n\n" SUMMARY;
+
+typedef struct {
+    json_t *args;
+} jcmd_opt_t;
+
+static size_t
+convert_int(const json_t *arr, const char *arg)
+{
+    ssize_t indx = 0;
+
+    if (sscanf(arg, "%zd", &indx) != 1)
+        return SIZE_MAX;
+
+    if (indx < 0)
+        indx += json_array_size(arr);
+
+    if (indx < 0)
+        return SIZE_MAX;
+
+    return indx;
+}
+
+static void
+jcmd_opt_cleanup(jcmd_opt_t *opt)
+{
+    json_decref(opt->args);
+}
+
+static bool
+cmd_output(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    const int wflags = JSON_ENCODE_ANY | JSON_COMPACT | JSON_SORT_KEYS;
+    const char *s = json_string_value(arg);
+    FILE *file = NULL;
+    bool ret = false;
+
+    if (strcmp(s, "-") == 0)
+        file = stdout;
+    else
+        file = fopen(s, "w");
+    if (!file)
+        return false;
+
+    if (json_dumpf(cur, file, wflags) < 0)
+        goto egress;
+
+    if (isatty(fileno(file)) && fwrite("\n", 1, 1, file) != 1)
+        goto egress;
+
+    ret = true;
+
+egress:
+    if (strcmp(s, "-") != 0)
+        fclose(file);
+    return ret;
+}
+
+static bool
+cmd_foreach(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    const int wflags = JSON_ENCODE_ANY | JSON_COMPACT | JSON_SORT_KEYS;
+    const char *s = json_string_value(arg);
+    FILE *file = NULL;
+    bool ret = false;
+
+    if (!json_is_array(cur) && !json_is_object(cur))
+        return false;
+
+    if (strcmp(s, "-") == 0)
+        file = stdout;
+    else
+        file = fopen(s, "w");
+    if (!file)
+        return false;
+
+    if (json_is_array(cur)) {
+        json_t *v = NULL;
+        size_t i = 0;
+
+        json_array_foreach(cur, i, v) {
+            if (json_dumpf(v, file, wflags) < 0 ||
+                fprintf(file, "\n") < 0)
+                goto egress;
+        }
+    } else if (json_is_object(cur)) {
+        const char *k = NULL;
+        json_t *v = NULL;
+
+        json_object_foreach(cur, k, v) {
+            if (fprintf(file, "%s=", k) < 0 ||
+                json_dumpf(v, file, wflags) < 0 ||
+                fprintf(file, "\n") < 0)
+                goto egress;
+        }
+    }
+
+    ret = true;
+
+egress:
+    if (strcmp(s, "-") != 0)
+        fclose(file);
+    return ret;
+}
+
+static bool
+cmd_unquote(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    const char *s = json_string_value(arg);
+    FILE *file = NULL;
+    bool ret = false;
+
+    if (!json_is_string(cur))
+        return false;
+
+    if (strcmp(s, "-") == 0)
+        return fprintf(stdout, "%s\n", json_string_value(cur)) >= 0;
+
+    file = fopen(s, "w");
+    if (!file)
+        return false;
+
+    ret = fprintf(file, "%s\n", json_string_value(cur)) >= 0;
+    fclose(file);
+    return ret;
+}
+
+static bool
+cmd_move(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    json_int_t i = json_integer_value(arg);
+
+    if (json_array_insert(stk, i + 1, cur) < 0)
+        return false;
+
+    if (json_array_remove(stk, 0) < 0)
+        return false;
+
+    return true;
+}
+
+static bool
+cmd_trunc(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    size_t i = json_integer_value(arg);
+    size_t s;
+
+    for (s = json_array_size(cur); s > i; s--) {
+        if (json_array_remove(cur, s - 1) < 0)
+            return false;
+    }
+
+    return true;
+}
+
+static bool
+cmd_insert(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    size_t i = json_integer_value(arg);
+    return json_array_insert(lst, i, cur) >= 0;
+}
+
+static bool
+cmd_append(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    if (json_is_array(lst))
+        return json_array_append(lst, cur) >= 0;
+
+    if (json_is_object(lst))
+        return json_object_update_missing(lst, cur) >= 0;
+
+    return false;
+}
+
+static bool
+cmd_extend(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    if (json_is_array(lst))
+        return json_array_extend(lst, cur) >= 0;
+
+    if (json_is_object(lst))
+        return json_object_update(lst, cur) >= 0;
+
+    return false;
+}
+
+static bool
+cmd_delete(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    const char *s = json_string_value(arg);
+
+    if (json_is_array(cur)) {
+        size_t indx;
+
+        indx = convert_int(cur, s);
+        if (indx == SIZE_MAX)
+            return false;
+
+        return json_array_remove(cur, indx) >= 0;
+    }
+
+    if (json_is_object(cur))
+        return json_object_del(cur, s) >= 0;
+
+    return false;
+}
+
+static bool
+cmd_length(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    size_t count = 0;
+
+    if (json_is_array(cur))
+        count = json_array_size(cur);
+    else if (json_is_object(cur))
+        count = json_object_size(cur);
+    else if (json_is_string(cur))
+        count = json_string_length(cur);
+    else
+        return false;
+
+    return json_array_insert_new(stk, 0, json_integer(count)) >= 0;
+}
+
+static bool
+cmd_empty(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    if (json_is_array(cur))
+        return json_array_clear(cur) >= 0;
+
+    if (json_is_object(cur))
+        return json_object_clear(cur) >= 0;
+
+    return false;
+}
+
+static bool
+cmd_get(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    const char *s = json_string_value(arg);
+    json_t *v = NULL;
+
+    if (json_is_array(cur)) {
+        size_t indx;
+
+        indx = convert_int(cur, s);
+        if (indx == SIZE_MAX)
+            return false;
+
+        v = json_array_get(cur, indx);
+    } else if (json_is_object(cur)) {
+        v = json_object_get(cur, s);
+    } else {
+        return false;
+    }
+
+    return json_array_insert(stk, 0, v) >= 0;
+}
+
+static bool
+cmd_set(const json_t *arg, json_t *stk, json_t *cur, json_t *lst)
+{
+    const char *s = json_string_value(arg);
+
+    if (json_is_array(lst)) {
+        size_t indx;
+
+        indx = convert_int(lst, s);
+        if (indx == SIZE_MAX)
+            return false;
+
+        return json_array_set(lst, indx, cur) >= 0;
+    }
+
+    if (json_is_object(lst))
+        return json_object_set(lst, s, cur) >= 0;
+
+    return false;
+}
+
+static const jcmd_doc_t doc_not[] = {
+    { .doc = "Invert the following assertion" },
+    {}
+};
+
+static const jcmd_doc_t doc_object[] = {
+    { .doc = "Assert TOP to be an object" },
+    {}
+};
+
+static const jcmd_doc_t doc_array[] = {
+    { .doc = "Assert TOP to be an array" },
+    {}
+};
+
+static const jcmd_doc_t doc_string[] = {
+    { .doc = "Assert TOP to be a string" },
+    {}
+};
+
+static const jcmd_doc_t doc_int[] = {
+    { .doc = "Assert TOP to be an integer" },
+    {}
+};
+
+static const jcmd_doc_t doc_real[] = {
+    { .doc = "Assert TOP to be a real" },
+    {}
+};
+
+static const jcmd_doc_t doc_number[] = {
+    { .doc = "Assert TOP to be a number" },
+    {}
+};
+
+static const jcmd_doc_t doc_true[] = {
+    { .doc = "Assert TOP to be true" },
+    {}
+};
+
+static const jcmd_doc_t doc_false[] = {
+    { .doc = "Assert TOP to be false" },
+    {}
+};
+
+static const jcmd_doc_t doc_bool[] = {
+    { .doc = "Assert TOP to be a boolean" },
+    {}
+};
+
+static const jcmd_doc_t doc_null[] = {
+    { .doc = "Assert TOP to be null" },
+    {}
+};
+
+static const jcmd_doc_t doc_equal[] = {
+    { .doc = "Assert TOP to be equal to PREV" },
+    {}
+};
+
+static const jcmd_doc_t doc_json[] = {
+    { .arg = "JSON", .doc = "Parse JSON constant, push onto TOP" },
+    { .arg = "FILE", .doc = "Read from FILE, push onto TOP" },
+    { .arg = "-",    .doc = "Read from STDIN, push onto TOP" },
+    {}
+};
+
+static const jcmd_doc_t doc_quote[] = {
+    { .arg = "STR",  .doc = "Convert STR to a string, push onto TOP" },
+    {}
+};
+
+static const jcmd_doc_t doc_output[] = {
+    { .arg = "FILE", .doc = "Write TOP to FILE" },
+    { .arg = "-",    .doc = "Write TOP to STDOUT" },
+    {}
+};
+
+static const jcmd_doc_t doc_foreach[] = {
+    { .arg = "FILE", .doc = "Write TOP (obj./arr.) to FILE, one line/item" },
+    { .arg = "-",    .doc = "Write TOP (obj./arr.) to STDOUT, one line/item" },
+    {}
+};
+
+static const jcmd_doc_t doc_unquote[] = {
+    { .arg = "FILE", .doc = "Write TOP (str.) to FILE without quotes" },
+    { .arg = "-",    .doc = "Write TOP (str.) to STDOUT without quotes" },
+    {}
+};
+
+static const jcmd_doc_t doc_copy[] = {
+    { .doc = "Deep copy TOP, push onto TOP" },
+    {}
+};
+
+static const jcmd_doc_t doc_query[] = {
+    { .doc = "Query the stack by deep copying and pushing onto TOP" },
+    {}
+};
+
+static const jcmd_doc_t doc_move[] = {
+    { .arg = "#", .doc = "Move TOP back # places on the stack" },
+    {}
+};
+
+static const jcmd_doc_t doc_unwind[] = {
+    { .doc = "Discard TOP from the stack" },
+    {}
+};
+
+static const jcmd_doc_t doc_trunc[] = {
+    { .arg = "#",  .doc = "Shrink TOP (arr.) to length #" },
+    { .arg = "-#", .doc = "Discard last # items from TOP (arr.)" },
+    {}
+};
+
+static const jcmd_doc_t doc_insert[] = {
+    { .arg = "#", .doc = "Insert TOP into PREV (arr.) at #" },
+    {}
+};
+
+static const jcmd_doc_t doc_append[] = {
+    { .doc = "Append TOP to the end of PREV (arr.)" },
+    { .doc = "Set missing values from TOP (obj.) into PREV (obj.)" },
+    {}
+};
+
+static const jcmd_doc_t doc_extend[] = {
+    { .doc = "Append items from TOP to the end of PREV (arr.)" },
+    { .doc = "Set all values from TOP (obj.) into PREV (obj.)" },
+    {}
+};
+
+static const jcmd_doc_t doc_delete[] = {
+    { .arg = "NAME", .doc = "Delete NAME from TOP (obj.)" },
+    { .arg = "#",    .doc = "Delete # from TOP (arr.)" },
+    { .arg = "-#",   .doc = "Delete # from the end of TOP (arr.)" },
+    {}
+};
+
+static const jcmd_doc_t doc_length[] = {
+    { .doc = "Push length of TOP (arr./str./obj.) to TOP" },
+    {}
+};
+
+static const jcmd_doc_t doc_empty[] = {
+    { .doc = "Erase all items from TOP (arr./obj.)" },
+    {}
+};
+
+static const jcmd_doc_t doc_get[] = {
+    { .arg = "NAME", .doc = "Get item with NAME from TOP (obj.), push to TOP" },
+    { .arg = "#",    .doc = "Get # item from TOP (arr.), push to TOP" },
+    { .arg = "-#",   .doc = "Get # item from the end of TOP (arr.), push to TOP" },
+    {}
+};
+
+static const jcmd_doc_t doc_set[] = {
+    { .arg = "NAME", .doc = "Sets TOP into PREV (obj.) with NAME" },
+    { .arg = "#",    .doc = "Sets TOP into PREV (obj.) at #" },
+    { .arg = "-#",   .doc = "Sets TOP into PREV (obj.) at # from the end" },
+    {}
+};
+
+static const jcmd_doc_t doc_b64l[] = {
+    { .doc = "URL-safe Base64 decode TOP (str.), push onto TOP" },
+    {}
+};
+
+static const jcmd_doc_t doc_b64d[] = {
+    { .doc = "URL-safe Base64 encode TOP, push onto TOP" },
+    {}
+};
+
+static bool
+opt_set_null(const jcmd_cfg_t *cfg, void *vopt, const char *arg)
+{
+    json_t **x = vopt;
+    if (!*x) *x = json_array();
+    return json_array_append_new(*x, json_pack("[i,n]", cfg->opt.val)) >= 0;
+}
+
+
+static bool
+opt_set_str(const jcmd_cfg_t *cfg, void *vopt, const char *arg)
+{
+    json_t **x = vopt;
+    if (!*x) *x = json_array();
+    return json_array_append_new(*x, json_pack("[i,s]", cfg->opt.val, arg)) >= 0;
+}
+
+static bool
+opt_set_int(const jcmd_cfg_t *cfg, void *vopt, const char *arg)
+{
+    json_t **x = vopt;
+    json_int_t j = 0;
+    int i = 0;
+
+    if (sscanf(arg, "%d", &i) != 1)
+        return false;
+
+    j = i;
+    if (!*x) *x = json_array();
+    return json_array_append_new(*x, json_pack("[i,I]", cfg->opt.val, j)) >= 0;
+}
+
+static bool
+opt_set_uint(const jcmd_cfg_t *cfg, void *vopt, const char *arg)
+{
+    unsigned int i = 0;
+    json_t **x = vopt;
+    json_int_t j = 0;
+
+    if (sscanf(arg, "%u", &i) != 1)
+        return false;
+
+    j = i;
+    if (!*x) *x = json_array();
+    return json_array_append_new(*x, json_pack("[i,I]", cfg->opt.val, j)) >= 0;
+}
+
+static bool
+opt_set_json(const jcmd_cfg_t *cfg, void *vopt, const char *arg)
+{
+    json_auto_t *j = NULL;
+    json_t **x = vopt;
+
+    if (!jcmd_opt_set_json(cfg, &j, arg))
+        return false;
+
+    if (!*x) *x = json_array();
+    return json_array_append_new(*x, json_pack("[i,O]", cfg->opt.val, j)) >= 0;
+}
+
+static const jcmd_cfg_t cfgs[] = {
+    { .opt = { "not",      no_argument,       .val = 'X' }, .doc = doc_not,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "object",   no_argument,       .val = 'O' }, .doc = doc_object,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "array",    no_argument,       .val = 'A' }, .doc = doc_array,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "string",   no_argument,       .val = 'S' }, .doc = doc_string,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "integer",  no_argument,       .val = 'I' }, .doc = doc_int,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "real",     no_argument,       .val = 'R' }, .doc = doc_real,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "number",   no_argument,       .val = 'N' }, .doc = doc_number,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "true",     no_argument,       .val = 'T' }, .doc = doc_true,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "false",    no_argument,       .val = 'F' }, .doc = doc_false,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "boolean",  no_argument,       .val = 'B' }, .doc = doc_bool,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "null",     no_argument,       .val = '0' }, .doc = doc_null,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "equal",    no_argument,       .val = 'E' }, .doc = doc_equal,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+
+    { .opt = { "query",    no_argument,       .val = 'Q' }, .doc = doc_query,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "move",     required_argument, .val = 'M' }, .doc = doc_move,
+      .set = opt_set_uint, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "unwind",   no_argument,       .val = 'U' }, .doc = doc_unwind,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+
+    { .opt = { "json",     required_argument, .val = 'j' }, .doc = doc_json,
+      .set = opt_set_json, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "copy",     no_argument,       .val = 'c' }, .doc = doc_copy,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "quote",    required_argument, .val = 'q' }, .doc = doc_quote,
+      .set = opt_set_str,  .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "output",   required_argument, .val = 'o' }, .doc = doc_output,
+      .set = opt_set_str,  .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "foreach",  required_argument, .val = 'f' }, .doc = doc_foreach,
+      .set = opt_set_str,  .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "unquote",  required_argument, .val = 'u' }, .doc = doc_unquote,
+      .set = opt_set_str,  .off = offsetof(jcmd_opt_t, args) },
+
+    { .opt = { "truncate", required_argument, .val = 't' }, .doc = doc_trunc,
+      .set = opt_set_int,  .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "insert",   required_argument, .val = 'i' }, .doc = doc_insert,
+      .set = opt_set_uint, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "append",   no_argument,       .val = 'a' }, .doc = doc_append,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "extend",   no_argument,       .val = 'x' }, .doc = doc_extend,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+
+    { .opt = { "delete",   required_argument, .val = 'd' }, .doc = doc_delete,
+      .set = opt_set_str,  .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "length",   no_argument,       .val = 'l' }, .doc = doc_length,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "empty",    no_argument,       .val = 'e' }, .doc = doc_empty,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "get",      required_argument, .val = 'g' }, .doc = doc_get,
+      .set = opt_set_str,  .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "set",      required_argument, .val = 's' }, .doc = doc_set,
+      .set = opt_set_str,  .off = offsetof(jcmd_opt_t, args) },
+
+    { .opt = { "b64load",  no_argument,       .val = 'y' }, .doc = doc_b64l,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+    { .opt = { "b64dump",  no_argument,       .val = 'Y' }, .doc = doc_b64d,
+      .set = opt_set_null, .off = offsetof(jcmd_opt_t, args) },
+
+    {}
+};
+
+static int
+jcmd_fmt(int argc, char *argv[])
+{
+    json_auto_t *stk = json_array();
+    jcmd_opt_auto_t opt = {};
+    unsigned char ret = 0;
+    bool not = false;
+
+    if (!jcmd_opt_parse(argc, argv, cfgs, &opt, prefix))
+        return -1;
+
+    for (size_t i = 0; i < json_array_size(opt.args); i++) {
+        json_t *lst = NULL;
+        json_t *cur = NULL;
+        json_t *p = NULL;
+        bool ok = false;
+        int o = 0;
+
+        if (json_unpack(json_array_get(opt.args, i), "[i,o!]", &o, &p) < 0)
+            return ++ret;
+
+        if (not && !strchr("OASIRNTFB0E", o))
+            return ret;
+
+        cur = json_array_get(stk, 0);
+        lst = json_array_get(stk, 1);
+        ret++;
+