diff --git a/l/scute/scute-1.5.0-generaterandom.diff b/l/scute/scute-1.5.0-generaterandom.diff new file mode 100644 index 00000000..1ac0a281 --- /dev/null +++ b/l/scute/scute-1.5.0-generaterandom.diff @@ -0,0 +1,285 @@ +diff --git a/src/agent.c b/src/agent.c +index b51dc7e..9a75bf8 100644 +--- a/src/agent.c ++++ b/src/agent.c +@@ -846,6 +846,12 @@ learn_status_cb (void *opaque, const char *line) + } + } + } ++ else if (keywordlen == 6 && !memcmp (keyword, "EXTCAP", keywordlen)) ++ { ++ /* FIXME: Should we parse the line properly instead of assuming ++ that the gc capability will always be at the beginning? */ ++ sscanf (line, "gc=%d", &(parm->rng_available)); ++ } + return 0; + } + +@@ -1281,6 +1287,28 @@ scute_agent_get_cert (int no, struct cert *cert) + return 0; + } + ++gpg_error_t ++get_challenge_data_cb (void *opaque, const void *line, size_t len) ++{ ++ memcpy (opaque, line, len); ++ ++ return 0; ++} ++ ++gpg_error_t ++scute_agent_get_random (unsigned char *data, size_t len) ++{ ++ char command[16]; ++ gpg_error_t err; ++ ++ snprintf (command, sizeof(command), "SCD RANDOM %lu", len); ++ ++ err = assuan_transact (agent_ctx, command, get_challenge_data_cb, ++ data, NULL, NULL, NULL, NULL); ++ ++ return err; ++} ++ + + void + scute_agent_finalize (void) +diff --git a/src/agent.h b/src/agent.h +index 6ac479f..0d6bb30 100644 +--- a/src/agent.h ++++ b/src/agent.h +@@ -73,6 +73,8 @@ struct agent_card_info_s + char grip1[41]; + char grip2[41]; + char grip3[41]; ++ int rng_available; /* True if the GET CHALLENGE operation ++ is supported. */ + }; + + +@@ -113,4 +115,7 @@ gpg_error_t scute_agent_is_trusted (char *fpr, bool *is_trusted); + /* Try to get certificate for key numer NO. */ + gpg_error_t scute_agent_get_cert (int no, struct cert *cert); + ++/* Get random bytes from the card. */ ++gpg_error_t scute_agent_get_random (unsigned char *data, size_t len); ++ + #endif /* AGENT_H */ +diff --git a/src/p11-generaterandom.c b/src/p11-generaterandom.c +index f192e9d..e8b20d9 100644 +--- a/src/p11-generaterandom.c ++++ b/src/p11-generaterandom.c +@@ -33,14 +33,32 @@ + + #include "cryptoki.h" + ++#include "locking.h" ++#include "slots.h" ++#include "agent.h" ++#include "error-mapping.h" ++ + + CK_DEFINE_FUNCTION(CK_RV, C_GenerateRandom) + (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, + CK_ULONG ulRandomLen) + { +- /* FIXME: Implement me. */ +- (void) hSession; +- (void) pRandomData; +- (void) ulRandomLen; +- return CKR_FUNCTION_NOT_SUPPORTED; ++ CK_RV err; ++ slot_iterator_t slot; ++ session_iterator_t session; ++ ++ if (pRandomData == NULL_PTR) ++ return CKR_ARGUMENTS_BAD; ++ ++ err = scute_global_lock (); ++ if (err) ++ return err; ++ ++ err = slots_lookup_session (hSession, &slot, &session); ++ if (!err) ++ err = scute_gpg_err_to_ck (scute_agent_get_random (pRandomData, ++ ulRandomLen)); ++ ++ scute_global_unlock (); ++ return err; + } +diff --git a/src/p11-gettokeninfo.c b/src/p11-gettokeninfo.c +index 88d77be..c0a2417 100644 +--- a/src/p11-gettokeninfo.c ++++ b/src/p11-gettokeninfo.c +@@ -72,8 +72,11 @@ CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo) + pInfo->flags = CKF_TOKEN_INITIALIZED + | CKF_PROTECTED_AUTHENTICATION_PATH | CKF_WRITE_PROTECTED + | CKF_USER_PIN_INITIALIZED; +- /* FIXME: Support this later: CKF_RNG. +- FIXME: CKF_USER_PIN_INITIALIZED only if PIN is not default pin? ++ ++ if (slot_token_has_rng (slot)) ++ pInfo->flags |= CKF_RNG; ++ ++ /* FIXME: CKF_USER_PIN_INITIALIZED only if PIN is not default pin? + FIXME: CKF_LOGIN_REQUIRED needed? We could implement login via + the "SCD CHECKPIN" command. I am not sure how this mixes with + CKF_PROTECTED_AUTHENTICATION_PATH. +diff --git a/src/slots.c b/src/slots.c +index 136d64e..810be0b 100644 +--- a/src/slots.c ++++ b/src/slots.c +@@ -657,6 +657,15 @@ slot_get_id (slot_iterator_t slot) + return slot; + } + ++/* Return true if the token supports the GET CHALLENGE operation. */ ++bool ++slot_token_has_rng (slot_iterator_t id) ++{ ++ struct slot *slot = scute_table_data (slots, id); ++ ++ return slot->info.rng_available; ++} ++ + + /* Mechanism management. */ + +diff --git a/src/slots.h b/src/slots.h +index e36be27..3624c55 100644 +--- a/src/slots.h ++++ b/src/slots.h +@@ -116,6 +116,9 @@ void slot_token_pincount (slot_iterator_t id, int *max, int *len); + /* Return the ID of slot SLOT. */ + CK_SLOT_ID slot_get_id (slot_iterator_t slot); + ++/* Return true if the token supports the GET CHALLENGE operation. */ ++bool slot_token_has_rng (slot_iterator_t id); ++ + + /* Begin iterating over the list of mechanisms. If succeeds, will be + followed up by a slot_iterate_end. */ +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 644eeb0..6c19071 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -33,7 +33,7 @@ noinst_HEADERS = t-support.h + TESTS = t-link t-getfunctionlist t-initialize t-getinfo t-getslotlist \ + t-getslotinfo t-gettokeninfo t-getmechanismlist t-getmechanisminfo \ + t-opensession t-closeallsessions t-getsessioninfo \ +- t-findobjects t-getattribute t-auth ++ t-findobjects t-getattribute t-auth t-generaterandom + + noinst_PROGRAMS = $(TESTS) + +diff --git a/tests/t-generaterandom.c b/tests/t-generaterandom.c +new file mode 100644 +index 0000000..675138d +--- /dev/null ++++ b/tests/t-generaterandom.c +@@ -0,0 +1,105 @@ ++/* t-generaterandom.c - Regression test. ++ Copyright (C) 2016 g10 Code GmbH ++ ++ This file is part of Scute. ++ ++ Scute 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 2 of the License, or ++ (at your option) any later version. ++ ++ Scute 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 Scute; if not, write to the Free Software Foundation, ++ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ ++ In addition, as a special exception, g10 Code GmbH gives permission ++ to link this library: with the Mozilla Foundation's code for ++ Mozilla (or with modified versions of it that use the same license ++ as the "Mozilla" code), and distribute the linked executables. You ++ must obey the GNU General Public License in all respects for all of ++ the code used other than "Mozilla". If you modify this file, you ++ may extend this exception to your version of the file, but you are ++ not obligated to do so. If you do not wish to do so, delete this ++ exception statement from your version. */ ++ ++#include ++#include ++ ++#include "t-support.h" ++ ++ ++int ++main (int argc, char *argv[]) ++{ ++ CK_RV err; ++ CK_SLOT_ID_PTR slots; ++ CK_ULONG slots_count; ++ unsigned int i; ++ ++ (void) argc; ++ (void) argv; ++ ++ init_cryptoki (); ++ ++ err = C_GetSlotList (true, NULL, &slots_count); ++ fail_if_err (err); ++ ++ if (slots_count == 0) ++ { ++ printf ("Skipping test because no token is present.\n"); ++ return 77; ++ } ++ ++ printf ("Number of slots with tokens: %lu\n", slots_count); ++ slots = malloc (sizeof (CK_SLOT_ID) * slots_count); ++ if (!slots) ++ fail_if_err (CKR_HOST_MEMORY); ++ ++ err = C_GetSlotList (true, slots, &slots_count); ++ fail_if_err (err); ++ ++ for (i = 0; i < slots_count; i++) ++ { ++ CK_TOKEN_INFO info; ++ ++ printf ("%2i. Slot ID %lu\n", i, slots[i]); ++ ++ err = C_GetTokenInfo (slots[i], &info); ++ fail_if_err (err); ++ ++ if ((info.flags & CKF_RNG) > 0) ++ { ++ CK_SESSION_HANDLE session; ++ unsigned char buffer[16]; ++ unsigned int j; ++ ++ printf(" RNG available\n"); ++ ++ err = C_OpenSession (slots[i], CKF_SERIAL_SESSION, NULL, NULL, ++ &session); ++ fail_if_err (err); ++ ++ printf (" Session ID: %lu\n", session); ++ ++ err = C_GenerateRandom (session, buffer, sizeof(buffer)); ++ fail_if_err (err); ++ ++ printf (" Random bytes: 0x"); ++ for (j = 0; j < sizeof(buffer); j++) ++ printf ("%02x", buffer[j]); ++ printf ("\n"); ++ ++ err = C_CloseSession (session); ++ fail_if_err (err); ++ } ++ else ++ printf (" No RNG available on token\n"); ++ } ++ ++ return 0; ++} diff --git a/l/scute/scute.SlackBuild b/l/scute/scute.SlackBuild index 1cab4ec9..0d9159e8 100755 --- a/l/scute/scute.SlackBuild +++ b/l/scute/scute.SlackBuild @@ -31,7 +31,7 @@ NAMESRC=${NAMESRC:-scute} VERSION=${VERSION:-1.5.0} ARCHIVE=${ARCHIVE:-$NAMESRC-$VERSION.tar.bz2} WGET=${WGET:-ftp://ftp.gnupg.org/gcrypt/scute/$ARCHIVE} -GITREV=${GITREV:-2d8d4f0} +GITREV=${GITREV:-dc7dff1} # Build infos NAMEPKG=${NAMEPKG:-scute} @@ -79,6 +79,7 @@ if [ ! -r $ARCHIVE ]; then git clone git://git.gnupg.org/scute.git cd scute git checkout $GITREV + patch -p 1 < $CWD/scute-1.5.0-generaterandom.diff AUTOMAKE_SUFFIX=-1.15 ./autogen.sh --force ./configure --enable-maintainer-mode make -j $JOBS