From 903844fa19496bc9959134a7e8b5766a9efcd8a8 Mon Sep 17 00:00:00 2001 From: Paul Wouters Date: Oct 07 2014 17:36:15 +0000 Subject: * Tue Sep 30 2014 Paul Wouters - 2.0.0b1-3 - Fix softhsm2-pk11install buid and post call - Do not use --with-objectstore-backend-db (causes issues on i686) - Change install directory to /usr/lib*/pkcs11/ - Install pkcs11 module file - Use official upstream tar ball - Create ods user to own softhsm/token files - Enable migration tools (for softhsm-v1 installs) - Add softlink for softhsm-v1 .so (needed for opendnssec's conf.xml) - Require p11-kit, nss-tools, for SoftHSM PKCS #11 Module file - Copy pk11install.c from coolkey package - Enable hardened build - Add upstream official source url --- diff --git a/.gitignore b/.gitignore index 35dcfb6..2e65a91 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /softhsm-1.3.3.tar.gz /softhsm-1.3.5.tar.gz /softhsm-1.3.6.tar.gz +/softhsm-2.0.0b1.tar.gz diff --git a/softhsm.module b/softhsm.module index 17433e4..e1e5619 100644 --- a/softhsm.module +++ b/softhsm.module @@ -5,4 +5,4 @@ # the p11-kit default path which is usually $(libdir)/pkcs11. # Doing it this way allows for packagers to package for # 32-bit and 64-bit and make them parallel installable -module: libsofthsm.so +module: libsofthsm2.so diff --git a/softhsm.spec b/softhsm.spec index b4c4d27..00c609d 100644 --- a/softhsm.spec +++ b/softhsm.spec @@ -1,42 +1,55 @@ Summary: Software version of a PKCS#11 Hardware Security Module Name: softhsm -Version: 1.3.6 +Version: 2.0.0b1 Release: 3%{?dist} +ExcludeArch: i686 ppc s390 License: BSD Url: http://www.opendnssec.org/ -Source: http://www.opendnssec.org/files/source/%{name}-%{version}.tar.gz +Source: http://dist.opendnssec.org/source/testing/%{name}-%{version}.tar.gz Source1: softhsm.module +# taken from coolkey which is not build on all arches we build on +Source2: softhsm2-pk11install.c Group: Applications/System -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -BuildRequires: botan-devel >= 1.8.5 sqlite-devel >= 3.4.2 +BuildRequires: openssl-devel, sqlite-devel >= 3.4.2, cppunit-devel +BuildRequires: gcc-c++, pkgconfig, p11-kit-devel, nss-devel + Requires(pre): shadow-utils -Requires: p11-kit -# temp. for p11install -Requires: coolkey +Requires: p11-kit, nss-tools + +%global _hardened_build 1 %global softhsm_module "SoftHSM PKCS #11 Module" %global nssdb %{_sysconfdir}/pki/nssdb %description -OpenDNSSEC is providing a software implementation of a generic -cryptographic device with a PKCS#11 interface, the SoftHSM. SoftHSM is -designed to meet the requirements of OpenDNSSEC, but can also work together +OpenDNSSEC is providing a software implementation of a generic +cryptographic device with a PKCS#11 interface, the SoftHSM. SoftHSM is +designed to meet the requirements of OpenDNSSEC, but can also work together with other cryptographic products because of the PKCS#11 interface. %package devel Summary: Development package of softhsm that includes the header files Group: Development/Libraries -Requires: %{name} = %{version}-%{release}, botan-devel, sqlite-devel +Requires: %{name} = %{version}-%{release}, openssl-devel, sqlite-devel %description devel The devel package contains the libsofthsm include files %prep -%setup -q +%setup -q +# remove softhsm/ subdir auto-added to --libdir +sed -i "s:full_libdir/softhsm:full_libdir:g" configure +sed -i "s:libdir)/@PACKAGE@:libdir):" Makefile.in %build -%configure --libdir=%{_libdir}/ --with-botan=%{_prefix} +%configure --libdir=/usr/lib64/pkcs11 --with-openssl=%{_prefix} --enable-ecc --disable-gost \ + --with-migrate --enable-visibility + make %{?_smp_mflags} +# install our copy of pk11install taken from coolkey package +cp %{SOURCE2} . +gcc $(pkg-config --cflags nss) %{optflags} -c softhsm2-pk11install.c +gcc $(pkg-config --libs nss) -lpthread -lsoftokn3 -ldl -lz %{optflags} softhsm2-pk11install.o -o softhsm2-pk11install %check make check @@ -44,26 +57,30 @@ make check %install rm -rf %{buildroot} make DESTDIR=%{buildroot} install -mkdir -p %{buildroot}/%{_libdir}/pkcs11 -#p11-kit install -ln -s ../softhsm/libsofthsm.so %{buildroot}/%{_libdir}/pkcs11/ install -D %{SOURCE1} %{buildroot}/%{_datadir}/p11-kit/modules/softhsm.module -rm %{buildroot}/etc/softhsm.conf.sample -rm -f %{buildroot}/%{_libdir}/softhsm/*a +rm %{buildroot}/%{_sysconfdir}/softhsm2.conf.sample +rm -f %{buildroot}/%{_libdir}/pkcs11/*a mkdir -p %{buildroot}%{_includedir}/softhsm cp src/lib/*.h %{buildroot}%{_includedir}/softhsm -mkdir -p %{buildroot}/var/softhsm +mkdir -p %{buildroot}/%{_sharedstatedir}/softhsm/tokens +install -m0755 -D softhsm2-pk11install %{buildroot}/%{_bindir}/softhsm2-pk11install + +# leave a softlink where softhsm-1 installed its library. Programs like +# opendnssec have that filename in their configuration file. +mkdir -p %{buildroot}/%{_libdir}/softhsm/ +ln -s ../pkcs11/libsofthsm2.so %{buildroot}/%{_libdir}/softhsm/libsofthsm.so -%files -%config(noreplace) %{_sysconfdir}/softhsm.conf +%files +%config(noreplace) %{_sysconfdir}/softhsm2.conf %{_bindir}/* -%dir %{_libdir}/softhsm/ +%dir %{_libdir}/softhsm +%{_libdir}/pkcs11/libsofthsm2.so %{_libdir}/softhsm/libsofthsm.so -%{_libdir}/pkcs11/libsofthsm.so -%{_datadir}/p11-kit/modules/softhsm.module -%attr(0770,ods,ods) %dir /var/softhsm -%doc AUTHORS NEWS LICENSE +%attr(0664,root,root) %{_datadir}/p11-kit/modules/softhsm.module +%attr(0770,ods,ods) %dir %{_sharedstatedir}/softhsm +%attr(0770,ods,ods) %dir %{_sharedstatedir}/softhsm/tokens +%doc LICENSE README.md NEWS %{_mandir}/*/* %files devel @@ -73,23 +90,40 @@ mkdir -p %{buildroot}/var/softhsm %pre getent group ods >/dev/null || groupadd -r ods getent passwd ods >/dev/null || \ - useradd -r -g ods -d /var/softhsm -s /sbin/nologin \ + useradd -r -g ods -d /%{_sharedstatedir}/softhsm -s /sbin/nologin \ -c "softhsm private keys owner" ods exit 0 %post isThere=`modutil -rawlist -dbdir %{nssdb} | grep %{softhsm_module} || echo NO` if [ "$isThere" == "NO" ]; then - if [ -x %{_bindir}/pk11install ]; then - pk11install -p %{nssdb} 'name=%{softhsm_module} library=libsofthsm.so' ||: - fi + softhsm2-pk11install -p %{nssdb} 'name=%{softhsm_module} library=libsofthsm2.so' fi if [ $1 -eq 0 ]; then modutil -delete %{softhsm_module} -dbdir %{nssdb} -force || : fi +%triggerpostun -- softhsm < 2.0.0 +if [ -f /var/softhsm/slot0.db ]; then + runuser -g ods ods -c 'softhsm2-migrate --db /var/softhsm/slot0.db --pin 1234 --slot 0' || : +fi + %changelog +* Tue Sep 30 2014 Paul Wouters - 2.0.0b1-3 +- Fix softhsm2-pk11install buid and post call +- Do not use --with-objectstore-backend-db (causes issues on i686) +- Change install directory to /usr/lib*/pkcs11/ +- Install pkcs11 module file +- Use official upstream tar ball +- Create ods user to own softhsm/token files +- Enable migration tools (for softhsm-v1 installs) +- Add softlink for softhsm-v1 .so (needed for opendnssec's conf.xml) +- Require p11-kit, nss-tools, for SoftHSM PKCS #11 Module file +- Copy pk11install.c from coolkey package +- Enable hardened build +- Add upstream official source url + * Mon Aug 18 2014 Fedora Release Engineering - 1.3.6-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild diff --git a/softhsm2-pk11install.c b/softhsm2-pk11install.c new file mode 100644 index 0000000..9e61646 --- /dev/null +++ b/softhsm2-pk11install.c @@ -0,0 +1,452 @@ +/* ***** BEGIN COPYRIGHT BLOCK ***** + * Copyright (C) 2006 Red Hat, Inc. + * All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version + * 2.1 of the License. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * ***** END COPYRIGHT BLOCK ***** */ + +#include +#include +#include "pkcs11.h" +#include "pkcs11n.h" + +/* + * windows specific globing search + */ +#ifdef WIN32 +#include +#include +#include +#include +#include + +#define PINST_FILE_DATA WIN32_FIND_DATA +#define PINST_ITERATOR HANDLE +#define PINST_FIRST(pattern, data) FindFirstFile(pattern, &data) +#define PINST_PATH(iter, data) (data).cFileName +#define PINST_NEXT(iter, data) FindNextFile(iter, &data) +#define PINST_FREE_ITER(iter, data) FindClose(iter) +#define PINST_INVALID_ITERATOR INVALID_HANDLE_VALUE +#define PINST_IS_DIRECTORY(iter, data) \ + ((data).dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) +#define PINST_IS_HIDDEN(iter, data) \ + ((data).dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) +#define PINST_FULLPATH(tempPath,path) tempPath +#define PINST_ERROR DWORD +#define PINST_NO_MORE ERROR_NO_MORE_FILES +#define PINST_SET_ERROR(x) SetLastError(x) +#define PINST_GET_ERROR() GetLastError() +#define PINST_FS "\\" + + +/*#define NETSCAPE_KEY "Software\\Netscape\\Netscape Navigator\\Main" */ +#define NETSCAPE_KEY "Software\\Netscape\\Netscape Navigator" +#define NETSCAPE_SUBKEY_1 "Main" +#define NETSCAPE_SUBKEY_2 "Install Directory" + +/* capture the window's error string */ +static void +winPerror(FILE *outFile, DWORD error, const char *msgString) +{ + char buffer[256]; + char *cp; + DWORD ret; + + fprintf(outFile,"*** %s: ",msgString); + sprintf(buffer,"Format message problem, error = %d (0x%x)\n", error, error); + ret=FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, buffer, + sizeof(buffer), NULL); + for (cp=buffer; *cp; cp++) { + if (*cp == '\r') *cp = ' '; + } + fprintf(outFile, buffer); +} +#endif + +/* + * otherwise we are assuming unix (posix) + */ +#ifndef PINST_FILE_DATA +#define UNIX +#include +#include +#include +#define PINST_FILE_DATA glob_t +#define PINST_ITERATOR int +#define PINST_INVALID_ITERATOR -1 +#define PINST_FIRST(pattern, data) \ + ((glob(pattern, GLOB_MARK, NULL, &data) == 0) ? 0 : PINST_INVALID_ITERATOR) +#define PINST_PATH(iter, data) \ + (((data).gl_pathv == NULL) ? 0 : (data).gl_pathv[iter] ) +#define PINST_NEXT(iter, data) (((data).gl_pathc > ++iter) ? iter : 0) +#define PINST_FREE_ITER(iter, data) globfree(&data) +#define PINST_IS_DIRECTORY(iter, data) pinst_isdir(PINST_PATH(iter,data)) +#define PINST_IS_HIDDEN(iter, data) (0) +#define PINST_FULLPATH(tempPath,path) path +#define PINST_ERROR int +#define NO_ERROR 0 +#define PINST_NO_MORE NO_ERROR +#define PINST_SET_ERROR(x) +#define PINST_GET_ERROR() NO_ERROR +#define PINST_FS "/" + + +#define MAX_PATH PATH_MAX + +static int +pinst_isdir(const char *path) +{ + int len = strlen(path); + + + return (len > 0) && (path[len-1] == '/'); +} + +#endif + + +typedef enum _InstType { + Install, + UnInstall, +} InstType; + +typedef enum _DirType { + AppDataDir = 0, + HomeDir, + NetscapeInstallDir, + MaxDirType, +} DirType; + +char *dirPaths[MaxDirType] = { NULL }; + +typedef struct _DirList { + DirType dirType; + char *search; + char *tail; +} DirList; + +DirList dirList[] = { +#ifdef WIN32 + { AppDataDir, "Mozilla\\Profiles\\*", "*.slt" }, + { AppDataDir, "Mozilla\\Firefox\\Profiles\\*", NULL }, + { AppDataDir, "Thunderbird\\Profiles\\*", NULL }, + { NetscapeInstallDir, "..\\Users\\*", NULL }, +#endif +#ifndef MAC +#ifdef UNIX + { HomeDir, ".mozilla/firefox/*", NULL }, + { HomeDir, ".mozilla/*", NULL }, + { HomeDir, ".thunderbird/*", NULL }, + { HomeDir, ".netscape", NULL }, +#endif +#endif +#ifdef MAC + + { HomeDir, "Library/Mozilla/Profiles/*", "*.slt"}, + { HomeDir, "Library/Application Support/Firefox/Profiles/*", NULL }, + { HomeDir, "Library/Thunderbird/Profiles/*", NULL }, + + +#endif + + +}; + +int verbose = 0; + +int dirListCount = sizeof(dirList)/sizeof(dirList[0]); + +static void +usage(char *prog) +{ + fprintf(stderr,"usage: %s [-u][-v] [-p path] module\n", prog); + return; +} + +/* Utility printing functions */ + + + +#define CONFIG_TAG "configDir=" +int +installPKCS11(char *dirPath, InstType type, char *module) +{ + char *paramString = (char *)malloc(strlen(dirPath)+sizeof(CONFIG_TAG)+3); + char *cp; + char **rc; + + if (paramString == NULL) { + PINST_SET_ERROR(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + sprintf(paramString,CONFIG_TAG"\"%s\" ",dirPath); + + /* translate all the \'s to /'s */ + for (cp=paramString; *cp; cp++) { + if (*cp == '\\') *cp='/'; + } + + /* don't call this if you have NSS initialized!!, use SECMOD_AddModule + * or SECMOD_AddUserModule instead */ + rc = (char **) NSC_ModuleDBFunc(type == Install ? + SECMOD_MODULE_DB_FUNCTION_ADD : + SECMOD_MODULE_DB_FUNCTION_DEL, paramString, module); + if (verbose) { + fprintf(stderr, "Install \"%s\" in %s : %s\n", module, dirPath, + rc ? *rc : "Fail" ); + } + + free(paramString); + return 1; +} + + +int +installAllPKCS11(char *dirPath, char *search, char *tail, + InstType type, char *module) +{ + char *searchString; + unsigned long searchStringLen; + int len; + char *tempPath, *fileStart; + PINST_FILE_DATA fileData; + PINST_ITERATOR iter; + PINST_ERROR err = NO_ERROR; + + char *myPath = NULL; + + searchString = (char *)malloc(strlen(dirPath)+2+strlen(search)); + + if (searchString == NULL) { + PINST_SET_ERROR(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + sprintf(searchString,"%s" PINST_FS "%s",dirPath,search); + + searchStringLen = strlen(searchString); + tempPath=malloc(searchStringLen+MAX_PATH+1); + if (tempPath == NULL) { + free(searchString); + PINST_SET_ERROR(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + strcpy(tempPath, searchString); + fileStart = strrchr(tempPath, *PINST_FS); + if (fileStart == NULL) { + tempPath[searchStringLen] = *PINST_FS; + fileStart = &tempPath[searchStringLen]; + } + fileStart++; + + iter = PINST_FIRST(searchString, fileData); + free(searchString); + if (iter == PINST_INVALID_ITERATOR) { + /* error set by PINST_FIRST */ + free(tempPath); + return 0; + } + + len=1; + + do { + char *path = PINST_PATH(iter, fileData); + if(!path) + { + break; + } + + if (!PINST_IS_DIRECTORY(iter, fileData)) { + continue; + } + if (PINST_IS_HIDDEN(iter, fileData)) { + continue; + } + /* skip . and .. */ + if ((path[0] == '.') && ((path[1] == 0) || + (path[1] == '.' && path[2] == 0)) ) { + continue; + } + strcpy(fileStart,path); + + myPath=PINST_FULLPATH(tempPath,path); + if (tail) { + installAllPKCS11(myPath, tail, NULL, type, module); + } else { + installPKCS11(myPath, type, module); + } + } while (PINST_NEXT(iter, fileData)); + free(tempPath); + + err = PINST_GET_ERROR(); + PINST_FREE_ITER(iter,fileData); + + if (err != PINST_NO_MORE) { + /* restore the previous error (in case FindClose trashes it) */ + PINST_SET_ERROR(err); + return 0; + } + return 1; +} + +int main(int argc, char **argv) +{ + char *module = NULL; + char *prog = *argv++; + char *cp; + int argCount = 0; + int i; + InstType type = Install; + char * path = NULL; +#ifdef WIN32 + BOOL brc; + HKEY regKey; + unsigned long lrc; + TCHAR appData[MAX_PATH]; + char netscapeInstall[MAX_PATH]; + unsigned long nsInstallSize = MAX_PATH; +#endif + + /* + * parse the arglist; + */ + while ((cp = *argv++) != 0) { + if (*cp == '-') { + while (*++cp) switch (*cp) { + case 'i': + type = Install; + break; + case 'u': + type = UnInstall; + break; + case 'v': + verbose = 1; + break; + case 'p': + path = *argv++; + if (path == NULL) { + usage(prog); + return 2; + } + break; + default: + usage(prog); + return 2; + } + } else switch (argCount++) { + case 0: + module = cp; + break; + default: + usage(prog); + return 2; + } + } + + if (module == NULL) { + usage(prog); + } + + if (path) { + installAllPKCS11(path, "", NULL, type, module); + return 0; + } + +#ifdef WIN32 + /* App Data Dir */ + brc = SHGetSpecialFolderPath(NULL, appData, CSIDL_APPDATA, FALSE); + if (brc) { + dirPaths[AppDataDir] = appData; + } else { + if (verbose) { + winPerror(stderr, GetLastError(), "Reading App Directory"); + } + } + + /* Netscape Install Dir */ + lrc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETSCAPE_KEY, 0, + KEY_ENUMERATE_SUB_KEYS, ®Key); + if (lrc == ERROR_SUCCESS) { + int i = 0; + TCHAR productName[255]; + HKEY prodKey; + HKEY mainKey; + + while ((lrc = RegEnumKey(regKey, i, productName, sizeof(productName))) + == ERROR_SUCCESS) { + i++; + lrc = RegOpenKeyEx(regKey, productName, 0, + KEY_ENUMERATE_SUB_KEYS, &prodKey); + if (lrc != ERROR_SUCCESS) { + if (verbose) { + winPerror(stderr, GetLastError(), + "Reading Netscape 4.0 prodkey"); + fprintf(stderr,"Product = %s\n",productName); + } + continue; + } + lrc = RegOpenKeyEx(prodKey, NETSCAPE_SUBKEY_1, 0, + KEY_QUERY_VALUE, &mainKey); + if (lrc != ERROR_SUCCESS) { + RegCloseKey(prodKey); + continue; + } + /* open main */ + lrc = RegQueryValueEx(mainKey, NETSCAPE_SUBKEY_2, NULL, NULL, + netscapeInstall, &nsInstallSize); + RegCloseKey(mainKey); + RegCloseKey(prodKey); + if (lrc == ERROR_SUCCESS) { + if (netscapeInstall[nsInstallSize-1] == 0) { + if (verbose) { + fprintf(stderr, + "Found Netscape 4.0 Install directory\n"); + } + dirPaths[NetscapeInstallDir] = netscapeInstall; + break; + } else { + fprintf(stderr, + "Reading Netscape 4.0 key: Value too large\n"); + } + } else { + if (verbose) { + winPerror(stderr, lrc, "Reading Netscape 4.0 key"); + } + } + } + if ((lrc != ERROR_SUCCESS) && (lrc != ERROR_NO_MORE_ITEMS)) { + winPerror(stderr, lrc, "EnumKey on Netscape Registry Key failed"); + } + } else { + if (verbose) { + winPerror(stderr, lrc, "Openning Netscape 4.0 key"); + } + } +#endif +#ifdef UNIX + dirPaths[HomeDir] = getenv("HOME"); +#endif + + /* OK, now search the directories and complete the Install */ + for (i=0; i < dirListCount; i++) { + char *dirPath = dirPaths[dirList[i].dirType]; + if (!dirPath) { + continue; + } + installAllPKCS11(dirPath, dirList[i].search, dirList[i].tail, + type, module); + } + + return 0; +} diff --git a/sources b/sources index 918b647..a58bfc3 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -78707a93046b53d9326e278cdbf7a6eb softhsm-1.3.6.tar.gz +7f7a450cf18611b37f67a326494de3aa softhsm-2.0.0b1.tar.gz