diff --git a/tool/Makefile.am b/tool/Makefile.am
index 0e5af5e..0d5c178 100644
--- a/tool/Makefile.am
+++ b/tool/Makefile.am
@@ -30,12 +30,16 @@ AM_CFLAGS = $(WERROR_CFLAGS) $(WARN_CFLAGS)
AM_CPPFLAGS = $(OPENSSL_CFLAGS)
AM_CPPFLAGS += -I$(top_srcdir)/lib -I$(top_builddir)/lib
-bin_PROGRAMS = yubico-piv-tool
+bin_PROGRAMS = yubico-piv-tool yubico-piv-signer
yubico_piv_tool_SOURCES = yubico-piv-tool.c yubico-piv-tool.h2m
yubico_piv_tool_LDADD = $(OPENSSL_LIBS) ../lib/libykpiv.la
yubico_piv_tool_LDADD += libpiv_cmd.la libpiv_util.la
-noinst_LTLIBRARIES = libpiv_cmd.la libpiv_util.la
+yubico_piv_signer_SOURCES = yubico-piv-signer.c
+yubico_piv_signer_LDADD = $(OPENSSL_LIBS) ../lib/libykpiv.la
+yubico_piv_signer_LDADD += libpivsigner_cmd.la libpiv_util.la
+
+noinst_LTLIBRARIES = libpiv_cmd.la libpiv_util.la libpivsigner_cmd.la
libpiv_cmd_la_SOURCES = cmdline.ggo cmdline.c cmdline.h
libpiv_cmd_la_CFLAGS =
@@ -45,6 +49,12 @@ libpiv_util_la_LIBADD = $(OPENSSL_LIBS)
cmdline.c cmdline.h: cmdline.ggo Makefile.am
$(GENGETOPT) --input $^
+libpivsigner_cmd_la_SOURCES = cmdline-signer.c cmdline-signer.h
+libpivsigner_cmd_la_CFLAGS =
+
+cmdline-signer.c cmdline-signer.h: cmdline-signer.ggo Makefile.am
+ $(GENGETOPT) --input $^ -F cmdline-signer
+
BUILT_SOURCES = cmdline.c cmdline.h
MAINTAINERCLEANFILES = $(BUILT_SOURCES)
diff --git a/tool/cmdline-signer.ggo b/tool/cmdline-signer.ggo
new file mode 100644
index 0000000..dc56c40
--- /dev/null
+++ b/tool/cmdline-signer.ggo
@@ -0,0 +1,39 @@
+# Copyright (c) 2014 Yubico AB
+# All rights reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# Additional permission under GNU GPL version 3 section 7
+#
+# If you modify this program, or any covered work, by linking or
+# combining it with the OpenSSL project's OpenSSL library (or a
+# modified version of that library), containing parts covered by the
+# terms of the OpenSSL or SSLeay licenses, We grant you additional
+# permission to convey the resulting work. Corresponding Source for a
+# non-source form of such a combination shall include the source code
+# for the parts of OpenSSL used as well as that of the covered work.
+
+option "verbose" v "Print more information" int optional default="0" argoptional
+option "reader" r "Only use a matching reader" string optional default="Yubikey"
+option "slot" s "What key slot to operate on" values="9a","9c","9d","9e" enum
+text "
+ 9a is for PIV Authentication
+ 9c is for Digital Signature (PIN always checked)
+ 9d is for Key Management
+ 9e is for Card Authentication (PIN never checked)\n"
+option "algorithm" A "What algorithm to use" values="RSA1024","RSA2048","ECCP256" enum optional default="RSA2048"
+option "input" i "Filename to use as input, - for stdin" string optional default="-"
+option "output" o "Filename to use as output, - for stdout" string optional default="-"
+option "pin" P "Pin code for verification" string
+option "hash" H "Hash to use for the signature" values="SHA1","SHA256" enum optional default="SHA1"
diff --git a/tool/yubico-piv-signer.c b/tool/yubico-piv-signer.c
new file mode 100644
index 0000000..5b8687f
--- /dev/null
+++ b/tool/yubico-piv-signer.c
@@ -0,0 +1,102 @@
+ /*
+ * Copyright (c) 2014 Yubico AB
+ * All rights reserved.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * Additional permission under GNU GPL version 3 section 7
+ *
+ * If you modify this program, or any covered work, by linking or
+ * combining it with the OpenSSL project's OpenSSL library (or a
+ * modified version of that library), containing parts covered by the
+ * terms of the OpenSSL or SSLeay licenses, We grant you additional
+ * permission to convey the resulting work. Corresponding Source for a
+ * non-source form of such a combination shall include the source code
+ * for the parts of OpenSSL used as well as that of the covered work.
+ *
+ */
+
+#include
+#include
+#include
+#include
+
+#include "ykpiv.h"
+
+#ifdef _WIN32
+#include
+#endif
+
+#include "util.h"
+
+static bool verify_pin(ykpiv_state *state, const char *pin) {
+ int tries = -1;
+ ykpiv_rc res;
+ int len = strlen(pin);
+
+ if(len > 8) {
+ fprintf(stderr, "Maximum 8 digits of PIN supported.\n");
+ }
+
+ res = ykpiv_verify(state, pin, &tries);
+ if(res == YKPIV_OK) {
+ return true;
+ } else if(res == YKPIV_WRONG_PIN) {
+ if(tries > 0) {
+ fprintf(stderr, "Pin verification failed, %d tries left before pin is blocked.\n", tries);
+ } else {
+ fprintf(stderr, "Pin code blocked, use unblock-pin action to unblock.\n");
+ }
+ } else {
+ fprintf(stderr, "Pin code verification failed: '%s'\n", ykpiv_strerror(res));
+ }
+ return false;
+}
+
+int main(int argc, char *argv[]) {
+ struct gengetopt_args_info args_info;
+ ykpiv_state *state;
+ int verbosity;
+ enum enum_action action;
+ int ret = EXIT_SUCCESS;
+
+ if(cmdline_parser(argc, argv, &args_info) != 0) {
+ return EXIT_FAILURE;
+ }
+
+ verbosity = args_info.verbose_arg + (int)args_info.verbose_given;
+
+ if(ykpiv_init(&state, verbosity) != YKPIV_OK) {
+ fprintf(stderr, "Failed initializing library.\n");
+ return EXIT_FAILURE;
+ }
+
+ if(ykpiv_connect(state, args_info.reader_arg) != YKPIV_OK) {
+ fprintf(stderr, "Failed to connect to reader.\n");
+ return EXIT_FAILURE;
+ }
+
+ if(verify_pin(state, args_info.pin_arg)) {
+ printf("Successfully verified PIN.\n");
+ } else {
+ return EXIT_FAILURE;
+ }
+
+ /* openssl setup.. */
+ OpenSSL_add_all_algorithms();
+
+ ykpiv_done(state);
+ EVP_cleanup();
+ return ret;
+}