You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
25320 lines
775 KiB
25320 lines
775 KiB
From e9ef042fc45d2004c99dd7642d5032fd5832b270 Mon Sep 17 00:00:00 2001 |
|
From: Tomas Hozza <thozza@redhat.com> |
|
Date: Thu, 21 May 2015 10:52:03 +0200 |
|
Subject: [PATCH] native PKCS#11 |
|
|
|
Signed-off-by: Tomas Hozza <thozza@redhat.com> |
|
--- |
|
acconfig.h | 7 +- |
|
bin/check/Makefile.in | 3 +- |
|
bin/dig/Makefile.in | 13 +- |
|
bin/dig/dighost.c | 11 +- |
|
bin/dnssec/Makefile.in | 3 +- |
|
bin/dnssec/dnssec-dsfromkey.c | 9 +- |
|
bin/dnssec/dnssec-importkey.c | 93 +- |
|
bin/dnssec/dnssec-importkey.docbook | 58 +- |
|
bin/dnssec/dnssec-keyfromlabel.c | 31 +- |
|
bin/dnssec/dnssec-keyfromlabel.docbook | 43 +- |
|
bin/dnssec/dnssec-keygen.c | 21 +- |
|
bin/dnssec/dnssec-keygen.docbook | 13 +- |
|
bin/dnssec/dnssec-revoke.c | 14 +- |
|
bin/dnssec/dnssec-revoke.docbook | 11 +- |
|
bin/dnssec/dnssec-settime.c | 14 +- |
|
bin/dnssec/dnssec-settime.docbook | 11 +- |
|
bin/dnssec/dnssec-signzone.c | 14 +- |
|
bin/dnssec/dnssec-signzone.docbook | 15 +- |
|
bin/dnssec/dnssec-verify.c | 14 +- |
|
bin/dnssec/dnssec-verify.docbook | 17 + |
|
bin/dnssec/dnssectool.c | 2 +- |
|
bin/named/Makefile.in | 2 +- |
|
bin/named/include/named/globals.h | 4 +- |
|
bin/named/main.c | 6 + |
|
bin/named/named.docbook | 16 +- |
|
bin/named/server.c | 9 +- |
|
bin/nsupdate/Makefile.in | 6 +- |
|
bin/pkcs11/Makefile.in | 67 +- |
|
bin/pkcs11/pkcs11-destroy.8 | 10 +- |
|
bin/pkcs11/pkcs11-destroy.c | 153 +- |
|
bin/pkcs11/pkcs11-destroy.docbook | 19 +- |
|
bin/pkcs11/pkcs11-destroy.html | 22 +- |
|
bin/pkcs11/pkcs11-keygen.8 | 69 +- |
|
bin/pkcs11/pkcs11-keygen.c | 687 +++++++-- |
|
bin/pkcs11/pkcs11-keygen.docbook | 115 +- |
|
bin/pkcs11/pkcs11-keygen.html | 90 +- |
|
bin/pkcs11/pkcs11-list.c | 118 +- |
|
bin/pkcs11/pkcs11-tokens.8 | 51 + |
|
bin/pkcs11/pkcs11-tokens.c | 106 ++ |
|
bin/pkcs11/pkcs11-tokens.docbook | 86 ++ |
|
bin/pkcs11/pkcs11-tokens.html | 58 + |
|
bin/rndc/Makefile.in | 3 +- |
|
bin/tests/Makefile.in | 76 +- |
|
bin/tests/dst/dst_test.c | 7 +- |
|
bin/tests/dst/t_dst.c | 14 +- |
|
bin/tests/pkcs11/Makefile.in | 49 + |
|
bin/tests/pkcs11/benchmarks/Makefile.in | 79 + |
|
bin/tests/pkcs11/benchmarks/create.c | 260 ++++ |
|
bin/tests/pkcs11/benchmarks/find.c | 227 +++ |
|
bin/tests/pkcs11/benchmarks/genrsa.c | 295 ++++ |
|
bin/tests/pkcs11/benchmarks/login.c | 249 ++++ |
|
bin/tests/pkcs11/benchmarks/privrsa.c | 360 +++++ |
|
bin/tests/pkcs11/benchmarks/pubrsa.c | 281 ++++ |
|
bin/tests/pkcs11/benchmarks/random.c | 192 +++ |
|
bin/tests/pkcs11/benchmarks/session.c | 213 +++ |
|
bin/tests/pkcs11/benchmarks/sha1.c | 214 +++ |
|
bin/tests/pkcs11/benchmarks/sign.c | 368 +++++ |
|
bin/tests/pkcs11/benchmarks/verify.c | 292 ++++ |
|
bin/tests/pkcs11/pkcs11-hmacmd5.c | 332 +++++ |
|
bin/tests/pkcs11/pkcs11-md5sum.c | 235 +++ |
|
bin/tests/system/autosign/prereq.sh | 3 +- |
|
bin/tests/system/cleanpkcs11.sh | 6 +- |
|
bin/tests/system/conf.sh.in | 8 +- |
|
bin/tests/system/dnssec/prereq.sh | 3 +- |
|
bin/tests/system/ecdsa/prereq.sh.in | 15 +- |
|
bin/tests/system/gost/prereq.sh.in | 15 +- |
|
bin/tests/system/inline/clean.sh | 2 +- |
|
bin/tests/system/metadata/prereq.sh | 3 +- |
|
bin/tests/system/pending/prereq.sh | 23 +- |
|
bin/tests/system/pkcs11/clean.sh | 5 +- |
|
bin/tests/system/pkcs11/ns1/named.conf | 10 +- |
|
bin/tests/system/pkcs11/setup.sh | 64 +- |
|
bin/tests/system/pkcs11/tests.sh | 72 +- |
|
bin/tests/system/pkcs11ssl/clean.sh | 20 + |
|
bin/tests/system/pkcs11ssl/ns1/example.db.in | 29 + |
|
bin/tests/system/pkcs11ssl/ns1/named.conf | 52 + |
|
bin/tests/system/pkcs11ssl/prereq.sh | 34 + |
|
bin/tests/system/pkcs11ssl/setup.sh | 46 + |
|
bin/tests/system/pkcs11ssl/tests.sh | 71 + |
|
bin/tests/system/pkcs11ssl/usepkcs11 | 1 + |
|
bin/tests/system/rsabigexponent/Makefile.in | 2 +- |
|
bin/tests/system/rsabigexponent/bigkey.c | 18 +- |
|
bin/tests/system/rsabigexponent/prereq.sh | 3 +- |
|
bin/tests/system/smartsign/prereq.sh | 3 +- |
|
bin/tests/system/tkey/keycreate.c | 1 + |
|
bin/tests/system/tkey/prereq.sh | 3 +- |
|
config.h.in | 19 +- |
|
configure.in | 383 ++++- |
|
doc/arm/pkcs11.xml | 694 +++++---- |
|
lib/dns/Makefile.in | 16 +- |
|
lib/dns/dnssec.c | 12 +- |
|
lib/dns/ds.c | 44 +- |
|
lib/dns/dst_api.c | 73 +- |
|
lib/dns/dst_gost.h | 57 + |
|
lib/dns/dst_internal.h | 28 +- |
|
lib/dns/dst_parse.c | 36 +- |
|
lib/dns/dst_parse.h | 6 +- |
|
lib/dns/dst_pkcs11.h | 43 + |
|
lib/dns/dst_result.c | 3 +- |
|
lib/dns/gssapi_link.c | 1 + |
|
lib/dns/hmac_link.c | 47 +- |
|
lib/dns/include/dst/dst.h | 10 + |
|
lib/dns/include/dst/result.h | 3 +- |
|
lib/dns/openssldh_link.c | 7 + |
|
lib/dns/openssldsa_link.c | 36 +- |
|
lib/dns/opensslecdsa_link.c | 73 +- |
|
lib/dns/opensslgost_link.c | 180 ++- |
|
lib/dns/opensslrsa_link.c | 35 +- |
|
lib/dns/pkcs11.c | 50 + |
|
lib/dns/pkcs11dh_link.c | 1140 +++++++++++++++ |
|
lib/dns/pkcs11dsa_link.c | 1130 +++++++++++++++ |
|
lib/dns/pkcs11ecdsa_link.c | 1189 ++++++++++++++++ |
|
lib/dns/pkcs11gost_link.c | 949 +++++++++++++ |
|
lib/dns/pkcs11rsa_link.c | 1583 +++++++++++++++++++++ |
|
lib/dns/rdata/generic/dlv_32769.c | 9 + |
|
lib/dns/rdata/generic/ds_43.c | 10 + |
|
lib/dns/tests/Makefile.in | 14 +- |
|
lib/dns/tests/gost_test.c | 232 +++ |
|
lib/dns/tkey.c | 10 +- |
|
lib/dns/tsig.c | 14 +- |
|
lib/export/dns/Makefile.in | 4 +- |
|
lib/export/isc/Makefile.in | 5 +- |
|
lib/export/isc/unix/Makefile.in | 4 + |
|
lib/isc/Makefile.in | 14 +- |
|
lib/isc/entropy.c | 8 + |
|
lib/isc/hmacmd5.c | 166 +++ |
|
lib/isc/hmacsha.c | 375 +++++ |
|
lib/isc/include/Makefile.in | 2 +- |
|
lib/isc/include/isc/hmacmd5.h | 5 + |
|
lib/isc/include/isc/hmacsha.h | 9 + |
|
lib/isc/include/isc/md5.h | 5 + |
|
lib/isc/include/isc/resultclass.h | 2 +- |
|
lib/isc/include/isc/sha1.h | 5 + |
|
lib/isc/include/isc/sha2.h | 6 + |
|
lib/isc/include/pk11/Makefile.in | 38 + |
|
lib/isc/include/pk11/constants.h | 107 ++ |
|
lib/isc/include/pk11/internal.h | 46 + |
|
lib/isc/include/pk11/pk11.h | 295 ++++ |
|
lib/isc/include/pk11/result.h | 56 + |
|
lib/isc/include/pkcs11/Makefile.in | 40 + |
|
lib/isc/include/pkcs11/pkcs11.h | 299 ++++ |
|
lib/isc/include/pkcs11/pkcs11f.h | 912 ++++++++++++ |
|
lib/isc/include/pkcs11/pkcs11t.h | 1977 ++++++++++++++++++++++++++ |
|
lib/isc/md5.c | 50 + |
|
lib/isc/pk11.c | 1327 +++++++++++++++++ |
|
lib/isc/pk11_result.c | 85 ++ |
|
lib/isc/sha1.c | 50 +- |
|
lib/isc/sha2.c | 279 ++++ |
|
lib/isc/unix/Makefile.in | 4 +- |
|
lib/isc/unix/include/Makefile.in | 2 +- |
|
lib/isc/unix/include/pkcs11/Makefile.in | 33 + |
|
lib/isc/unix/include/pkcs11/cryptoki.h | 66 + |
|
lib/isc/unix/pk11_api.c | 673 +++++++++ |
|
153 files changed, 20271 insertions(+), 1183 deletions(-) |
|
create mode 100644 bin/pkcs11/pkcs11-tokens.8 |
|
create mode 100644 bin/pkcs11/pkcs11-tokens.c |
|
create mode 100644 bin/pkcs11/pkcs11-tokens.docbook |
|
create mode 100644 bin/pkcs11/pkcs11-tokens.html |
|
create mode 100644 bin/tests/pkcs11/Makefile.in |
|
create mode 100644 bin/tests/pkcs11/benchmarks/Makefile.in |
|
create mode 100644 bin/tests/pkcs11/benchmarks/create.c |
|
create mode 100644 bin/tests/pkcs11/benchmarks/find.c |
|
create mode 100644 bin/tests/pkcs11/benchmarks/genrsa.c |
|
create mode 100644 bin/tests/pkcs11/benchmarks/login.c |
|
create mode 100644 bin/tests/pkcs11/benchmarks/privrsa.c |
|
create mode 100644 bin/tests/pkcs11/benchmarks/pubrsa.c |
|
create mode 100644 bin/tests/pkcs11/benchmarks/random.c |
|
create mode 100644 bin/tests/pkcs11/benchmarks/session.c |
|
create mode 100644 bin/tests/pkcs11/benchmarks/sha1.c |
|
create mode 100644 bin/tests/pkcs11/benchmarks/sign.c |
|
create mode 100644 bin/tests/pkcs11/benchmarks/verify.c |
|
create mode 100644 bin/tests/pkcs11/pkcs11-hmacmd5.c |
|
create mode 100644 bin/tests/pkcs11/pkcs11-md5sum.c |
|
create mode 100644 bin/tests/system/pkcs11ssl/clean.sh |
|
create mode 100644 bin/tests/system/pkcs11ssl/ns1/example.db.in |
|
create mode 100644 bin/tests/system/pkcs11ssl/ns1/named.conf |
|
create mode 100644 bin/tests/system/pkcs11ssl/prereq.sh |
|
create mode 100644 bin/tests/system/pkcs11ssl/setup.sh |
|
create mode 100644 bin/tests/system/pkcs11ssl/tests.sh |
|
create mode 100644 bin/tests/system/pkcs11ssl/usepkcs11 |
|
create mode 100644 lib/dns/dst_gost.h |
|
create mode 100644 lib/dns/dst_pkcs11.h |
|
create mode 100644 lib/dns/pkcs11.c |
|
create mode 100644 lib/dns/pkcs11dh_link.c |
|
create mode 100644 lib/dns/pkcs11dsa_link.c |
|
create mode 100644 lib/dns/pkcs11ecdsa_link.c |
|
create mode 100644 lib/dns/pkcs11gost_link.c |
|
create mode 100644 lib/dns/pkcs11rsa_link.c |
|
create mode 100644 lib/dns/tests/gost_test.c |
|
create mode 100644 lib/isc/include/pk11/Makefile.in |
|
create mode 100644 lib/isc/include/pk11/constants.h |
|
create mode 100644 lib/isc/include/pk11/internal.h |
|
create mode 100644 lib/isc/include/pk11/pk11.h |
|
create mode 100644 lib/isc/include/pk11/result.h |
|
create mode 100644 lib/isc/include/pkcs11/Makefile.in |
|
create mode 100644 lib/isc/include/pkcs11/pkcs11.h |
|
create mode 100644 lib/isc/include/pkcs11/pkcs11f.h |
|
create mode 100644 lib/isc/include/pkcs11/pkcs11t.h |
|
create mode 100644 lib/isc/pk11.c |
|
create mode 100644 lib/isc/pk11_result.c |
|
create mode 100644 lib/isc/unix/include/pkcs11/Makefile.in |
|
create mode 100644 lib/isc/unix/include/pkcs11/cryptoki.h |
|
create mode 100644 lib/isc/unix/pk11_api.c |
|
|
|
diff --git a/acconfig.h b/acconfig.h |
|
index 3d412d9..c8e832a 100644 |
|
--- a/acconfig.h |
|
+++ b/acconfig.h |
|
@@ -132,14 +132,11 @@ int sigwait(const unsigned int *set, int *sig); |
|
/** define if you have strerror in the C library. */ |
|
#undef HAVE_STRERROR |
|
|
|
-/** Define if you are running under Compaq TruCluster. */ |
|
-#undef HAVE_TRUCLUSTER |
|
- |
|
/* Define if OpenSSL includes DSA support */ |
|
#undef HAVE_OPENSSL_DSA |
|
|
|
-/* Define if OpenSSL includes ECDSA support */ |
|
-#undef HAVE_OPENSSL_ECDSA |
|
+/* Define if you have getpassphrase in the C library. */ |
|
+#undef HAVE_GETPASSPHRASE |
|
|
|
/* Define to the length type used by the socket API (socklen_t, size_t, int). */ |
|
#undef ISC_SOCKADDR_LEN_T |
|
diff --git a/bin/check/Makefile.in b/bin/check/Makefile.in |
|
index c191605..d585480 100644 |
|
--- a/bin/check/Makefile.in |
|
+++ b/bin/check/Makefile.in |
|
@@ -75,7 +75,8 @@ named-checkconf@EXEEXT@: named-checkconf.@O@ check-tool.@O@ ${ISCDEPLIBS} \ |
|
export LIBS0="${BIND9LIBS} ${ISCCFGLIBS} ${DNSLIBS}"; \ |
|
${FINALBUILDCMD} |
|
|
|
-named-checkzone@EXEEXT@: named-checkzone.@O@ check-tool.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
+named-checkzone@EXEEXT@: named-checkzone.@O@ check-tool.@O@ \ |
|
+ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
export BASEOBJS="named-checkzone.@O@ check-tool.@O@"; \ |
|
export LIBS0="${ISCCFGLIBS} ${DNSLIBS}"; \ |
|
${FINALBUILDCMD} |
|
diff --git a/bin/dig/Makefile.in b/bin/dig/Makefile.in |
|
index 3864e06..43dd061 100644 |
|
--- a/bin/dig/Makefile.in |
|
+++ b/bin/dig/Makefile.in |
|
@@ -28,7 +28,7 @@ READLINE_LIB = @READLINE_LIB@ |
|
CINCLUDES = -I${srcdir}/include ${DNS_INCLUDES} ${BIND9_INCLUDES} \ |
|
${ISC_INCLUDES} ${LWRES_INCLUDES} ${ISCCFG_INCLUDES} |
|
|
|
-CDEFINES = -DVERSION=\"${VERSION}\" |
|
+CDEFINES = -DVERSION=\"${VERSION}\" @CRYPTO@ |
|
CWARNINGS = |
|
|
|
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@ |
|
@@ -44,13 +44,13 @@ BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ |
|
ISCDEPLIBS = ../../lib/isc/libisc.@A@ |
|
LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ |
|
|
|
-DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS} \ |
|
- ${LWRESDEPLIBS} |
|
+DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} \ |
|
+ ${ISCCFGDEPLIBS} ${LWRESDEPLIBS} |
|
|
|
-LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \ |
|
+LIBS = ${LWRESLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \ |
|
${ISCLIBS} @IDNLIBS@ @LIBS@ -lidn |
|
|
|
-NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \ |
|
+NOSYMLIBS = ${LWRESLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \ |
|
${ISCNOSYMLIBS} @IDNLIBS@ @LIBS@ -lidn |
|
|
|
SUBDIRS = |
|
@@ -75,14 +75,17 @@ EXT_CFLAGS = -DWITH_LIBIDN |
|
|
|
dig@EXEEXT@: dig.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS} |
|
export BASEOBJS="dig.@O@ dighost.@O@ ${UOBJS}"; \ |
|
+ export LIBS0="${DNSLIBS}"; \ |
|
${FINALBUILDCMD} |
|
|
|
host@EXEEXT@: host.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS} |
|
export BASEOBJS="host.@O@ dighost.@O@ ${UOBJS}"; \ |
|
+ export LIBS0="${DNSLIBS}"; \ |
|
${FINALBUILDCMD} |
|
|
|
nslookup@EXEEXT@: nslookup.@O@ dighost.@O@ ${UOBJS} ${DEPLIBS} |
|
export BASEOBJS="nslookup.@O@ dighost.@O@ ${READLINE_LIB} ${UOBJS}"; \ |
|
+ export LIBS0="${DNSLIBS}"; \ |
|
${FINALBUILDCMD} |
|
|
|
doc man:: ${MANOBJS} |
|
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c |
|
index e2bb110..5c03d95 100644 |
|
--- a/bin/dig/dighost.c |
|
+++ b/bin/dig/dighost.c |
|
@@ -105,6 +105,10 @@ |
|
|
|
#include <dig/dig.h> |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+#include <pk11/result.h> |
|
+#endif |
|
+ |
|
#if ! defined(NS_INADDRSZ) |
|
#define NS_INADDRSZ 4 |
|
#endif |
|
@@ -1347,6 +1351,11 @@ setup_libs(void) { |
|
|
|
debug("setup_libs()"); |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+ pk11_result_register(); |
|
+#endif |
|
+ dns_result_register(); |
|
+ |
|
result = isc_net_probeipv4(); |
|
if (result == ISC_R_SUCCESS) |
|
have_ipv4 = ISC_TRUE; |
|
@@ -1403,8 +1412,6 @@ setup_libs(void) { |
|
|
|
result = isc_mutex_init(&lookup_lock); |
|
check_result(result, "isc_mutex_init"); |
|
- |
|
- dns_result_register(); |
|
} |
|
|
|
/*% |
|
diff --git a/bin/dnssec/Makefile.in b/bin/dnssec/Makefile.in |
|
index ecb0fae..64e1846 100644 |
|
--- a/bin/dnssec/Makefile.in |
|
+++ b/bin/dnssec/Makefile.in |
|
@@ -25,7 +25,8 @@ top_srcdir = @top_srcdir@ |
|
|
|
CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} |
|
|
|
-CDEFINES = -DVERSION=\"${VERSION}\" @USE_PKCS11@ |
|
+CDEFINES = -DVERSION=\"${VERSION}\" @USE_PKCS11@ @PKCS11_ENGINE@ \ |
|
+ @CRYPTO@ -DPK11_LIB_LOCATION=\"@PKCS11_PROVIDER@\" |
|
CWARNINGS = |
|
|
|
DNSLIBS = ../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ |
|
diff --git a/bin/dnssec/dnssec-dsfromkey.c b/bin/dnssec/dnssec-dsfromkey.c |
|
index bfedae8..df616ac 100644 |
|
--- a/bin/dnssec/dnssec-dsfromkey.c |
|
+++ b/bin/dnssec/dnssec-dsfromkey.c |
|
@@ -49,6 +49,10 @@ |
|
|
|
#include <dst/dst.h> |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+#include <pk11/result.h> |
|
+#endif |
|
+ |
|
#include "dnssectool.h" |
|
|
|
#ifndef PATH_MAX |
|
@@ -370,6 +374,9 @@ main(int argc, char **argv) { |
|
if (result != ISC_R_SUCCESS) |
|
fatal("out of memory"); |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+ pk11_result_register(); |
|
+#endif |
|
dns_result_register(); |
|
|
|
isc_commandline_errprint = ISC_FALSE; |
|
@@ -448,7 +455,7 @@ main(int argc, char **argv) { |
|
else if (strcasecmp(algname, "SHA256") == 0 || |
|
strcasecmp(algname, "SHA-256") == 0) |
|
dtype = DNS_DSDIGEST_SHA256; |
|
-#ifdef HAVE_OPENSSL_GOST |
|
+#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) |
|
else if (strcasecmp(algname, "GOST") == 0) |
|
dtype = DNS_DSDIGEST_GOST; |
|
#endif |
|
diff --git a/bin/dnssec/dnssec-importkey.c b/bin/dnssec/dnssec-importkey.c |
|
index 00f9200..73166c4 100644 |
|
--- a/bin/dnssec/dnssec-importkey.c |
|
+++ b/bin/dnssec/dnssec-importkey.c |
|
@@ -47,6 +47,10 @@ |
|
|
|
#include <dst/dst.h> |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+#include <pk11/result.h> |
|
+#endif |
|
+ |
|
#include "dnssectool.h" |
|
|
|
#ifndef PATH_MAX |
|
@@ -61,7 +65,9 @@ static dns_fixedname_t fixed; |
|
static dns_name_t *name = NULL; |
|
static isc_mem_t *mctx = NULL; |
|
static isc_boolean_t setpub = ISC_FALSE, setdel = ISC_FALSE; |
|
+static isc_boolean_t setttl = ISC_FALSE; |
|
static isc_stdtime_t pub = 0, del = 0; |
|
+static dns_ttl_t ttl = 0; |
|
|
|
static isc_result_t |
|
initname(char *setname) { |
|
@@ -190,9 +196,10 @@ static void |
|
emit(const char *dir, dns_rdata_t *rdata) { |
|
isc_result_t result; |
|
char keystr[DST_KEY_FORMATSIZE]; |
|
- char newname[1024]; |
|
+ char pubname[1024]; |
|
+ char priname[1024]; |
|
isc_buffer_t buf; |
|
- dst_key_t *key = NULL; |
|
+ dst_key_t *key = NULL, *tmp = NULL; |
|
|
|
isc_buffer_init(&buf, rdata->data, rdata->length); |
|
isc_buffer_add(&buf, rdata->length); |
|
@@ -201,18 +208,36 @@ emit(const char *dir, dns_rdata_t *rdata) { |
|
fatal("dst_key_fromdns: %s", isc_result_totext(result)); |
|
} |
|
|
|
- dst_key_setexternal(key, ISC_TRUE); |
|
- if (setpub) |
|
- dst_key_settime(key, DST_TIME_PUBLISH, pub); |
|
- if (setdel) |
|
- dst_key_settime(key, DST_TIME_DELETE, del); |
|
- |
|
- isc_buffer_init(&buf, newname, sizeof(newname)); |
|
+ isc_buffer_init(&buf, pubname, sizeof(pubname)); |
|
result = dst_key_buildfilename(key, DST_TYPE_PUBLIC, dir, &buf); |
|
if (result != ISC_R_SUCCESS) { |
|
fatal("Failed to build public key filename: %s", |
|
isc_result_totext(result)); |
|
} |
|
+ isc_buffer_init(&buf, priname, sizeof(priname)); |
|
+ result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf); |
|
+ if (result != ISC_R_SUCCESS) { |
|
+ fatal("Failed to build private key filename: %s", |
|
+ isc_result_totext(result)); |
|
+ } |
|
+ |
|
+ result = dst_key_fromfile(dst_key_name(key), dst_key_id(key), |
|
+ dst_key_alg(key), |
|
+ DST_TYPE_PUBLIC | DST_TYPE_PRIVATE, |
|
+ dir, mctx, &tmp); |
|
+ if (result == ISC_R_SUCCESS) { |
|
+ if (dst_key_isprivate(tmp) && !dst_key_isexternal(tmp)) |
|
+ fatal("Private key already exists in %s", priname); |
|
+ dst_key_free(&tmp); |
|
+ } |
|
+ |
|
+ dst_key_setexternal(key, ISC_TRUE); |
|
+ if (setpub) |
|
+ dst_key_settime(key, DST_TIME_PUBLISH, pub); |
|
+ if (setdel) |
|
+ dst_key_settime(key, DST_TIME_DELETE, del); |
|
+ if (setttl) |
|
+ dst_key_setttl(key, ttl); |
|
|
|
result = dst_key_tofile(key, DST_TYPE_PUBLIC|DST_TYPE_PRIVATE, |
|
dir); |
|
@@ -221,8 +246,7 @@ emit(const char *dir, dns_rdata_t *rdata) { |
|
fatal("Failed to write key %s: %s", keystr, |
|
isc_result_totext(result)); |
|
} |
|
- |
|
- printf("%s\n", newname); |
|
+ printf("%s\n", pubname); |
|
|
|
isc_buffer_clear(&buf); |
|
result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, dir, &buf); |
|
@@ -230,7 +254,7 @@ emit(const char *dir, dns_rdata_t *rdata) { |
|
fatal("Failed to build private key filename: %s", |
|
isc_result_totext(result)); |
|
} |
|
- printf("%s\n", newname); |
|
+ printf("%s\n", priname); |
|
dst_key_free(&key); |
|
} |
|
|
|
@@ -240,13 +264,21 @@ usage(void) ISC_PLATFORM_NORETURN_POST; |
|
static void |
|
usage(void) { |
|
fprintf(stderr, "Usage:\n"); |
|
- fprintf(stderr, " %s options [-K dir] file\n\n", program); |
|
+ fprintf(stderr, " %s options [-K dir] keyfile\n\n", program); |
|
+ fprintf(stderr, " %s options -f file [keyname]\n\n", program); |
|
fprintf(stderr, "Version: %s\n", VERSION); |
|
fprintf(stderr, "Options:\n"); |
|
- fprintf(stderr, " -v <verbose level>\n"); |
|
+ fprintf(stderr, " -f file: read key from zone file\n"); |
|
fprintf(stderr, " -K <directory>: directory in which to store " |
|
- "the keyset files\n"); |
|
- fprintf(stderr, " -f file: read keyset from zone file\n"); |
|
+ "the key files\n"); |
|
+ fprintf(stderr, " -L ttl: set default key TTL\n"); |
|
+ fprintf(stderr, " -v <verbose level>\n"); |
|
+ fprintf(stderr, " -h: print usage and exit\n"); |
|
+ fprintf(stderr, "Timing options:\n"); |
|
+ fprintf(stderr, " -P date/[+-]offset/none: set/unset key " |
|
+ "publication date\n"); |
|
+ fprintf(stderr, " -D date/[+-]offset/none: set/unset key " |
|
+ "deletion date\n"); |
|
|
|
exit (-1); |
|
} |
|
@@ -274,15 +306,19 @@ main(int argc, char **argv) { |
|
if (result != ISC_R_SUCCESS) |
|
fatal("out of memory"); |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+ pk11_result_register(); |
|
+#endif |
|
dns_result_register(); |
|
|
|
isc_commandline_errprint = ISC_FALSE; |
|
|
|
- while ((ch = isc_commandline_parse(argc, argv, "D:f:hK:P:v:")) != -1) { |
|
+#define CMDLINE_FLAGS "D:f:hK:L:P:v:" |
|
+ while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { |
|
switch (ch) { |
|
- case 'D': |
|
- if (setdel) |
|
- fatal("-D specified more than once"); |
|
+ case 'D': |
|
+ if (setdel) |
|
+ fatal("-D specified more than once"); |
|
|
|
setdel = ISC_TRUE; |
|
del = strtotime(isc_commandline_argument, now, now); |
|
@@ -292,9 +328,16 @@ main(int argc, char **argv) { |
|
if (strlen(dir) == 0U) |
|
fatal("directory must be non-empty string"); |
|
break; |
|
- case 'P': |
|
- if (setpub) |
|
- fatal("-P specified more than once"); |
|
+ case 'L': |
|
+ if (strcmp(isc_commandline_argument, "none") == 0) |
|
+ ttl = 0; |
|
+ else |
|
+ ttl = strtottl(isc_commandline_argument); |
|
+ setttl = ISC_TRUE; |
|
+ break; |
|
+ case 'P': |
|
+ if (setpub) |
|
+ fatal("-P specified more than once"); |
|
|
|
setpub = ISC_TRUE; |
|
pub = strtotime(isc_commandline_argument, now, now); |
|
@@ -346,8 +389,8 @@ main(int argc, char **argv) { |
|
dns_rdataset_init(&rdataset); |
|
|
|
if (filename != NULL) { |
|
- if (argc < isc_commandline_index + 1 && filename != NULL) { |
|
- /* using zone name as the zone file name */ |
|
+ if (argc < isc_commandline_index + 1) { |
|
+ /* using filename as zone name */ |
|
namestr = filename; |
|
} else |
|
namestr = argv[isc_commandline_index]; |
|
diff --git a/bin/dnssec/dnssec-importkey.docbook b/bin/dnssec/dnssec-importkey.docbook |
|
index b8d160c..853db30 100644 |
|
--- a/bin/dnssec/dnssec-importkey.docbook |
|
+++ b/bin/dnssec/dnssec-importkey.docbook |
|
@@ -44,22 +44,45 @@ |
|
<refsynopsisdiv> |
|
<cmdsynopsis> |
|
<command>dnssec-importkey</command> |
|
- <arg><option>-f <replaceable class="parameter">filename</replaceable></option></arg> |
|
<arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg> |
|
+ <arg><option>-L <replaceable class="parameter">ttl</replaceable></option></arg> |
|
<arg><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg> |
|
<arg><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg> |
|
<arg><option>-h</option></arg> |
|
<arg><option>-v <replaceable class="parameter">level</replaceable></option></arg> |
|
- <arg><option>keyname</option></arg> |
|
+ <arg choice="req"><option>keyfile</option></arg> |
|
+ </cmdsynopsis> |
|
+ <cmdsynopsis> |
|
+ <command>dnssec-importkey</command> |
|
+ <arg choice="req"><option>-f <replaceable class="parameter">filename</replaceable></option></arg> |
|
+ <arg><option>-K <replaceable class="parameter">directory</replaceable></option></arg> |
|
+ <arg><option>-L <replaceable class="parameter">ttl</replaceable></option></arg> |
|
+ <arg><option>-P <replaceable class="parameter">date/offset</replaceable></option></arg> |
|
+ <arg><option>-D <replaceable class="parameter">date/offset</replaceable></option></arg> |
|
+ <arg><option>-h</option></arg> |
|
+ <arg><option>-v <replaceable class="parameter">level</replaceable></option></arg> |
|
+ <arg><option>dnsname</option></arg> |
|
</cmdsynopsis> |
|
</refsynopsisdiv> |
|
|
|
<refsect1> |
|
<title>DESCRIPTION</title> |
|
<para><command>dnssec-importkey</command> |
|
- read a DNSKEY record and generated a .key/.private key pair. |
|
- Publication (<option>-P</option>) and deletions (<option>-D</option>) |
|
- times can be set for the key. |
|
+ reads a public DNSKEY record and generates a pair of |
|
+ .key/.private files. The DNSKEY record may be read from an |
|
+ existing .key file, in which case a corresponding .private file |
|
+ will be generated, or it may be read from any other file or |
|
+ from the standard input, in which case both .key and .private |
|
+ files will be generated. |
|
+ </para> |
|
+ <para> |
|
+ The newly-created .private file does <emphasis>not</command> |
|
+ contain private key data, and cannot be used for signing. |
|
+ However, having a .private file makes it possible to set |
|
+ publication (<option>-P</option>) and deletion |
|
+ (<option>-D</option>) times for the key, which means the |
|
+ public key can be added to and removed from the DNSKEY RRset |
|
+ on schedule even if the true private key is stored offline. |
|
</para> |
|
</refsect1> |
|
|
|
@@ -70,9 +93,16 @@ |
|
<varlistentry> |
|
<term>-f <replaceable class="parameter">filename</replaceable></term> |
|
<listitem> |
|
- <para> |
|
- Filename to read the key from. |
|
- </para> |
|
+ <para> |
|
+ Zone file mode: instead of a public keyfile name, the argument |
|
+ is the DNS domain name of a zone master file, which can be read |
|
+ from <option>file</option>. If the domain name is the same as |
|
+ <option>file</option>, then it may be omitted. |
|
+ </para> |
|
+ <para> |
|
+ If <option>file</option> is set to <literal>"-"</literal>, then |
|
+ the zone data is read from the standard input. |
|
+ </para> |
|
</listitem> |
|
</varlistentry> |
|
|
|
@@ -93,7 +123,7 @@ |
|
into a DNSKEY RR. If the key is imported into a zone, |
|
this is the TTL that will be used for it, unless there was |
|
already a DNSKEY RRset in place, in which case the existing TTL |
|
- would take precedence. importkey the default TTL to |
|
+ would take precedence. Setting the default TTL to |
|
<literal>0</literal> or <literal>none</literal> removes it. |
|
</para> |
|
</listitem> |
|
@@ -160,6 +190,16 @@ |
|
</refsect1> |
|
|
|
<refsect1> |
|
+ <title>FILES</title> |
|
+ <para> |
|
+ A keyfile can be designed by the key identification |
|
+ <filename>Knnnn.+aaa+iiiii</filename> or the full file name |
|
+ <filename>Knnnn.+aaa+iiiii.key</filename> as generated by |
|
+ <refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum>. |
|
+ </para> |
|
+ </refsect1> |
|
+ |
|
+ <refsect1> |
|
<title>SEE ALSO</title> |
|
<para><citerefentry> |
|
<refentrytitle>dnssec-keygen</refentrytitle><manvolnum>8</manvolnum> |
|
diff --git a/bin/dnssec/dnssec-keyfromlabel.c b/bin/dnssec/dnssec-keyfromlabel.c |
|
index 3ad00d7..cc212e1 100644 |
|
--- a/bin/dnssec/dnssec-keyfromlabel.c |
|
+++ b/bin/dnssec/dnssec-keyfromlabel.c |
|
@@ -43,6 +43,10 @@ |
|
|
|
#include <dst/dst.h> |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+#include <pk11/result.h> |
|
+#endif |
|
+ |
|
#include "dnssectool.h" |
|
|
|
#define MAX_RSA 4096 /* should be long enough... */ |
|
@@ -76,10 +80,15 @@ usage(void) { |
|
"NSEC3RSASHA1 if using -3)\n"); |
|
fprintf(stderr, " -3: use NSEC3-capable algorithm\n"); |
|
fprintf(stderr, " -c class (default: IN)\n"); |
|
-#ifdef USE_PKCS11 |
|
- fprintf(stderr, " -E enginename (default: pkcs11)\n"); |
|
+ fprintf(stderr, " -E <engine>:\n"); |
|
+#if defined(PKCS11CRYPTO) |
|
+ fprintf(stderr, " path to PKCS#11 provider library " |
|
+ "(default is %s)\n", PK11_LIB_LOCATION); |
|
+#elif defined(USE_PKCS11) |
|
+ fprintf(stderr, " name of an OpenSSL engine to use " |
|
+ "(default is \"pkcs11\")\n"); |
|
#else |
|
- fprintf(stderr, " -E enginename\n"); |
|
+ fprintf(stderr, " name of an OpenSSL engine to use\n"); |
|
#endif |
|
fprintf(stderr, " -f keyflag: KSK | REVOKE\n"); |
|
fprintf(stderr, " -K directory: directory in which to place " |
|
@@ -116,7 +125,7 @@ main(int argc, char **argv) { |
|
char *nametype = NULL, *type = NULL; |
|
const char *directory = NULL; |
|
#ifdef USE_PKCS11 |
|
- const char *engine = "pkcs11"; |
|
+ const char *engine = PKCS11_ENGINE; |
|
#else |
|
const char *engine = NULL; |
|
#endif |
|
@@ -161,6 +170,9 @@ main(int argc, char **argv) { |
|
|
|
RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS); |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+ pk11_result_register(); |
|
+#endif |
|
dns_result_register(); |
|
|
|
isc_commandline_errprint = ISC_FALSE; |
|
@@ -334,16 +346,15 @@ main(int argc, char **argv) { |
|
if (argc > isc_commandline_index + 1) |
|
fatal("extraneous arguments"); |
|
|
|
- if (strchr(label, ':') == NULL && |
|
- engine != NULL && strlen(engine) != 0U) { |
|
+ if (strchr(label, ':') == NULL) { |
|
char *l; |
|
int len; |
|
|
|
- len = strlen(label) + strlen(engine) + 2; |
|
+ len = strlen(label) + 8; |
|
l = isc_mem_allocate(mctx, len); |
|
if (l == NULL) |
|
fatal("cannot allocate memory"); |
|
- snprintf(l, len, "%s:%s", engine, label); |
|
+ snprintf(l, len, "pkcs11:%s", label); |
|
isc_mem_free(mctx, label); |
|
label = l; |
|
} |
|
@@ -460,7 +471,7 @@ main(int argc, char **argv) { |
|
|
|
/* associate the key */ |
|
ret = dst_key_fromlabel(name, alg, flags, protocol, |
|
- rdclass, engine, label, NULL, mctx, &key); |
|
+ rdclass, "pkcs11", label, NULL, mctx, &key); |
|
isc_entropy_stopcallbacksources(ectx); |
|
|
|
if (ret != ISC_R_SUCCESS) { |
|
@@ -468,7 +479,7 @@ main(int argc, char **argv) { |
|
char algstr[DNS_SECALG_FORMATSIZE]; |
|
dns_name_format(name, namestr, sizeof(namestr)); |
|
dns_secalg_format(alg, algstr, sizeof(algstr)); |
|
- fatal("failed to get key %s/%s: %s\n", |
|
+ fatal("failed to get key %s/%s: %s", |
|
namestr, algstr, isc_result_totext(ret)); |
|
/* NOTREACHED */ |
|
exit(-1); |
|
diff --git a/bin/dnssec/dnssec-keyfromlabel.docbook b/bin/dnssec/dnssec-keyfromlabel.docbook |
|
index 0dd3c0e..c48a100 100644 |
|
--- a/bin/dnssec/dnssec-keyfromlabel.docbook |
|
+++ b/bin/dnssec/dnssec-keyfromlabel.docbook |
|
@@ -133,8 +133,15 @@ |
|
<term>-E <replaceable class="parameter">engine</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Specifies the name of the crypto hardware (OpenSSL engine). |
|
- When compiled with PKCS#11 support it defaults to "pkcs11". |
|
+ Specifies the cryptographic hardware to use. |
|
+ </para> |
|
+ <para> |
|
+ When BIND is built with OpenSSL PKCS#11 support, this defaults |
|
+ to the string "pkcs11", which identifies an OpenSSL engine |
|
+ that can drive a cryptographic accelerator or hardware service |
|
+ module. When BIND is built with native PKCS#11 cryptography |
|
+ (--enable-native-pkcs11), it defaults to the path of the PKCS#11 |
|
+ provider library specified via "--with-pkcs11". |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
@@ -143,9 +150,32 @@ |
|
<term>-l <replaceable class="parameter">label</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Specifies the label of the key pair in the crypto hardware. |
|
- The label may be preceded by an optional OpenSSL engine name, |
|
- separated by a colon, as in "pkcs11:keylabel". |
|
+ Specifies the label for a key pair in the crypto hardware. |
|
+ </para> |
|
+ <para> |
|
+ When <acronym>BIND</acronym> 9 is built with OpenSSL-based |
|
+ PKCS#11 support, the label is an arbitrary string that |
|
+ identifies a particular key. It may be preceded by an |
|
+ optional OpenSSL engine name, followed by a colon, as in |
|
+ "pkcs11:<replaceable>keylabel<replaceable>". |
|
+ </para> |
|
+ <para> |
|
+ When <acronym>BIND</acronym> 9 is built with native PKCS#11 |
|
+ support, the label is a PKCS#11 URI string in the format |
|
+ "pkcs11:<option>keyword</option>=<replaceable>value</replaceable><optional>;<option>keyword</option>=<replaceable>value</replaceable>;...</optional>" |
|
+ Keywords include "token", which identifies the HSM; "object", which |
|
+ identifies the key; and "pin-source", which identifies a file from |
|
+ which the HSM's PIN code can be obtained. The label will be |
|
+ stored in the on-disk "private" file. |
|
+ </para> |
|
+ <para> |
|
+ If the label contains a |
|
+ <option>pin-source</option> field, tools using the generated |
|
+ key files will be able to use the HSM for signing and other |
|
+ operations without any need for an operator to manually enter |
|
+ a PIN. Note: Making the HSM's PIN accessible in this manner |
|
+ may reduce the security advantage of using an HSM; be sure |
|
+ this is what you want to do before making use of this feature. |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
@@ -429,7 +459,8 @@ |
|
<refentrytitle>dnssec-signzone</refentrytitle><manvolnum>8</manvolnum> |
|
</citerefentry>, |
|
<citetitle>BIND 9 Administrator Reference Manual</citetitle>, |
|
- <citetitle>RFC 4034</citetitle>. |
|
+ <citetitle>RFC 4034</citetitle>, |
|
+ <citetitle>The PKCS#11 URI Scheme (draft-pechanec-pkcs11uri-13)</citetitle>. |
|
</para> |
|
</refsect1> |
|
|
|
diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c |
|
index 7061829..97b96ee 100644 |
|
--- a/bin/dnssec/dnssec-keygen.c |
|
+++ b/bin/dnssec/dnssec-keygen.c |
|
@@ -58,6 +58,10 @@ |
|
|
|
#include <dst/dst.h> |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+#include <pk11/result.h> |
|
+#endif |
|
+ |
|
#include "dnssectool.h" |
|
|
|
#define MAX_RSA 4096 /* should be long enough... */ |
|
@@ -119,10 +123,15 @@ usage(void) { |
|
fprintf(stderr, " (DNSKEY generation defaults to ZONE)\n"); |
|
fprintf(stderr, " -c <class>: (default: IN)\n"); |
|
fprintf(stderr, " -d <digest bits> (0 => max, default)\n"); |
|
-#ifdef USE_PKCS11 |
|
- fprintf(stderr, " -E <engine name> (default \"pkcs11\")\n"); |
|
+ fprintf(stderr, " -E <engine>:\n"); |
|
+#if defined(PKCS11CRYPTO) |
|
+ fprintf(stderr, " path to PKCS#11 provider library " |
|
+ "(default is %s)\n", PK11_LIB_LOCATION); |
|
+#elif defined(USE_PKCS11) |
|
+ fprintf(stderr, " name of an OpenSSL engine to use " |
|
+ "(default is \"pkcs11\")\n"); |
|
#else |
|
- fprintf(stderr, " -E <engine name>\n"); |
|
+ fprintf(stderr, " name of an OpenSSL engine to use\n"); |
|
#endif |
|
fprintf(stderr, " -f <keyflag>: KSK | REVOKE\n"); |
|
fprintf(stderr, " -g <generator>: use specified generator " |
|
@@ -134,7 +143,6 @@ usage(void) { |
|
"records with (default: 0)\n"); |
|
fprintf(stderr, " -T <rrtype>: DNSKEY | KEY (default: DNSKEY; " |
|
"use KEY for SIG(0))\n"); |
|
- fprintf(stderr, " ECCGOST:\tignored\n"); |
|
fprintf(stderr, " -t <type>: " |
|
"AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF " |
|
"(default: AUTHCONF)\n"); |
|
@@ -223,7 +231,7 @@ main(int argc, char **argv) { |
|
isc_log_t *log = NULL; |
|
isc_entropy_t *ectx = NULL; |
|
#ifdef USE_PKCS11 |
|
- const char *engine = "pkcs11"; |
|
+ const char *engine = PKCS11_ENGINE; |
|
#else |
|
const char *engine = NULL; |
|
#endif |
|
@@ -250,6 +258,9 @@ main(int argc, char **argv) { |
|
if (argc == 1) |
|
usage(); |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+ pk11_result_register(); |
|
+#endif |
|
dns_result_register(); |
|
|
|
isc_commandline_errprint = ISC_FALSE; |
|
diff --git a/bin/dnssec/dnssec-keygen.docbook b/bin/dnssec/dnssec-keygen.docbook |
|
index bc50c02..4c693eb 100644 |
|
--- a/bin/dnssec/dnssec-keygen.docbook |
|
+++ b/bin/dnssec/dnssec-keygen.docbook |
|
@@ -224,10 +224,15 @@ |
|
<term>-E <replaceable class="parameter">engine</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Uses a crypto hardware (OpenSSL engine) for random number |
|
- and, when supported, key generation. When compiled with PKCS#11 |
|
- support it defaults to pkcs11; the empty name resets it to |
|
- no engine. |
|
+ Specifies the cryptographic hardware to use, when applicable. |
|
+ </para> |
|
+ <para> |
|
+ When BIND is built with OpenSSL PKCS#11 support, this defaults |
|
+ to the string "pkcs11", which identifies an OpenSSL engine |
|
+ that can drive a cryptographic accelerator or hardware service |
|
+ module. When BIND is built with native PKCS#11 cryptography |
|
+ (--enable-native-pkcs11), it defaults to the path of the PKCS#11 |
|
+ provider library specified via "--with-pkcs11". |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
diff --git a/bin/dnssec/dnssec-revoke.c b/bin/dnssec/dnssec-revoke.c |
|
index 7b11581..7b5aaee 100644 |
|
--- a/bin/dnssec/dnssec-revoke.c |
|
+++ b/bin/dnssec/dnssec-revoke.c |
|
@@ -38,6 +38,10 @@ |
|
|
|
#include <dst/dst.h> |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+#include <pk11/result.h> |
|
+#endif |
|
+ |
|
#include "dnssectool.h" |
|
|
|
const char *program = "dnssec-revoke"; |
|
@@ -53,7 +57,10 @@ usage(void) { |
|
fprintf(stderr, "Usage:\n"); |
|
fprintf(stderr, " %s [options] keyfile\n\n", program); |
|
fprintf(stderr, "Version: %s\n", VERSION); |
|
-#ifdef USE_PKCS11 |
|
+#if defined(PKCS11CRYPTO) |
|
+ fprintf(stderr, " -E engine: specify PKCS#11 provider " |
|
+ "(default: %s)\n", PK11_LIB_LOCATION); |
|
+#elif defined(USE_PKCS11) |
|
fprintf(stderr, " -E engine: specify OpenSSL engine " |
|
"(default \"pkcs11\")\n"); |
|
#else |
|
@@ -76,7 +83,7 @@ int |
|
main(int argc, char **argv) { |
|
isc_result_t result; |
|
#ifdef USE_PKCS11 |
|
- const char *engine = "pkcs11"; |
|
+ const char *engine = PKCS11_ENGINE; |
|
#else |
|
const char *engine = NULL; |
|
#endif |
|
@@ -100,6 +107,9 @@ main(int argc, char **argv) { |
|
if (result != ISC_R_SUCCESS) |
|
fatal("Out of memory"); |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+ pk11_result_register(); |
|
+#endif |
|
dns_result_register(); |
|
|
|
isc_commandline_errprint = ISC_FALSE; |
|
diff --git a/bin/dnssec/dnssec-revoke.docbook b/bin/dnssec/dnssec-revoke.docbook |
|
index 4062f5e..0c1dd4e 100644 |
|
--- a/bin/dnssec/dnssec-revoke.docbook |
|
+++ b/bin/dnssec/dnssec-revoke.docbook |
|
@@ -109,8 +109,15 @@ |
|
<term>-E <replaceable class="parameter">engine</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Use the given OpenSSL engine. When compiled with PKCS#11 support |
|
- it defaults to pkcs11; the empty name resets it to no engine. |
|
+ Specifies the cryptographic hardware to use, when applicable. |
|
+ </para> |
|
+ <para> |
|
+ When BIND is built with OpenSSL PKCS#11 support, this defaults |
|
+ to the string "pkcs11", which identifies an OpenSSL engine |
|
+ that can drive a cryptographic accelerator or hardware service |
|
+ module. When BIND is built with native PKCS#11 cryptography |
|
+ (--enable-native-pkcs11), it defaults to the path of the PKCS#11 |
|
+ provider library specified via "--with-pkcs11". |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
diff --git a/bin/dnssec/dnssec-settime.c b/bin/dnssec/dnssec-settime.c |
|
index 108d803..c71cac7 100644 |
|
--- a/bin/dnssec/dnssec-settime.c |
|
+++ b/bin/dnssec/dnssec-settime.c |
|
@@ -41,6 +41,10 @@ |
|
|
|
#include <dst/dst.h> |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+#include <pk11/result.h> |
|
+#endif |
|
+ |
|
#include "dnssectool.h" |
|
|
|
const char *program = "dnssec-settime"; |
|
@@ -57,7 +61,10 @@ usage(void) { |
|
fprintf(stderr, " %s [options] keyfile\n\n", program); |
|
fprintf(stderr, "Version: %s\n", VERSION); |
|
fprintf(stderr, "General options:\n"); |
|
-#ifdef USE_PKCS11 |
|
+#if defined(PKCS11CRYPTO) |
|
+ fprintf(stderr, " -E engine: specify PKCS#11 provider " |
|
+ "(default: %s)\n", PK11_LIB_LOCATION); |
|
+#elif defined(USE_PKCS11) |
|
fprintf(stderr, " -E engine: specify OpenSSL engine " |
|
"(default \"pkcs11\")\n"); |
|
#else |
|
@@ -119,7 +126,7 @@ int |
|
main(int argc, char **argv) { |
|
isc_result_t result; |
|
#ifdef USE_PKCS11 |
|
- const char *engine = "pkcs11"; |
|
+ const char *engine = PKCS11_ENGINE; |
|
#else |
|
const char *engine = NULL; |
|
#endif |
|
@@ -165,6 +172,9 @@ main(int argc, char **argv) { |
|
|
|
setup_logging(verbose, mctx, &log); |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+ pk11_result_register(); |
|
+#endif |
|
dns_result_register(); |
|
|
|
isc_commandline_errprint = ISC_FALSE; |
|
diff --git a/bin/dnssec/dnssec-settime.docbook b/bin/dnssec/dnssec-settime.docbook |
|
index bc6870b..3540bf2 100644 |
|
--- a/bin/dnssec/dnssec-settime.docbook |
|
+++ b/bin/dnssec/dnssec-settime.docbook |
|
@@ -153,8 +153,15 @@ |
|
<term>-E <replaceable class="parameter">engine</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Use the given OpenSSL engine. When compiled with PKCS#11 support |
|
- it defaults to pkcs11; the empty name resets it to no engine. |
|
+ Specifies the cryptographic hardware to use, when applicable. |
|
+ </para> |
|
+ <para> |
|
+ When BIND is built with OpenSSL PKCS#11 support, this defaults |
|
+ to the string "pkcs11", which identifies an OpenSSL engine |
|
+ that can drive a cryptographic accelerator or hardware service |
|
+ module. When BIND is built with native PKCS#11 cryptography |
|
+ (--enable-native-pkcs11), it defaults to the path of the PKCS#11 |
|
+ provider library specified via "--with-pkcs11". |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c |
|
index 83456a7..128c753 100644 |
|
--- a/bin/dnssec/dnssec-signzone.c |
|
+++ b/bin/dnssec/dnssec-signzone.c |
|
@@ -86,6 +86,10 @@ |
|
|
|
#include <dst/dst.h> |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+#include <pk11/result.h> |
|
+#endif |
|
+ |
|
#include "dnssectool.h" |
|
|
|
#ifndef PATH_MAX |
|
@@ -2938,7 +2942,10 @@ usage(void) { |
|
fprintf(stderr, "verify generated signatures\n"); |
|
fprintf(stderr, "\t-c class (IN)\n"); |
|
fprintf(stderr, "\t-E engine:\n"); |
|
-#ifdef USE_PKCS11 |
|
+#if defined(PKCS11CRYPTO) |
|
+ fprintf(stderr, "\t\tpath to PKCS#11 provider library " |
|
+ "(default is %s)\n", PK11_LIB_LOCATION); |
|
+#elif defined(USE_PKCS11) |
|
fprintf(stderr, "\t\tname of an OpenSSL engine to use " |
|
"(default is \"pkcs11\")\n"); |
|
#else |
|
@@ -3033,7 +3040,7 @@ main(int argc, char *argv[]) { |
|
isc_log_t *log = NULL; |
|
isc_boolean_t pseudorandom = ISC_FALSE; |
|
#ifdef USE_PKCS11 |
|
- const char *engine = "pkcs11"; |
|
+ const char *engine = PKCS11_ENGINE; |
|
#else |
|
const char *engine = NULL; |
|
#endif |
|
@@ -3085,6 +3092,9 @@ main(int argc, char *argv[]) { |
|
if (result != ISC_R_SUCCESS) |
|
fatal("out of memory"); |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+ pk11_result_register(); |
|
+#endif |
|
dns_result_register(); |
|
|
|
isc_commandline_errprint = ISC_FALSE; |
|
diff --git a/bin/dnssec/dnssec-signzone.docbook b/bin/dnssec/dnssec-signzone.docbook |
|
index e427fc1..c46f43c 100644 |
|
--- a/bin/dnssec/dnssec-signzone.docbook |
|
+++ b/bin/dnssec/dnssec-signzone.docbook |
|
@@ -176,10 +176,17 @@ |
|
<term>-E <replaceable class="parameter">engine</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Uses a crypto hardware (OpenSSL engine) for the crypto operations |
|
- it supports, for instance signing with private keys from |
|
- a secure key store. When compiled with PKCS#11 support |
|
- it defaults to pkcs11; the empty name resets it to no engine. |
|
+ When applicable, specifies the hardware to use for |
|
+ cryptographic operations, such as a secure key store used |
|
+ for signing. |
|
+ </para> |
|
+ <para> |
|
+ When BIND is built with OpenSSL PKCS#11 support, this defaults |
|
+ to the string "pkcs11", which identifies an OpenSSL engine |
|
+ that can drive a cryptographic accelerator or hardware service |
|
+ module. When BIND is built with native PKCS#11 cryptography |
|
+ (--enable-native-pkcs11), it defaults to the path of the PKCS#11 |
|
+ provider library specified via "--with-pkcs11". |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
diff --git a/bin/dnssec/dnssec-verify.c b/bin/dnssec/dnssec-verify.c |
|
index 682896c..817e380 100644 |
|
--- a/bin/dnssec/dnssec-verify.c |
|
+++ b/bin/dnssec/dnssec-verify.c |
|
@@ -69,6 +69,10 @@ |
|
|
|
#include <dst/dst.h> |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+#include <pk11/result.h> |
|
+#endif |
|
+ |
|
#include "dnssectool.h" |
|
|
|
const char *program = "dnssec-verify"; |
|
@@ -137,7 +141,10 @@ usage(void) { |
|
fprintf(stderr, "\t\tfile format of input zonefile (text)\n"); |
|
fprintf(stderr, "\t-c class (IN)\n"); |
|
fprintf(stderr, "\t-E engine:\n"); |
|
-#ifdef USE_PKCS11 |
|
+#if defined(PKCS11CRYPTO) |
|
+ fprintf(stderr, "\t\tpath to PKCS#11 provider library " |
|
+ "(default is %s)\n", PK11_LIB_LOCATION); |
|
+#elif defined(USE_PKCS11) |
|
fprintf(stderr, "\t\tname of an OpenSSL engine to use " |
|
"(default is \"pkcs11\")\n"); |
|
#else |
|
@@ -156,7 +163,7 @@ main(int argc, char *argv[]) { |
|
isc_result_t result; |
|
isc_log_t *log = NULL; |
|
#ifdef USE_PKCS11 |
|
- const char *engine = "pkcs11"; |
|
+ const char *engine = PKCS11_ENGINE; |
|
#else |
|
const char *engine = NULL; |
|
#endif |
|
@@ -195,6 +202,9 @@ main(int argc, char *argv[]) { |
|
if (result != ISC_R_SUCCESS) |
|
fatal("out of memory"); |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+ pk11_result_register(); |
|
+#endif |
|
dns_result_register(); |
|
|
|
isc_commandline_errprint = ISC_FALSE; |
|
diff --git a/bin/dnssec/dnssec-verify.docbook b/bin/dnssec/dnssec-verify.docbook |
|
index 0835df1..875f3ed 100644 |
|
--- a/bin/dnssec/dnssec-verify.docbook |
|
+++ b/bin/dnssec/dnssec-verify.docbook |
|
@@ -78,6 +78,23 @@ |
|
</varlistentry> |
|
|
|
<varlistentry> |
|
+ <term>-E <replaceable class="parameter">engine</replaceable></term> |
|
+ <listitem> |
|
+ <para> |
|
+ Specifies the cryptographic hardware to use, when applicable. |
|
+ </para> |
|
+ <para> |
|
+ When BIND is built with OpenSSL PKCS#11 support, this defaults |
|
+ to the string "pkcs11", which identifies an OpenSSL engine |
|
+ that can drive a cryptographic accelerator or hardware service |
|
+ module. When BIND is built with native PKCS#11 cryptography |
|
+ (--enable-native-pkcs11), it defaults to the path of the PKCS#11 |
|
+ provider library specified via "--with-pkcs11". |
|
+ </para> |
|
+ </listitem> |
|
+ </varlistentry> |
|
+ |
|
+ <varlistentry> |
|
<term>-I <replaceable class="parameter">input-format</replaceable></term> |
|
<listitem> |
|
<para> |
|
diff --git a/bin/dnssec/dnssectool.c b/bin/dnssec/dnssectool.c |
|
index 5f5f7d8..c68ae69 100644 |
|
--- a/bin/dnssec/dnssectool.c |
|
+++ b/bin/dnssec/dnssectool.c |
|
@@ -319,7 +319,7 @@ strtotime(const char *str, isc_int64_t now, isc_int64_t base) { |
|
isc_result_t result; |
|
const char *orig = str; |
|
char *endp; |
|
- int n; |
|
+ size_t n; |
|
|
|
if ((str[0] == '0' || str[0] == '-') && str[1] == '\0') |
|
return ((isc_stdtime_t) 0); |
|
diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in |
|
index 68c42a8..cd65777 100644 |
|
--- a/bin/named/Makefile.in |
|
+++ b/bin/named/Makefile.in |
|
@@ -51,7 +51,7 @@ CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include -I. \ |
|
${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} ${ISC_INCLUDES} \ |
|
${DLZDRIVER_INCLUDES} ${DBDRIVER_INCLUDES} @DST_OPENSSL_INC@ |
|
|
|
-CDEFINES = @CONTRIB_DLZ@ @USE_PKCS11@ @USE_OPENSSL@ |
|
+CDEFINES = @CONTRIB_DLZ@ @USE_PKCS11@ @PKCS11_ENGINE@ @CRYPTO@ |
|
|
|
CWARNINGS = |
|
|
|
diff --git a/bin/named/include/named/globals.h b/bin/named/include/named/globals.h |
|
index cbc14d8..aad462d 100644 |
|
--- a/bin/named/include/named/globals.h |
|
+++ b/bin/named/include/named/globals.h |
|
@@ -146,8 +146,8 @@ EXTERN const char * lwresd_g_defaultpidfile INIT(NS_LOCALSTATEDIR |
|
|
|
EXTERN const char * ns_g_username INIT(NULL); |
|
|
|
-#ifdef USE_PKCS11 |
|
-EXTERN const char * ns_g_engine INIT("pkcs11"); |
|
+#if defined(USE_PKCS11) |
|
+EXTERN const char * ns_g_engine INIT(PKCS11_ENGINE); |
|
#else |
|
EXTERN const char * ns_g_engine INIT(NULL); |
|
#endif |
|
diff --git a/bin/named/main.c b/bin/named/main.c |
|
index 15905ef..a00687f 100644 |
|
--- a/bin/named/main.c |
|
+++ b/bin/named/main.c |
|
@@ -51,6 +51,9 @@ |
|
#include <dns/view.h> |
|
|
|
#include <dst/result.h> |
|
+#ifdef PKCS11CRYPTO |
|
+#include <pk11/result.h> |
|
+#endif |
|
|
|
#include <dlz/dlz_dlopen_driver.h> |
|
|
|
@@ -1081,6 +1084,9 @@ main(int argc, char *argv[]) { |
|
dns_result_register(); |
|
dst_result_register(); |
|
isccc_result_register(); |
|
+#ifdef PKCS11CRYPTO |
|
+ pk11_result_register(); |
|
+#endif |
|
|
|
parse_command_line(argc, argv); |
|
|
|
diff --git a/bin/named/named.docbook b/bin/named/named.docbook |
|
index 1f08e19..8f46aac 100644 |
|
--- a/bin/named/named.docbook |
|
+++ b/bin/named/named.docbook |
|
@@ -153,11 +153,17 @@ |
|
<term>-E <replaceable class="parameter">engine-name</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Use a crypto hardware (OpenSSL engine) for the crypto operations |
|
- it supports, for instance re-signing with private keys from |
|
- a secure key store. When compiled with PKCS#11 support |
|
- <replaceable class="parameter">engine-name</replaceable> |
|
- defaults to pkcs11, the empty name resets it to no engine. |
|
+ When applicable, specifies the hardware to use for |
|
+ cryptographic operations, such as a secure key store used |
|
+ for signing. |
|
+ </para> |
|
+ <para> |
|
+ When BIND is built with OpenSSL PKCS#11 support, this defaults |
|
+ to the string "pkcs11", which identifies an OpenSSL engine |
|
+ that can drive a cryptographic accelerator or hardware service |
|
+ module. When BIND is built with native PKCS#11 cryptography |
|
+ (--enable-native-pkcs11), it defaults to the path of the PKCS#11 |
|
+ provider library specified via "--with-pkcs11". |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
diff --git a/bin/named/server.c b/bin/named/server.c |
|
index 56df6bf..227c646 100644 |
|
--- a/bin/named/server.c |
|
+++ b/bin/named/server.c |
|
@@ -6215,6 +6215,11 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { |
|
server->in_roothints = NULL; |
|
server->blackholeacl = NULL; |
|
|
|
+ /* Must be first. */ |
|
+ CHECKFATAL(dst_lib_init2(ns_g_mctx, ns_g_entropy, |
|
+ ns_g_engine, ISC_ENTROPY_GOODONLY), |
|
+ "initializing DST"); |
|
+ |
|
CHECKFATAL(dns_rootns_create(mctx, dns_rdataclass_in, NULL, |
|
&server->in_roothints), |
|
"setting up root hints"); |
|
@@ -6231,10 +6236,6 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) { |
|
ISC_R_NOMEMORY : ISC_R_SUCCESS, |
|
"allocating reload event"); |
|
|
|
- CHECKFATAL(dst_lib_init2(ns_g_mctx, ns_g_entropy, |
|
- ns_g_engine, ISC_ENTROPY_GOODONLY), |
|
- "initializing DST"); |
|
- |
|
server->tkeyctx = NULL; |
|
CHECKFATAL(dns_tkeyctx_create(ns_g_mctx, ns_g_entropy, |
|
&server->tkeyctx), |
|
diff --git a/bin/nsupdate/Makefile.in b/bin/nsupdate/Makefile.in |
|
index 09e6c14..e258ffc 100644 |
|
--- a/bin/nsupdate/Makefile.in |
|
+++ b/bin/nsupdate/Makefile.in |
|
@@ -46,9 +46,11 @@ ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@ |
|
|
|
DEPLIBS = ${DNSDEPLIBS} ${BIND9DEPLIBS} ${ISCDEPLIBS} ${ISCCFGDEPLIBS} |
|
|
|
-LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@ |
|
+LIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \ |
|
+ ${ISCLIBS} @LIBS@ |
|
|
|
-NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} ${ISCNOSYMLIBS} @LIBS@ |
|
+NOSYMLIBS = ${LWRESLIBS} ${DNSLIBS} ${BIND9LIBS} ${ISCCFGLIBS} \ |
|
+ ${ISCNOSYMLIBS} @LIBS@ |
|
|
|
SUBDIRS = |
|
|
|
diff --git a/bin/pkcs11/Makefile.in b/bin/pkcs11/Makefile.in |
|
index 407d977..15d3fb5 100644 |
|
--- a/bin/pkcs11/Makefile.in |
|
+++ b/bin/pkcs11/Makefile.in |
|
@@ -20,38 +20,51 @@ top_srcdir = @top_srcdir@ |
|
|
|
@BIND9_MAKE_INCLUDES@ |
|
|
|
-PROVIDER = @PKCS11_PROVIDER@ |
|
+CINCLUDES = ${ISC_INCLUDES} |
|
|
|
-CINCLUDES = -I${srcdir}/include -I${srcdir}/unix |
|
+CDEFINES = |
|
|
|
-CDEFINES = -DPK11_LIB_LOCATION=\"${PROVIDER}\" |
|
+ISCLIBS = ../../lib/isc/libisc.@A@ |
|
+ |
|
+ISCDEPLIBS = ../../lib/isc/libisc.@A@ |
|
+ |
|
+DEPLIBS = ${ISCDEPLIBS} |
|
|
|
# if FORCE_STATIC_PROVIDER: LIBS = ${PROVIDER} |
|
-LIBS = -ldl |
|
+LIBS = ${ISCLIBS} @LIBS@ |
|
|
|
-SUBDIRS = |
|
+SUBDIRS = benchmarks |
|
|
|
-TARGETS = pkcs11-keygen@EXEEXT@ pkcs11-list@EXEEXT@ \ |
|
- pkcs11-destroy@EXEEXT@ |
|
-SRCS = pkcs11-keygen.c pkcs11-list.c pkcs11-destroy.c |
|
+TARGETS = pkcs11-list@EXEEXT@ pkcs11-destroy@EXEEXT@ \ |
|
+ pkcs11-keygen@EXEEXT@ pkcs11-tokens@EXEEXT@ |
|
+SRCS = pkcs11-list.c pkcs11-destroy.c \ |
|
+ pkcs11-keygen.c pkcs11-tokens.c |
|
+OBJS = pkcs11-list.@O@ pkcs11-destroy.@O@ \ |
|
+ pkcs11-keygen.@O@ pkcs11-tokens.@O@ |
|
|
|
-MANPAGES = pkcs11-keygen.8 pkcs11-list.8 pkcs11-destroy.8 |
|
-HTMLPAGES = pkcs11-keygen.html pkcs11-list.html pkcs11-destroy.html |
|
+MANPAGES = pkcs11-list.8 pkcs11-destroy.8 \ |
|
+ pkcs11-keygen.8 pkcs11-tokens.8 |
|
+HTMLPAGES = pkcs11-list.html pkcs11-destroy.html \ |
|
+ pkcs11-keygen.html pkcs11-tokens.html |
|
MANOBJS = ${MANPAGES} ${HTMLPAGES} |
|
|
|
@BIND9_MAKE_RULES@ |
|
|
|
-pkcs11-keygen@EXEEXT@: @srcdir@/pkcs11-keygen.c |
|
- ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ |
|
- -o $@ @srcdir@/pkcs11-keygen.c ${LIBS} |
|
- |
|
-pkcs11-list@EXEEXT@: @srcdir@/pkcs11-list.c |
|
- ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ |
|
- -o $@ @srcdir@/pkcs11-list.c ${LIBS} |
|
- |
|
-pkcs11-destroy@EXEEXT@: @srcdir@/pkcs11-destroy.c |
|
- ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ |
|
- -o $@ @srcdir@/pkcs11-destroy.c ${LIBS} |
|
+pkcs11-list@EXEEXT@: @srcdir@/pkcs11-list.@O@ ${DEPLIBS} |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ |
|
+ -o $@ @srcdir@/pkcs11-list.@O@ ${LIBS} |
|
+ |
|
+pkcs11-destroy@EXEEXT@: @srcdir@/pkcs11-destroy.@O@ ${DEPLIBS} |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ |
|
+ -o $@ @srcdir@/pkcs11-destroy.@O@ ${LIBS} |
|
+ |
|
+pkcs11-keygen@EXEEXT@: @srcdir@/pkcs11-keygen.@O@ ${DEPLIBS} |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ |
|
+ -o $@ @srcdir@/pkcs11-keygen.@O@ ${LIBS} |
|
+ |
|
+pkcs11-tokens@EXEEXT@: @srcdir@/pkcs11-tokens.@O@ ${DEPLIBS} |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ |
|
+ -o $@ @srcdir@/pkcs11-tokens.@O@ ${LIBS} |
|
|
|
doc man:: ${MANOBJS} |
|
|
|
@@ -63,12 +76,14 @@ installdirs: |
|
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${mandir}/man8 |
|
|
|
install:: ${TARGETS} installdirs |
|
- ${INSTALL_PROGRAM} pkcs11-keygen@EXEEXT@ ${DESTDIR}${sbindir} |
|
- ${INSTALL_PROGRAM} pkcs11-list@EXEEXT@ ${DESTDIR}${sbindir} |
|
- ${INSTALL_PROGRAM} pkcs11-destroy@EXEEXT@ ${DESTDIR}${sbindir} |
|
- ${INSTALL_DATA} ${srcdir}/pkcs11-keygen.8 ${DESTDIR}${mandir}/man8 |
|
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} pkcs11-list@EXEEXT@ ${DESTDIR}${sbindir} |
|
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} pkcs11-destroy@EXEEXT@ ${DESTDIR}${sbindir} |
|
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} pkcs11-keygen@EXEEXT@ ${DESTDIR}${sbindir} |
|
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} pkcs11-tokens@EXEEXT@ ${DESTDIR}${sbindir} |
|
${INSTALL_DATA} ${srcdir}/pkcs11-list.8 ${DESTDIR}${mandir}/man8 |
|
${INSTALL_DATA} ${srcdir}/pkcs11-destroy.8 ${DESTDIR}${mandir}/man8 |
|
+ ${INSTALL_DATA} ${srcdir}/pkcs11-keygen.8 ${DESTDIR}${mandir}/man8 |
|
+ ${INSTALL_DATA} ${srcdir}/pkcs11-tokens.8 ${DESTDIR}${mandir}/man8 |
|
|
|
clean distclean:: |
|
- rm -f ${TARGETS} |
|
+ rm -f ${OBJS} ${TARGETS} |
|
diff --git a/bin/pkcs11/pkcs11-destroy.8 b/bin/pkcs11/pkcs11-destroy.8 |
|
index aff35b3..25323ca 100644 |
|
--- a/bin/pkcs11/pkcs11-destroy.8 |
|
+++ b/bin/pkcs11/pkcs11-destroy.8 |
|
@@ -32,7 +32,7 @@ |
|
pkcs11\-destroy \- destroy PKCS#11 objects |
|
.SH "SYNOPSIS" |
|
.HP 15 |
|
-\fBpkcs11\-destroy\fR [\fB\-m\ \fR\fB\fImodule\fR\fR] [\fB\-s\ \fR\fB\fIslot\fR\fR] {\-i\ \fIID\fR | \-l\ \fIlabel\fR} [\fB\-p\ \fR\fB\fIPIN\fR\fR] |
|
+\fBpkcs11\-destroy\fR [\fB\-m\ \fR\fB\fImodule\fR\fR] [\fB\-s\ \fR\fB\fIslot\fR\fR] {\-i\ \fIID\fR | \-l\ \fIlabel\fR} [\fB\-p\ \fR\fB\fIPIN\fR\fR] [\fB\-w\ \fR\fB\fIseconds\fR\fR] |
|
.SH "DESCRIPTION" |
|
.PP |
|
\fBpkcs11\-destroy\fR |
|
@@ -41,7 +41,7 @@ destroys keys stored in a PKCS#11 device, identified by their |
|
or |
|
\fBlabel\fR. |
|
.PP |
|
-Matching keys are displayed before being destroyed. There is a five second delay to allow the user to interrupt the process before the destruction takes place. |
|
+Matching keys are displayed before being destroyed. By default, there is a five second delay to allow the user to interrupt the process before the destruction takes place. |
|
.SH "ARGUMENTS" |
|
.PP |
|
\-m \fImodule\fR |
|
@@ -70,6 +70,12 @@ Specify the PIN for the device. If no PIN is provided on the command line, |
|
\fBpkcs11\-destroy\fR |
|
will prompt for it. |
|
.RE |
|
+.PP |
|
+\-w \fIseconds\fR |
|
+.RS 4 |
|
+Specify how long to pause before carrying out key destruction. The default is five seconds. If set to |
|
+0, destruction will be immediate. |
|
+.RE |
|
.SH "SEE ALSO" |
|
.PP |
|
\fBpkcs11\-list\fR(3), |
|
diff --git a/bin/pkcs11/pkcs11-destroy.c b/bin/pkcs11/pkcs11-destroy.c |
|
index 0f46a89..2905395 100644 |
|
--- a/bin/pkcs11/pkcs11-destroy.c |
|
+++ b/bin/pkcs11/pkcs11-destroy.c |
|
@@ -40,7 +40,10 @@ |
|
|
|
/* $Id: pkcs11-destroy.c,v 1.8 2010/01/13 21:19:52 fdupont Exp $ */ |
|
|
|
-/* pkcs11-destroy [-m module] [-s $slot] [-i $id | -l $label] [-p $pin] */ |
|
+/* |
|
+ * pkcs11-destroy [-m module] [-s $slot] [-i $id | -l $label] |
|
+ * [-p $pin] [ -w $wait ] |
|
+ */ |
|
|
|
/*! \file */ |
|
|
|
@@ -52,74 +55,70 @@ |
|
#include <errno.h> |
|
#include <string.h> |
|
#include <sys/types.h> |
|
-#include "cryptoki.h" |
|
|
|
-#ifdef WIN32 |
|
-#define sleep(x) Sleep(x) |
|
-#include "win32.c" |
|
-#else |
|
-#ifndef FORCE_STATIC_PROVIDER |
|
-#include "unix.c" |
|
-#endif |
|
-#endif |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
|
|
#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
#define getpassphrase(x) getpass(x) |
|
#endif |
|
|
|
int |
|
-main(int argc, char *argv[]) |
|
-{ |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
CK_RV rv; |
|
CK_SLOT_ID slot = 0; |
|
CK_SESSION_HANDLE hSession; |
|
- CK_UTF8CHAR *pin = NULL; |
|
CK_BYTE attr_id[2]; |
|
CK_OBJECT_HANDLE akey[50]; |
|
+ pk11_context_t pctx; |
|
+ char *lib_name = NULL; |
|
char *label = NULL; |
|
+ char *pin = NULL; |
|
int error = 0; |
|
- unsigned int id = 0, i = 0; |
|
+ unsigned int id = 0, i = 0, wait = 5; |
|
int c, errflg = 0; |
|
CK_ULONG ulObjectCount; |
|
CK_ATTRIBUTE search_template[] = { |
|
{CKA_ID, &attr_id, sizeof(attr_id)} |
|
}; |
|
- char *pk11_provider; |
|
unsigned int j, len; |
|
- extern char *optarg; |
|
- extern int optopt; |
|
- |
|
- pk11_provider = getenv("PKCS11_PROVIDER"); |
|
- if (pk11_provider != NULL) |
|
- pk11_libname = pk11_provider; |
|
|
|
- while ((c = getopt(argc, argv, ":m:s:i:l:p:")) != -1) { |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:i:l:p:w:")) != -1) { |
|
switch (c) { |
|
case 'm': |
|
- pk11_libname = optarg; |
|
+ lib_name = isc_commandline_argument; |
|
break; |
|
case 's': |
|
- slot = atoi(optarg); |
|
+ slot = atoi(isc_commandline_argument); |
|
break; |
|
case 'i': |
|
- id = atoi(optarg); |
|
+ id = atoi(isc_commandline_argument); |
|
id &= 0xffff; |
|
break; |
|
case 'l': |
|
- label = optarg; |
|
+ label = isc_commandline_argument; |
|
break; |
|
case 'p': |
|
- pin = (CK_UTF8CHAR *)optarg; |
|
+ pin = isc_commandline_argument; |
|
+ break; |
|
+ case 'w': |
|
+ wait = atoi(isc_commandline_argument); |
|
break; |
|
case ':': |
|
fprintf(stderr, |
|
"Option -%c requires an operand\n", |
|
- optopt); |
|
+ isc_commandline_option); |
|
errflg++; |
|
break; |
|
case '?': |
|
default: |
|
- fprintf(stderr, "Unrecognised option: -%c\n", optopt); |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
errflg++; |
|
} |
|
} |
|
@@ -127,56 +126,49 @@ main(int argc, char *argv[]) |
|
if (errflg || (id && (label != NULL))) { |
|
fprintf(stderr, "Usage:\n"); |
|
fprintf(stderr, "\tpkcs11-destroy [-m module] [-s slot] " |
|
- "[-i id | -l label] [-p pin]\n"); |
|
+ "[-i id | -l label] [-p pin] [-w waittime]\n"); |
|
exit(1); |
|
} |
|
|
|
if (id) { |
|
- printf("id %i\n", id); |
|
attr_id[0] = (id >> 8) & 0xff; |
|
attr_id[1] = id & 0xff; |
|
} else if (label) { |
|
- printf("label %s\n", label); |
|
search_template[0].type = CKA_LABEL; |
|
search_template[0].pValue = label; |
|
search_template[0].ulValueLen = strlen(label); |
|
} |
|
|
|
- /* Initialize the CRYPTOKI library */ |
|
- rv = C_Initialize(NULL_PTR); |
|
- if (rv != CKR_OK) { |
|
- if (rv == 0xfe) |
|
- fprintf(stderr, |
|
- "Can't load or link module \"%s\"\n", |
|
- pk11_libname); |
|
- else |
|
- fprintf(stderr, "C_Initialize: Error = 0x%.8lX\n", rv); |
|
- exit(1); |
|
- } |
|
+ pk11_result_register(); |
|
|
|
- /* Open a session on the slot found */ |
|
- rv = C_OpenSession(slot, CKF_RW_SESSION+CKF_SERIAL_SESSION, |
|
- NULL_PTR, NULL_PTR, &hSession); |
|
- if (rv != CKR_OK) { |
|
- fprintf(stderr, "C_OpenSession: Error = 0x%.8lX\n", rv); |
|
- error = 1; |
|
- goto exit_program; |
|
- } |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
|
|
if (pin == NULL) |
|
- pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: "); |
|
+ pin = getpassphrase("Enter Pin: "); |
|
|
|
/* Login to the Token (Keystore) */ |
|
- rv = C_Login(hSession, CKU_USER, pin, strlen((char *)pin)); |
|
- memset(pin, 0, strlen((char *)pin)); |
|
- if (rv != CKR_OK) { |
|
- fprintf(stderr, "C_Login: Error = 0x%.8lX\n", rv); |
|
- error = 1; |
|
- goto exit_session; |
|
+ result = pk11_get_session(&pctx, OP_ANY, ISC_FALSE, ISC_TRUE, |
|
+ ISC_TRUE, (const char *) pin, slot); |
|
+ if (result == PK11_R_NORANDOMSERVICE || |
|
+ result == PK11_R_NODIGESTSERVICE || |
|
+ result == PK11_R_NOAESSERVICE) { |
|
+ fprintf(stderr, "Warning: %s\n", isc_result_totext(result)); |
|
+ fprintf(stderr, "This HSM will not work with BIND 9 " |
|
+ "using native PKCS#11.\n"); |
|
+ } else if (result != ISC_R_SUCCESS) { |
|
+ fprintf(stderr, "Unrecoverable error initializing " |
|
+ "PKCS#11: %s\n", isc_result_totext(result)); |
|
+ exit(1); |
|
} |
|
|
|
- rv = C_FindObjectsInit(hSession, search_template, |
|
- ((id != 0) || (label != NULL)) ? 1 : 0); |
|
+ memset(pin, 0, strlen(pin)); |
|
+ |
|
+ hSession = pctx.session; |
|
+ |
|
+ rv = pkcs_C_FindObjectsInit(hSession, search_template, |
|
+ ((id != 0) || (label != NULL)) ? 1 : 0); |
|
|
|
if (rv != CKR_OK) { |
|
fprintf(stderr, "C_FindObjectsInit: Error = 0x%.8lX\n", rv); |
|
@@ -184,13 +176,19 @@ main(int argc, char *argv[]) |
|
goto exit_session; |
|
} |
|
|
|
- rv = C_FindObjects(hSession, akey, 50, &ulObjectCount); |
|
+ rv = pkcs_C_FindObjects(hSession, akey, 50, &ulObjectCount); |
|
if (rv != CKR_OK) { |
|
fprintf(stderr, "C_FindObjects: Error = 0x%.8lX\n", rv); |
|
error = 1; |
|
goto exit_search; |
|
} |
|
|
|
+ if (ulObjectCount == 0) { |
|
+ printf("No matching key objects found.\n"); |
|
+ goto exit_search; |
|
+ } else |
|
+ printf("Key object%s found:\n", ulObjectCount > 1 ? "s" : ""); |
|
+ |
|
for (i = 0; i < ulObjectCount; i++) { |
|
CK_OBJECT_CLASS oclass = 0; |
|
CK_BYTE labelbuf[64 + 1]; |
|
@@ -204,7 +202,8 @@ main(int argc, char *argv[]) |
|
memset(labelbuf, 0, sizeof(labelbuf)); |
|
memset(idbuf, 0, sizeof(idbuf)); |
|
|
|
- rv = C_GetAttributeValue(hSession, akey[i], attr_template, 3); |
|
+ rv = pkcs_C_GetAttributeValue(hSession, akey[i], |
|
+ attr_template, 3); |
|
if (rv != CKR_OK) { |
|
fprintf(stderr, |
|
"C_GetAttributeValue[%u]: rv = 0x%.8lX\n", |
|
@@ -213,7 +212,7 @@ main(int argc, char *argv[]) |
|
goto exit_search; |
|
} |
|
len = attr_template[2].ulValueLen; |
|
- printf("object[%u]: class %lu label '%s' id[%lu] ", |
|
+ printf(" object[%u]: class %lu, label '%s', id[%lu] ", |
|
i, oclass, labelbuf, attr_template[2].ulValueLen); |
|
if (len > 4) |
|
len = 4; |
|
@@ -227,32 +226,40 @@ main(int argc, char *argv[]) |
|
printf("\n"); |
|
} |
|
|
|
- /* give a chance to kill this */ |
|
- printf("sleeping 5 seconds...\n"); |
|
- sleep(5); |
|
+ if (wait != 0) { |
|
+ printf("WARNING: This action is irreversible! " |
|
+ "Destroying key objects in %d seconds\n ", wait); |
|
+ for (i = 0; i < wait; i++) { |
|
+ printf("."); |
|
+ fflush(stdout); |
|
+ sleep(1); |
|
+ } |
|
+ printf("\n"); |
|
+ } |
|
|
|
for (i = 0; i < ulObjectCount; i++) { |
|
- rv = C_DestroyObject(hSession, akey[i]); |
|
+ rv = pkcs_C_DestroyObject(hSession, akey[i]); |
|
if (rv != CKR_OK) { |
|
fprintf(stderr, |
|
- "C_DestroyObject[%u]: rv = 0x%.8lX\n", |
|
+ "C_DestroyObject[%u] failed: rv = 0x%.8lX\n", |
|
i, rv); |
|
error = 1; |
|
} |
|
} |
|
|
|
+ if (error == 0) |
|
+ printf("Destruction complete.\n"); |
|
+ |
|
exit_search: |
|
- rv = C_FindObjectsFinal(hSession); |
|
+ rv = pkcs_C_FindObjectsFinal(hSession); |
|
if (rv != CKR_OK) { |
|
fprintf(stderr, "C_FindObjectsFinal: Error = 0x%.8lX\n", rv); |
|
error = 1; |
|
} |
|
|
|
exit_session: |
|
- (void)C_CloseSession(hSession); |
|
- |
|
- exit_program: |
|
- (void)C_Finalize(NULL_PTR); |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
|
|
exit(error); |
|
} |
|
diff --git a/bin/pkcs11/pkcs11-destroy.docbook b/bin/pkcs11/pkcs11-destroy.docbook |
|
index b4c2048..45c0208 100644 |
|
--- a/bin/pkcs11/pkcs11-destroy.docbook |
|
+++ b/bin/pkcs11/pkcs11-destroy.docbook |
|
@@ -37,6 +37,7 @@ |
|
<docinfo> |
|
<copyright> |
|
<year>2009</year> |
|
+ <year>2014</year> |
|
<holder>Internet Systems Consortium, Inc. ("ISC")</holder> |
|
</copyright> |
|
</docinfo> |
|
@@ -51,6 +52,7 @@ |
|
<arg choice="plain">-l <replaceable class="parameter">label</replaceable></arg> |
|
</group> |
|
<arg><option>-p <replaceable class="parameter">PIN</replaceable></option></arg> |
|
+ <arg><option>-w <replaceable class="parameter">seconds</replaceable></option></arg> |
|
</cmdsynopsis> |
|
</refsynopsisdiv> |
|
|
|
@@ -62,9 +64,9 @@ |
|
<option>label</option>. |
|
</para> |
|
<para> |
|
- Matching keys are displayed before being destroyed. There is a |
|
- five second delay to allow the user to interrupt the process |
|
- before the destruction takes place. |
|
+ Matching keys are displayed before being destroyed. By default, |
|
+ there is a five second delay to allow the user to interrupt the |
|
+ process before the destruction takes place. |
|
</para> |
|
</refsect1> |
|
|
|
@@ -119,6 +121,17 @@ |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
+ |
|
+ <varlistentry> |
|
+ <term>-w <replaceable class="parameter">seconds</replaceable></term> |
|
+ <listitem> |
|
+ <para> |
|
+ Specify how long to pause before carrying out key destruction. |
|
+ The default is five seconds. If set to <literal>0</literal>, |
|
+ destruction will be immediate. |
|
+ </para> |
|
+ </listitem> |
|
+ </varlistentry> |
|
</variablelist> |
|
</refsect1> |
|
|
|
diff --git a/bin/pkcs11/pkcs11-destroy.html b/bin/pkcs11/pkcs11-destroy.html |
|
index afc6e36..899b3e9 100644 |
|
--- a/bin/pkcs11/pkcs11-destroy.html |
|
+++ b/bin/pkcs11/pkcs11-destroy.html |
|
@@ -29,23 +29,23 @@ |
|
</div> |
|
<div class="refsynopsisdiv"> |
|
<h2>Synopsis</h2> |
|
-<div class="cmdsynopsis"><p><code class="command">pkcs11-destroy</code> [<code class="option">-m <em class="replaceable"><code>module</code></em></code>] [<code class="option">-s <em class="replaceable"><code>slot</code></em></code>] { -i <em class="replaceable"><code>ID</code></em> | -l <em class="replaceable"><code>label</code></em> } [<code class="option">-p <em class="replaceable"><code>PIN</code></em></code>]</p></div> |
|
+<div class="cmdsynopsis"><p><code class="command">pkcs11-destroy</code> [<code class="option">-m <em class="replaceable"><code>module</code></em></code>] [<code class="option">-s <em class="replaceable"><code>slot</code></em></code>] { -i <em class="replaceable"><code>ID</code></em> | -l <em class="replaceable"><code>label</code></em> } [<code class="option">-p <em class="replaceable"><code>PIN</code></em></code>] [<code class="option">-w <em class="replaceable"><code>seconds</code></em></code>]</p></div> |
|
</div> |
|
<div class="refsect1" lang="en"> |
|
-<a name="id2543384"></a><h2>DESCRIPTION</h2> |
|
+<a name="id2543393"></a><h2>DESCRIPTION</h2> |
|
<p> |
|
<span><strong class="command">pkcs11-destroy</strong></span> destroys keys stored in a |
|
PKCS#11 device, identified by their <code class="option">ID</code> or |
|
<code class="option">label</code>. |
|
</p> |
|
<p> |
|
- Matching keys are displayed before being destroyed. There is a |
|
- five second delay to allow the user to interrupt the process |
|
- before the destruction takes place. |
|
+ Matching keys are displayed before being destroyed. By default, |
|
+ there is a five second delay to allow the user to interrupt the |
|
+ process before the destruction takes place. |
|
</p> |
|
</div> |
|
<div class="refsect1" lang="en"> |
|
-<a name="id2543406"></a><h2>ARGUMENTS</h2> |
|
+<a name="id2543415"></a><h2>ARGUMENTS</h2> |
|
<div class="variablelist"><dl> |
|
<dt><span class="term">-m <em class="replaceable"><code>module</code></em></span></dt> |
|
<dd><p> |
|
@@ -71,17 +71,23 @@ |
|
Specify the PIN for the device. If no PIN is provided on the |
|
command line, <span><strong class="command">pkcs11-destroy</strong></span> will prompt for it. |
|
</p></dd> |
|
+<dt><span class="term">-w <em class="replaceable"><code>seconds</code></em></span></dt> |
|
+<dd><p> |
|
+ Specify how long to pause before carrying out key destruction. |
|
+ The default is five seconds. If set to <code class="literal">0</code>, |
|
+ destruction will be immediate. |
|
+ </p></dd> |
|
</dl></div> |
|
</div> |
|
<div class="refsect1" lang="en"> |
|
-<a name="id2543507"></a><h2>SEE ALSO</h2> |
|
+<a name="id2543537"></a><h2>SEE ALSO</h2> |
|
<p> |
|
<span class="citerefentry"><span class="refentrytitle">pkcs11-list</span>(3)</span>, |
|
<span class="citerefentry"><span class="refentrytitle">pkcs11-keygen</span>(3)</span> |
|
</p> |
|
</div> |
|
<div class="refsect1" lang="en"> |
|
-<a name="id2543533"></a><h2>AUTHOR</h2> |
|
+<a name="id2543563"></a><h2>AUTHOR</h2> |
|
<p><span class="corpauthor">Internet Systems Consortium</span> |
|
</p> |
|
</div> |
|
diff --git a/bin/pkcs11/pkcs11-keygen.8 b/bin/pkcs11/pkcs11-keygen.8 |
|
index 568e862..53de464 100644 |
|
--- a/bin/pkcs11/pkcs11-keygen.8 |
|
+++ b/bin/pkcs11/pkcs11-keygen.8 |
|
@@ -23,80 +23,91 @@ |
|
.\" Manual: BIND9 |
|
.\" Source: BIND9 |
|
.\" |
|
-.TH "PKCS11\-KEYGEN" "8" "Sep 18, 2009" "BIND9" "BIND9" |
|
+.TH "PKCS11\-ECGEN" "8" "Feb 30, 2012" "BIND9" "BIND9" |
|
.\" disable hyphenation |
|
.nh |
|
.\" disable justification (adjust text to left margin only) |
|
.ad l |
|
.SH "NAME" |
|
-pkcs11\-keygen \- generate RSA keys on a PKCS#11 device |
|
+pkcs11\-keygen \- generate keys on a PKCS#11 device |
|
.SH "SYNOPSIS" |
|
.HP 14 |
|
-\fBpkcs11\-keygen\fR [\fB\-P\fR] [\fB\-m\ \fR\fB\fImodule\fR\fR] [\fB\-s\ \fR\fB\fIslot\fR\fR] [\fB\-e\fR] {\-b\ \fIkeysize\fR} {\-l\ \fIlabel\fR} [\fB\-i\ \fR\fB\fIid\fR\fR] [\fB\-p\ \fR\fB\fIPIN\fR\fR] |
|
+\fBpkcs11\-keygen\fR {\-a\ \fIalgorithm\fR} [\fB\-b\ \fR\fB\fIkeysize\fR\fR] [\fB\-e\fR] [\fB\-i\ \fR\fB\fIid\fR\fR] [\fB\-m\ \fR\fB\fImodule\fR\fR] [\fB\-P\fR] [\fB\-p\ \fR\fB\fIPIN\fR\fR] [\fB\-q\fR] [\fB\-S\fR] [\fB\-s\ \fR\fB\fIslot\fR\fR] {label} |
|
.SH "DESCRIPTION" |
|
.PP |
|
\fBpkcs11\-keygen\fR |
|
-causes a PKCS#11 device to generate a new RSA key pair with the specified |
|
+causes a PKCS#11 device to generate a new key pair with the given |
|
\fBlabel\fR |
|
-and with |
|
+(which must be unique) and with |
|
\fBkeysize\fR |
|
-bits of modulus. |
|
+bits of prime. |
|
.SH "ARGUMENTS" |
|
.PP |
|
-\-P |
|
-.RS 4 |
|
-Set the new private key to be non\-sensitive and extractable. The allows the private key data to be read from the PKCS#11 device. The default is for private keys to be sensitive and non\-extractable. |
|
-.RE |
|
-.PP |
|
-\-m \fImodule\fR |
|
+\-a \fIalgorithm\fR |
|
.RS 4 |
|
-Specify the PKCS#11 provider module. This must be the full path to a shared library object implementing the PKCS#11 API for the device. |
|
+Specify the key algorithm class: Supported classes are RSA, DSA, DH, and ECC. In addition to these strings, the |
|
+\fBalgorithm\fR |
|
+can be specified as a DNSSEC signing algorithm that will be used with this key; for example, NSEC3RSASHA1 maps to RSA, and ECDSAP256SHA256 maps to ECC. The default class is "RSA". |
|
.RE |
|
.PP |
|
-\-s \fIslot\fR |
|
+\-b \fIkeysize\fR |
|
.RS 4 |
|
-Open the session with the given PKCS#11 slot. The default is slot 0. |
|
+Create the key pair with |
|
+\fBkeysize\fR |
|
+bits of prime. For ECC keys, the only valid values are 256 and 384, and the default is 256. |
|
.RE |
|
.PP |
|
\-e |
|
.RS 4 |
|
-Use a large exponent. |
|
+For RSA keys only, use a large exponent. |
|
.RE |
|
.PP |
|
-\-b \fIkeysize\fR |
|
+\-i \fIid\fR |
|
.RS 4 |
|
-Create the key pair with |
|
-\fBkeysize\fR |
|
-bits of modulus. |
|
+Create key objects with id. The id is either an unsigned short 2 byte or an unsigned long 4 byte number. |
|
.RE |
|
.PP |
|
-\-l \fIlabel\fR |
|
+\-m \fImodule\fR |
|
.RS 4 |
|
-Create key objects with the given label. This name must be unique. |
|
+Specify the PKCS#11 provider module. This must be the full path to a shared library object implementing the PKCS#11 API for the device. |
|
.RE |
|
.PP |
|
-\-i \fIid\fR |
|
+\-P |
|
.RS 4 |
|
-Create key objects with id. The id is either an unsigned short 2 byte or an unsigned long 4 byte number. |
|
+Set the new private key to be non\-sensitive and extractable. The allows the private key data to be read from the PKCS#11 device. The default is for private keys to be sensitive and non\-extractable. |
|
.RE |
|
.PP |
|
\-p \fIPIN\fR |
|
.RS 4 |
|
Specify the PIN for the device. If no PIN is provided on the command line, |
|
-\fBpkcs11\-keygen\fR |
|
+\fBpkcs11\-ecgen\fR |
|
will prompt for it. |
|
.RE |
|
+.PP |
|
+\-e |
|
+.RS 4 |
|
+Quiet mode: suppress unnecessary output. |
|
+.RE |
|
+.PP |
|
+\-S |
|
+.RS 4 |
|
+For Diffie\-Hellman (DH) keys only, use a special prime of 768, 1024 or 1536 bit size and base (aka generator) 2. If not specified, bit size will default to 1024. |
|
+.RE |
|
+.PP |
|
+\-s \fIslot\fR |
|
+.RS 4 |
|
+Open the session with the given PKCS#11 slot. The default is slot 0. |
|
+.RE |
|
.SH "SEE ALSO" |
|
.PP |
|
+\fBpkcs11\-rsagen\fR(3), |
|
+\fBpkcs11\-dsagen\fR(3), |
|
\fBpkcs11\-list\fR(3), |
|
\fBpkcs11\-destroy\fR(3), |
|
\fBdnssec\-keyfromlabel\fR(3), |
|
-.SH "CAVEAT" |
|
-.PP |
|
-Some PKCS#11 providers crash with big public exponent. |
|
.SH "AUTHOR" |
|
.PP |
|
Internet Systems Consortium |
|
.SH "COPYRIGHT" |
|
-Copyright \(co 2009 Internet Systems Consortium, Inc. ("ISC") |
|
+Copyright \(co 2012 Internet Systems Consortium, Inc. ("ISC") |
|
.br |
|
diff --git a/bin/pkcs11/pkcs11-keygen.c b/bin/pkcs11/pkcs11-keygen.c |
|
index 1ffb343..cc91776 100644 |
|
--- a/bin/pkcs11/pkcs11-keygen.c |
|
+++ b/bin/pkcs11/pkcs11-keygen.c |
|
@@ -40,18 +40,19 @@ |
|
|
|
/* $Id: pkcs11-keygen.c,v 1.9 2009/10/26 23:36:53 each Exp $ */ |
|
|
|
-/* pkcs11-keygen - pkcs11 rsa key generator |
|
-* |
|
-* create RSASHA1 key in the keystore of an SCA6000 |
|
-* The calculation of key tag is left to the script |
|
-* that converts the key into a DNSKEY RR and inserts |
|
-* it into a zone file. |
|
-* |
|
-* usage: |
|
-* pkcs11-keygen [-P] [-m module] [-s slot] [-e] -b keysize |
|
-* -l label [-i id] [-p pin] |
|
-* |
|
-*/ |
|
+/* pkcs11-keygen - PKCS#11 key generator |
|
+ * |
|
+ * Create a key in the keystore of an HSM |
|
+ * |
|
+ * The calculation of key tag is left to the script |
|
+ * that converts the key into a DNSKEY RR and inserts |
|
+ * it into a zone file. |
|
+ * |
|
+ * usage: |
|
+ * pkcs11-keygen [-P] [-m module] [-s slot] [-e] [-b keysize] |
|
+ * [-i id] [-p pin] -l label |
|
+ * |
|
+ */ |
|
|
|
/*! \file */ |
|
|
|
@@ -63,15 +64,16 @@ |
|
#include <errno.h> |
|
#include <string.h> |
|
#include <sys/types.h> |
|
-#include "cryptoki.h" |
|
|
|
-#ifdef WIN32 |
|
-#include "win32.c" |
|
-#else |
|
-#ifndef FORCE_STATIC_PROVIDER |
|
-#include "unix.c" |
|
-#endif |
|
-#endif |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+#define WANT_DH_PRIMES |
|
+#define WANT_ECC_CURVES |
|
+#include <pk11/constants.h> |
|
|
|
#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
#define getpassphrase(x) getpass(x) |
|
@@ -81,188 +83,478 @@ |
|
static CK_BBOOL truevalue = TRUE; |
|
static CK_BBOOL falsevalue = FALSE; |
|
|
|
+/* Key class: RSA, ECC, DSA, DH, or unknown */ |
|
+typedef enum { |
|
+ key_unknown, |
|
+ key_rsa, |
|
+ key_dsa, |
|
+ key_dh, |
|
+ key_ecc |
|
+} key_class_t; |
|
+ |
|
+/* |
|
+ * Private key template: usable for most key classes without |
|
+ * modificaton; override CKA_SIGN with CKA_DERIVE for DH |
|
+ */ |
|
+#define PRIVATE_LABEL 0 |
|
+#define PRIVATE_SIGN 1 |
|
+#define PRIVATE_DERIVE 1 |
|
+#define PRIVATE_TOKEN 2 |
|
+#define PRIVATE_PRIVATE 3 |
|
+#define PRIVATE_SENSITIVE 4 |
|
+#define PRIVATE_EXTRACTABLE 5 |
|
+#define PRIVATE_ID 6 |
|
+#define PRIVATE_ATTRS 7 |
|
+static CK_ATTRIBUTE private_template[] = { |
|
+ {CKA_LABEL, NULL_PTR, 0}, |
|
+ {CKA_SIGN, &truevalue, sizeof(truevalue)}, |
|
+ {CKA_TOKEN, &truevalue, sizeof(truevalue)}, |
|
+ {CKA_PRIVATE, &truevalue, sizeof(truevalue)}, |
|
+ {CKA_SENSITIVE, &truevalue, sizeof(truevalue)}, |
|
+ {CKA_EXTRACTABLE, &falsevalue, sizeof(falsevalue)}, |
|
+ {CKA_ID, NULL_PTR, 0} |
|
+}; |
|
+ |
|
+/* |
|
+ * Public key template for RSA keys |
|
+ */ |
|
+#define RSA_LABEL 0 |
|
+#define RSA_VERIFY 1 |
|
+#define RSA_TOKEN 2 |
|
+#define RSA_PRIVATE 3 |
|
+#define RSA_MODULUS_BITS 4 |
|
+#define RSA_PUBLIC_EXPONENT 5 |
|
+#define RSA_ID 6 |
|
+#define RSA_ATTRS 7 |
|
+static CK_ATTRIBUTE rsa_template[] = { |
|
+ {CKA_LABEL, NULL_PTR, 0}, |
|
+ {CKA_VERIFY, &truevalue, sizeof(truevalue)}, |
|
+ {CKA_TOKEN, &truevalue, sizeof(truevalue)}, |
|
+ {CKA_PRIVATE, &falsevalue, sizeof(falsevalue)}, |
|
+ {CKA_MODULUS_BITS, NULL_PTR, 0}, |
|
+ {CKA_PUBLIC_EXPONENT, NULL_PTR, 0}, |
|
+ {CKA_ID, NULL_PTR, 0} |
|
+}; |
|
+ |
|
+/* |
|
+ * Public key template for ECC keys |
|
+ */ |
|
+#define ECC_LABEL 0 |
|
+#define ECC_VERIFY 1 |
|
+#define ECC_TOKEN 2 |
|
+#define ECC_PRIVATE 3 |
|
+#define ECC_PARAMS 4 |
|
+#define ECC_ID 5 |
|
+#define ECC_ATTRS 6 |
|
+static CK_ATTRIBUTE ecc_template[] = { |
|
+ {CKA_LABEL, NULL_PTR, 0}, |
|
+ {CKA_VERIFY, &truevalue, sizeof(truevalue)}, |
|
+ {CKA_TOKEN, &truevalue, sizeof(truevalue)}, |
|
+ {CKA_PRIVATE, &falsevalue, sizeof(falsevalue)}, |
|
+ {CKA_EC_PARAMS, NULL_PTR, 0}, |
|
+ {CKA_ID, NULL_PTR, 0} |
|
+}; |
|
+ |
|
+/* |
|
+ * Public key template for DSA keys |
|
+ */ |
|
+#define DSA_LABEL 0 |
|
+#define DSA_VERIFY 1 |
|
+#define DSA_TOKEN 2 |
|
+#define DSA_PRIVATE 3 |
|
+#define DSA_PRIME 4 |
|
+#define DSA_SUBPRIME 5 |
|
+#define DSA_BASE 6 |
|
+#define DSA_ID 7 |
|
+#define DSA_ATTRS 8 |
|
+static CK_ATTRIBUTE dsa_template[] = { |
|
+ {CKA_LABEL, NULL_PTR, 0}, |
|
+ {CKA_VERIFY, &truevalue, sizeof(truevalue)}, |
|
+ {CKA_TOKEN, &truevalue, sizeof(truevalue)}, |
|
+ {CKA_PRIVATE, &falsevalue, sizeof(falsevalue)}, |
|
+ {CKA_PRIME, NULL_PTR, 0}, |
|
+ {CKA_SUBPRIME, NULL_PTR, 0}, |
|
+ {CKA_BASE, NULL_PTR, 0}, |
|
+ {CKA_ID, NULL_PTR, 0} |
|
+}; |
|
+#define DSA_PARAM_PRIME 0 |
|
+#define DSA_PARAM_SUBPRIME 1 |
|
+#define DSA_PARAM_BASE 2 |
|
+#define DSA_PARAM_ATTRS 3 |
|
+static CK_ATTRIBUTE dsa_param_template[] = { |
|
+ {CKA_PRIME, NULL_PTR, 0}, |
|
+ {CKA_SUBPRIME, NULL_PTR, 0}, |
|
+ {CKA_BASE, NULL_PTR, 0}, |
|
+}; |
|
+#define DSA_DOMAIN_PRIMEBITS 0 |
|
+#define DSA_DOMAIN_PRIVATE 1 |
|
+#define DSA_DOMAIN_ATTRS 2 |
|
+static CK_ATTRIBUTE dsa_domain_template[] = { |
|
+ {CKA_PRIME_BITS, NULL_PTR, 0}, |
|
+ {CKA_PRIVATE, &falsevalue, sizeof(falsevalue)}, |
|
+}; |
|
+ |
|
+/* |
|
+ * Public key template for DH keys |
|
+ */ |
|
+#define DH_LABEL 0 |
|
+#define DH_VERIFY 1 |
|
+#define DH_TOKEN 2 |
|
+#define DH_PRIVATE 3 |
|
+#define DH_PRIME 4 |
|
+#define DH_BASE 5 |
|
+#define DH_ID 6 |
|
+#define DH_ATTRS 7 |
|
+static CK_ATTRIBUTE dh_template[] = { |
|
+ {CKA_LABEL, NULL_PTR, 0}, |
|
+ {CKA_VERIFY, &truevalue, sizeof(truevalue)}, |
|
+ {CKA_TOKEN, &truevalue, sizeof(truevalue)}, |
|
+ {CKA_PRIVATE, &falsevalue, sizeof(falsevalue)}, |
|
+ {CKA_PRIME, NULL_PTR, 0}, |
|
+ {CKA_BASE, NULL_PTR, 0}, |
|
+ {CKA_ID, NULL_PTR, 0} |
|
+}; |
|
+#define DH_PARAM_PRIME 0 |
|
+#define DH_PARAM_BASE 1 |
|
+#define DH_PARAM_ATTRS 2 |
|
+static CK_ATTRIBUTE dh_param_template[] = { |
|
+ {CKA_PRIME, NULL_PTR, 0}, |
|
+ {CKA_BASE, NULL_PTR, 0}, |
|
+}; |
|
+#define DH_DOMAIN_PRIMEBITS 0 |
|
+#define DH_DOMAIN_ATTRS 1 |
|
+static CK_ATTRIBUTE dh_domain_template[] = { |
|
+ {CKA_PRIME_BITS, NULL_PTR, 0}, |
|
+}; |
|
+ |
|
+/* |
|
+ * Convert from text to key class. Accepts the names of DNSSEC |
|
+ * signing algorithms, so e.g., ECDSAP256SHA256 maps to ECC and |
|
+ * NSEC3RSASHA1 maps to RSA. |
|
+ */ |
|
+static key_class_t |
|
+keyclass_fromtext(const char *name) { |
|
+ if (name == NULL) |
|
+ return (key_unknown); |
|
+ |
|
+ if (strncasecmp(name, "rsa", 3) == 0 || |
|
+ strncasecmp(name, "nsec3rsa", 8) == 0) |
|
+ return (key_rsa); |
|
+ else if (strncasecmp(name, "dsa", 3) == 0 || |
|
+ strncasecmp(name, "nsec3dsa", 8) == 0) |
|
+ return (key_dsa); |
|
+ else if (strcasecmp(name, "dh") == 0) |
|
+ return (key_dh); |
|
+ else if (strncasecmp(name, "ecc", 3) == 0 || |
|
+ strncasecmp(name, "ecdsa", 5) == 0) |
|
+ return (key_ecc); |
|
+ else |
|
+ return (key_unknown); |
|
+} |
|
+ |
|
+static void |
|
+usage() { |
|
+ fprintf(stderr, |
|
+ "Usage:\n" |
|
+ "\tpkcs11-keygen -a algorithm -b keysize -l label\n" |
|
+ "\t [-P] [-m module] " |
|
+ "[-s slot] [-e] [-S] [-i id] [-p PIN]\n"); |
|
+ exit(2); |
|
+} |
|
+ |
|
int |
|
-main(int argc, char *argv[]) |
|
-{ |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
CK_RV rv; |
|
CK_SLOT_ID slot = 0; |
|
- CK_MECHANISM genmech; |
|
+ CK_MECHANISM mech, dpmech; |
|
CK_SESSION_HANDLE hSession; |
|
- CK_UTF8CHAR *pin = NULL; |
|
- CK_ULONG modulusbits = 0; |
|
+ char *lib_name = NULL; |
|
+ char *pin = NULL; |
|
+ CK_ULONG bits = 0; |
|
CK_CHAR *label = NULL; |
|
- CK_OBJECT_HANDLE privatekey, publickey; |
|
- CK_BYTE public_exponent[5]; |
|
- CK_ULONG expsize = 3; |
|
+ CK_OBJECT_HANDLE privatekey, publickey, domainparams; |
|
+ CK_BYTE exponent[5]; |
|
+ CK_ULONG expsize = 0; |
|
+ pk11_context_t pctx; |
|
int error = 0; |
|
int c, errflg = 0; |
|
- int hide = 1; |
|
- int idlen = 0; |
|
+ int hide = 1, special = 0, quiet = 0; |
|
+ int idlen = 0, id_offset = 0; |
|
+ unsigned int i; |
|
unsigned long id = 0; |
|
CK_BYTE idbuf[4]; |
|
CK_ULONG ulObjectCount; |
|
- /* Set search template */ |
|
CK_ATTRIBUTE search_template[] = { |
|
{CKA_LABEL, NULL_PTR, 0} |
|
}; |
|
- CK_ATTRIBUTE publickey_template[] = { |
|
- {CKA_LABEL, NULL_PTR, 0}, |
|
- {CKA_VERIFY, &truevalue, sizeof(truevalue)}, |
|
- {CKA_TOKEN, &truevalue, sizeof(truevalue)}, |
|
- {CKA_MODULUS_BITS, &modulusbits, sizeof(modulusbits)}, |
|
- {CKA_PUBLIC_EXPONENT, &public_exponent, expsize}, |
|
- {CKA_ID, &idbuf, idlen} |
|
- }; |
|
- CK_ULONG publickey_attrcnt = 6; |
|
- CK_ATTRIBUTE privatekey_template[] = { |
|
- {CKA_LABEL, NULL_PTR, 0}, |
|
- {CKA_SIGN, &truevalue, sizeof(truevalue)}, |
|
- {CKA_TOKEN, &truevalue, sizeof(truevalue)}, |
|
- {CKA_PRIVATE, &truevalue, sizeof(truevalue)}, |
|
- {CKA_SENSITIVE, &truevalue, sizeof(truevalue)}, |
|
- {CKA_EXTRACTABLE, &falsevalue, sizeof(falsevalue)}, |
|
- {CKA_ID, &idbuf, idlen} |
|
- }; |
|
- CK_ULONG privatekey_attrcnt = 7; |
|
- char *pk11_provider; |
|
- extern char *optarg; |
|
- extern int optopt; |
|
|
|
- pk11_provider = getenv("PKCS11_PROVIDER"); |
|
- if (pk11_provider != NULL) |
|
- pk11_libname = pk11_provider; |
|
+ CK_ATTRIBUTE *public_template = NULL; |
|
+ CK_ATTRIBUTE *domain_template = NULL; |
|
+ CK_ATTRIBUTE *param_template = NULL; |
|
+ CK_ULONG public_attrcnt = 0, private_attrcnt = PRIVATE_ATTRS; |
|
+ CK_ULONG domain_attrcnt = 0, param_attrcnt = 0; |
|
+ key_class_t keyclass = key_rsa; |
|
+ pk11_optype_t op_type = OP_ANY; |
|
|
|
- while ((c = getopt(argc, argv, ":Pm:s:b:ei:l:p:")) != -1) { |
|
+#define OPTIONS ":a:b:ei:l:m:Pp:qSs:" |
|
+ while ((c = isc_commandline_parse(argc, argv, OPTIONS)) != -1) { |
|
switch (c) { |
|
+ case 'a': |
|
+ keyclass = keyclass_fromtext(isc_commandline_argument); |
|
+ break; |
|
case 'P': |
|
hide = 0; |
|
break; |
|
case 'm': |
|
- pk11_libname = optarg; |
|
+ lib_name = isc_commandline_argument; |
|
break; |
|
case 's': |
|
- slot = atoi(optarg); |
|
+ slot = atoi(isc_commandline_argument); |
|
break; |
|
case 'e': |
|
expsize = 5; |
|
break; |
|
case 'b': |
|
- modulusbits = atoi(optarg); |
|
+ bits = atoi(isc_commandline_argument); |
|
break; |
|
case 'l': |
|
- label = (CK_CHAR *)optarg; |
|
+ /* -l option is retained for backward compatibility * */ |
|
+ label = (CK_CHAR *)isc_commandline_argument; |
|
break; |
|
case 'i': |
|
- id = strtoul(optarg, NULL, 0); |
|
+ id = strtoul(isc_commandline_argument, NULL, 0); |
|
idlen = 4; |
|
break; |
|
case 'p': |
|
- pin = (CK_UTF8CHAR *)optarg; |
|
+ pin = isc_commandline_argument; |
|
+ break; |
|
+ case 'q': |
|
+ quiet = 1; |
|
+ break; |
|
+ case 'S': |
|
+ special = 1; |
|
break; |
|
case ':': |
|
fprintf(stderr, |
|
"Option -%c requires an operand\n", |
|
- optopt); |
|
+ isc_commandline_option); |
|
errflg++; |
|
break; |
|
case '?': |
|
default: |
|
- fprintf(stderr, "Unrecognised option: -%c\n", optopt); |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
errflg++; |
|
} |
|
} |
|
|
|
- if (errflg || !modulusbits || (label == NULL)) { |
|
- fprintf(stderr, "Usage:\n"); |
|
- fprintf(stderr, "\tpkcs11-keygen -b keysize -l label\n"); |
|
- fprintf(stderr, "\t [-P] [-m module] " |
|
- "[-s slot] [-e] [-i id] [-p PIN]\n"); |
|
+ if (label == NULL && isc_commandline_index < argc) |
|
+ label = (CK_CHAR *)argv[isc_commandline_index]; |
|
+ |
|
+ if (errflg || (label == NULL)) |
|
+ usage(); |
|
+ |
|
+ if (expsize != 0 && keyclass != key_rsa) { |
|
+ fprintf(stderr, "The -e option is only compatible " |
|
+ "with RSA key generation\n"); |
|
exit(2); |
|
} |
|
+ |
|
+ if (special != 0 && keyclass != key_dh) { |
|
+ fprintf(stderr, "The -S option is only compatible " |
|
+ "with Diffie-Hellman key generation\n"); |
|
+ exit(2); |
|
+ } |
|
+ |
|
+ switch (keyclass) { |
|
+ case key_rsa: |
|
+ op_type = OP_RSA; |
|
+ if (expsize == 0) |
|
+ expsize = 3; |
|
+ if (bits == 0) |
|
+ usage(); |
|
+ |
|
+ mech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; |
|
+ mech.pParameter = NULL; |
|
+ mech.ulParameterLen = 0; |
|
+ |
|
+ public_template = rsa_template; |
|
+ public_attrcnt = RSA_ATTRS; |
|
+ id_offset = RSA_ID; |
|
+ |
|
+ /* Set public exponent to F4 or F5 */ |
|
+ exponent[0] = 0x01; |
|
+ exponent[1] = 0x00; |
|
+ if (expsize == 3) |
|
+ exponent[2] = 0x01; |
|
+ else { |
|
+ exponent[2] = 0x00; |
|
+ exponent[3] = 0x00; |
|
+ exponent[4] = 0x01; |
|
+ } |
|
+ |
|
+ public_template[RSA_MODULUS_BITS].pValue = &bits; |
|
+ public_template[RSA_MODULUS_BITS].ulValueLen = sizeof(bits); |
|
+ public_template[RSA_PUBLIC_EXPONENT].pValue = &exponent; |
|
+ public_template[RSA_PUBLIC_EXPONENT].ulValueLen = expsize; |
|
+ break; |
|
+ case key_ecc: |
|
+ op_type = OP_EC; |
|
+ if (bits == 0) |
|
+ bits = 256; |
|
+ else if (bits != 256 && bits != 384) { |
|
+ fprintf(stderr, "ECC keys only support bit sizes of " |
|
+ "256 and 384\n"); |
|
+ exit(2); |
|
+ } |
|
+ |
|
+ mech.mechanism = CKM_EC_KEY_PAIR_GEN; |
|
+ mech.pParameter = NULL; |
|
+ mech.ulParameterLen = 0; |
|
+ |
|
+ public_template = ecc_template; |
|
+ public_attrcnt = ECC_ATTRS; |
|
+ id_offset = ECC_ID; |
|
+ |
|
+ if (bits == 256) { |
|
+ public_template[4].pValue = pk11_ecc_prime256v1; |
|
+ public_template[4].ulValueLen = |
|
+ sizeof(pk11_ecc_prime256v1); |
|
+ } else { |
|
+ public_template[4].pValue = pk11_ecc_secp384r1; |
|
+ public_template[4].ulValueLen = |
|
+ sizeof(pk11_ecc_secp384r1); |
|
+ } |
|
+ |
|
+ break; |
|
+ case key_dsa: |
|
+ op_type = OP_DSA; |
|
+ if (bits == 0) |
|
+ usage(); |
|
+ |
|
+ dpmech.mechanism = CKM_DSA_PARAMETER_GEN; |
|
+ dpmech.pParameter = NULL; |
|
+ dpmech.ulParameterLen = 0; |
|
+ mech.mechanism = CKM_DSA_KEY_PAIR_GEN; |
|
+ mech.pParameter = NULL; |
|
+ mech.ulParameterLen = 0; |
|
+ |
|
+ public_template = dsa_template; |
|
+ public_attrcnt = DSA_ATTRS; |
|
+ id_offset = DSA_ID; |
|
+ |
|
+ domain_template = dsa_domain_template; |
|
+ domain_attrcnt = DSA_DOMAIN_ATTRS; |
|
+ param_template = dsa_param_template; |
|
+ param_attrcnt = DSA_PARAM_ATTRS; |
|
+ |
|
+ domain_template[DSA_DOMAIN_PRIMEBITS].pValue = &bits; |
|
+ domain_template[DSA_DOMAIN_PRIMEBITS].ulValueLen = sizeof(bits); |
|
+ break; |
|
+ case key_dh: |
|
+ op_type = OP_DH; |
|
+ if (special && bits == 0) |
|
+ bits = 1024; |
|
+ else if (special && |
|
+ bits != 768 && bits != 1024 && bits != 1536) |
|
+ { |
|
+ fprintf(stderr, "When using the special prime (-S) " |
|
+ "option, only key sizes of\n" |
|
+ "768, 1024 or 1536 are supported.\n"); |
|
+ exit(2); |
|
+ } else if (bits == 0) |
|
+ usage(); |
|
+ |
|
+ dpmech.mechanism = CKM_DH_PKCS_PARAMETER_GEN; |
|
+ dpmech.pParameter = NULL; |
|
+ dpmech.ulParameterLen = 0; |
|
+ mech.mechanism = CKM_DH_PKCS_KEY_PAIR_GEN; |
|
+ mech.pParameter = NULL; |
|
+ mech.ulParameterLen = 0; |
|
+ |
|
+ /* Override CKA_SIGN attribute */ |
|
+ private_template[PRIVATE_DERIVE].type = CKA_DERIVE; |
|
+ |
|
+ public_template = dh_template; |
|
+ public_attrcnt = DH_ATTRS; |
|
+ id_offset = DH_ID; |
|
+ |
|
+ domain_template = dh_domain_template; |
|
+ domain_attrcnt = DH_DOMAIN_ATTRS; |
|
+ param_template = dh_param_template; |
|
+ param_attrcnt = DH_PARAM_ATTRS; |
|
+ |
|
+ domain_template[DH_DOMAIN_PRIMEBITS].pValue = &bits; |
|
+ domain_template[DH_DOMAIN_PRIMEBITS].ulValueLen = sizeof(bits); |
|
+ break; |
|
+ case key_unknown: |
|
+ usage(); |
|
+ } |
|
|
|
search_template[0].pValue = label; |
|
search_template[0].ulValueLen = strlen((char *)label); |
|
- publickey_template[0].pValue = label; |
|
- publickey_template[0].ulValueLen = strlen((char *)label); |
|
- privatekey_template[0].pValue = label; |
|
- privatekey_template[0].ulValueLen = strlen((char *)label); |
|
- |
|
- /* Set public exponent to F4 or F5 */ |
|
- public_exponent[0] = 0x01; |
|
- public_exponent[1] = 0x00; |
|
- if (expsize == 3) |
|
- public_exponent[2] = 0x01; |
|
- else { |
|
- publickey_template[4].ulValueLen = expsize; |
|
- public_exponent[2] = 0x00; |
|
- public_exponent[3] = 0x00; |
|
- public_exponent[4] = 0x01; |
|
- } |
|
- |
|
- /* Set up mechanism for generating key pair */ |
|
- genmech.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN; |
|
- genmech.pParameter = NULL_PTR; |
|
- genmech.ulParameterLen = 0; |
|
+ public_template[0].pValue = label; |
|
+ public_template[0].ulValueLen = strlen((char *)label); |
|
+ private_template[0].pValue = label; |
|
+ private_template[0].ulValueLen = strlen((char *)label); |
|
|
|
if (idlen == 0) { |
|
- publickey_attrcnt--; |
|
- privatekey_attrcnt--; |
|
- } else if (id <= 0xffff) { |
|
- idlen = 2; |
|
- publickey_template[5].ulValueLen = idlen; |
|
- privatekey_template[6].ulValueLen = idlen; |
|
- idbuf[0] = (CK_BYTE)(id >> 8); |
|
- idbuf[1] = (CK_BYTE)id; |
|
+ public_attrcnt--; |
|
+ private_attrcnt--; |
|
} else { |
|
- idbuf[0] = (CK_BYTE)(id >> 24); |
|
- idbuf[1] = (CK_BYTE)(id >> 16); |
|
- idbuf[2] = (CK_BYTE)(id >> 8); |
|
- idbuf[3] = (CK_BYTE)id; |
|
- } |
|
- |
|
- /* Initialize the CRYPTOKI library */ |
|
- rv = C_Initialize(NULL_PTR); |
|
+ if (id <= 0xffff) { |
|
+ idlen = 2; |
|
+ idbuf[0] = (CK_BYTE)(id >> 8); |
|
+ idbuf[1] = (CK_BYTE)id; |
|
+ } else { |
|
+ idbuf[0] = (CK_BYTE)(id >> 24); |
|
+ idbuf[1] = (CK_BYTE)(id >> 16); |
|
+ idbuf[2] = (CK_BYTE)(id >> 8); |
|
+ idbuf[3] = (CK_BYTE)id; |
|
+ } |
|
|
|
- if (rv != CKR_OK) { |
|
- if (rv == 0xfe) |
|
- fprintf(stderr, |
|
- "Can't load or link module \"%s\"\n", |
|
- pk11_libname); |
|
- else |
|
- fprintf(stderr, "C_Initialize: Error = 0x%.8lX\n", rv); |
|
- exit(1); |
|
+ public_template[id_offset].pValue = idbuf; |
|
+ public_template[id_offset].ulValueLen = idlen; |
|
+ private_template[PRIVATE_ID].pValue = idbuf; |
|
+ private_template[PRIVATE_ID].ulValueLen = idlen; |
|
} |
|
|
|
- /* Open a session on the slot found */ |
|
- rv = C_OpenSession(slot, CKF_RW_SESSION+CKF_SERIAL_SESSION, |
|
- NULL_PTR, NULL_PTR, &hSession); |
|
+ pk11_result_register(); |
|
|
|
- if (rv != CKR_OK) { |
|
- fprintf(stderr, "C_OpenSession: Error = 0x%.8lX\n", rv); |
|
- error = 1; |
|
- goto exit_program; |
|
- } |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
|
|
- /* Login to the Token (Keystore) */ |
|
if (pin == NULL) |
|
- pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: "); |
|
+ pin = getpassphrase("Enter Pin: "); |
|
|
|
- rv = C_Login(hSession, CKU_USER, pin, strlen((char *)pin)); |
|
- memset(pin, 0, strlen((char *)pin)); |
|
- if (rv != CKR_OK) { |
|
- fprintf(stderr, "C_Login: Error = 0x%.8lX\n", rv); |
|
- error = 1; |
|
- goto exit_session; |
|
+ result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_TRUE, |
|
+ ISC_TRUE, (const char *) pin, slot); |
|
+ if (result == PK11_R_NORANDOMSERVICE || |
|
+ result == PK11_R_NODIGESTSERVICE || |
|
+ result == PK11_R_NOAESSERVICE) { |
|
+ fprintf(stderr, "Warning: %s\n", isc_result_totext(result)); |
|
+ fprintf(stderr, "This HSM will not work with BIND 9 " |
|
+ "using native PKCS#11.\n"); |
|
+ } else if (result != ISC_R_SUCCESS) { |
|
+ fprintf(stderr, "Unrecoverable error initializing " |
|
+ "PKCS#11: %s\n", isc_result_totext(result)); |
|
+ exit(1); |
|
} |
|
|
|
+ /* Login to the Token (Keystore) */ |
|
+ memset(pin, 0, strlen(pin)); |
|
+ hSession = pctx.session; |
|
+ |
|
/* check if a key with the same id already exists */ |
|
- rv = C_FindObjectsInit(hSession, search_template, 1); |
|
+ rv = pkcs_C_FindObjectsInit(hSession, search_template, 1); |
|
if (rv != CKR_OK) { |
|
fprintf(stderr, "C_FindObjectsInit: Error = 0x%.8lX\n", rv); |
|
error = 1; |
|
goto exit_session; |
|
} |
|
- rv = C_FindObjects(hSession, &privatekey, 1, &ulObjectCount); |
|
+ rv = pkcs_C_FindObjects(hSession, &privatekey, 1, &ulObjectCount); |
|
if (rv != CKR_OK) { |
|
fprintf(stderr, "C_FindObjects: Error = 0x%.8lX\n", rv); |
|
error = 1; |
|
@@ -276,33 +568,140 @@ main(int argc, char *argv[]) |
|
|
|
/* Set attributes if the key is not to be hidden */ |
|
if (!hide) { |
|
- privatekey_template[4].pValue = &falsevalue; |
|
- privatekey_template[5].pValue = &truevalue; |
|
+ private_template[4].pValue = &falsevalue; |
|
+ private_template[5].pValue = &truevalue; |
|
+ } |
|
+ |
|
+ if (keyclass == key_rsa || keyclass == key_ecc) |
|
+ goto generate_keys; |
|
+ |
|
+ /* |
|
+ * Special setup for Diffie-Hellman keys |
|
+ */ |
|
+ if (special != 0) { |
|
+ public_template[DH_BASE].pValue = pk11_dh_bn2; |
|
+ public_template[DH_BASE].ulValueLen = sizeof(pk11_dh_bn2); |
|
+ if (bits == 768) { |
|
+ public_template[DH_PRIME].pValue = pk11_dh_bn768; |
|
+ public_template[DH_PRIME].ulValueLen = |
|
+ sizeof(pk11_dh_bn768); |
|
+ } else if (bits == 1024) { |
|
+ public_template[DH_PRIME].pValue = pk11_dh_bn1024; |
|
+ public_template[DH_PRIME].ulValueLen = |
|
+ sizeof(pk11_dh_bn1024); |
|
+ } else { |
|
+ public_template[DH_PRIME].pValue = pk11_dh_bn1536; |
|
+ public_template[DH_PRIME].ulValueLen = |
|
+ sizeof(pk11_dh_bn1536); |
|
+ } |
|
+ param_attrcnt = 0; |
|
+ goto generate_keys; |
|
+ } |
|
+ |
|
+ /* Generate Domain parameters */ |
|
+ rv = pkcs_C_GenerateKey(hSession, &dpmech, domain_template, |
|
+ domain_attrcnt, &domainparams); |
|
+ |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_GenerateKey: Error = 0x%.8lX\n", rv); |
|
+ error = 1; |
|
+ goto exit_search; |
|
+ } |
|
+ |
|
+ /* Get Domain parameters */ |
|
+ rv = pkcs_C_GetAttributeValue(hSession, domainparams, |
|
+ param_template, param_attrcnt); |
|
+ |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_GetAttributeValue0: Error = 0x%.8lX\n", rv); |
|
+ error = 1; |
|
+ goto exit_domain; |
|
+ } |
|
+ |
|
+ /* Allocate space for parameter attributes */ |
|
+ for (i = 0; i < param_attrcnt; i++) |
|
+ param_template[i].pValue = malloc(param_template[i].ulValueLen); |
|
+ |
|
+ rv = pkcs_C_GetAttributeValue(hSession, domainparams, |
|
+ dsa_param_template, DSA_PARAM_ATTRS); |
|
+ |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_GetAttributeValue1: Error = 0x%.8lX\n", rv); |
|
+ error = 1; |
|
+ goto exit_params; |
|
+ } |
|
+ |
|
+ switch (keyclass) { |
|
+ case key_dsa: |
|
+ public_template[DSA_PRIME].pValue = |
|
+ param_template[DSA_PARAM_PRIME].pValue; |
|
+ public_template[DSA_PRIME].ulValueLen = |
|
+ param_template[DSA_PARAM_PRIME].ulValueLen; |
|
+ public_template[DSA_SUBPRIME].pValue = |
|
+ param_template[DSA_PARAM_SUBPRIME].pValue; |
|
+ public_template[DSA_SUBPRIME].ulValueLen = |
|
+ param_template[DSA_PARAM_SUBPRIME].ulValueLen; |
|
+ public_template[DSA_BASE].pValue = |
|
+ param_template[DSA_PARAM_BASE].pValue; |
|
+ public_template[DSA_BASE].ulValueLen = |
|
+ param_template[DSA_PARAM_BASE].ulValueLen; |
|
+ break; |
|
+ case key_dh: |
|
+ public_template[DH_PRIME].pValue = |
|
+ param_template[DH_PARAM_PRIME].pValue; |
|
+ public_template[DH_PRIME].ulValueLen = |
|
+ param_template[DH_PARAM_PRIME].ulValueLen; |
|
+ public_template[DH_BASE].pValue = |
|
+ param_template[DH_PARAM_BASE].pValue; |
|
+ public_template[DH_BASE].ulValueLen = |
|
+ param_template[DH_PARAM_BASE].ulValueLen; |
|
+ default: |
|
+ break; |
|
} |
|
|
|
+ generate_keys: |
|
/* Generate Key pair for signing/verifying */ |
|
- rv = C_GenerateKeyPair(hSession, &genmech, |
|
- publickey_template, publickey_attrcnt, |
|
- privatekey_template, privatekey_attrcnt, |
|
+ rv = pkcs_C_GenerateKeyPair(hSession, &mech, |
|
+ public_template, public_attrcnt, |
|
+ private_template, private_attrcnt, |
|
&publickey, &privatekey); |
|
|
|
if (rv != CKR_OK) { |
|
fprintf(stderr, "C_GenerateKeyPair: Error = 0x%.8lX\n", rv); |
|
error = 1; |
|
+ } else if (!quiet) |
|
+ printf("Key pair generation complete.\n"); |
|
+ |
|
+ exit_params: |
|
+ /* Free parameter attributes */ |
|
+ if (keyclass == key_dsa || keyclass == key_dh) |
|
+ for (i = 0; i < param_attrcnt; i++) |
|
+ free(param_template[i].pValue); |
|
+ |
|
+ exit_domain: |
|
+ /* Destroy domain parameters */ |
|
+ if (keyclass == key_dsa || (keyclass == key_dh && !special)) { |
|
+ rv = pkcs_C_DestroyObject(hSession, domainparams); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_DestroyObject: Error = 0x%.8lX\n", rv); |
|
+ error = 1; |
|
+ } |
|
} |
|
- |
|
+ |
|
exit_search: |
|
- rv = C_FindObjectsFinal(hSession); |
|
+ rv = pkcs_C_FindObjectsFinal(hSession); |
|
if (rv != CKR_OK) { |
|
fprintf(stderr, "C_FindObjectsFinal: Error = 0x%.8lX\n", rv); |
|
error = 1; |
|
} |
|
|
|
exit_session: |
|
- (void)C_CloseSession(hSession); |
|
- |
|
- exit_program: |
|
- (void)C_Finalize(NULL_PTR); |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
|
|
exit(error); |
|
} |
|
diff --git a/bin/pkcs11/pkcs11-keygen.docbook b/bin/pkcs11/pkcs11-keygen.docbook |
|
index 7c4ba08..d62ba2f 100644 |
|
--- a/bin/pkcs11/pkcs11-keygen.docbook |
|
+++ b/bin/pkcs11/pkcs11-keygen.docbook |
|
@@ -18,25 +18,26 @@ |
|
--> |
|
|
|
<!-- $Id: pkcs11-keygen.docbook,v 1.3 2009/10/05 12:23:11 fdupont Exp $ --> |
|
-<refentry id="man.pkcs11-keygen"> |
|
+<refentry id="man.pkcs11-ecgen"> |
|
<refentryinfo> |
|
- <date>Sep 18, 2009</date> |
|
+ <date>Feb 30, 2012</date> |
|
</refentryinfo> |
|
|
|
<refmeta> |
|
- <refentrytitle><application>pkcs11-keygen</application></refentrytitle> |
|
+ <refentrytitle><application>pkcs11-ecgen</application></refentrytitle> |
|
<manvolnum>8</manvolnum> |
|
<refmiscinfo>BIND9</refmiscinfo> |
|
</refmeta> |
|
|
|
<refnamediv> |
|
<refname><application>pkcs11-keygen</application></refname> |
|
- <refpurpose>generate RSA keys on a PKCS#11 device</refpurpose> |
|
+ <refpurpose>generate keys on a PKCS#11 device</refpurpose> |
|
</refnamediv> |
|
|
|
<docinfo> |
|
<copyright> |
|
<year>2009</year> |
|
+ <year>2014</year> |
|
<holder>Internet Systems Consortium, Inc. ("ISC")</holder> |
|
</copyright> |
|
</docinfo> |
|
@@ -44,14 +45,17 @@ |
|
<refsynopsisdiv> |
|
<cmdsynopsis> |
|
<command>pkcs11-keygen</command> |
|
- <arg><option>-P</option></arg> |
|
- <arg><option>-m <replaceable class="parameter">module</replaceable></option></arg> |
|
- <arg><option>-s <replaceable class="parameter">slot</replaceable></option></arg> |
|
+ <arg choice="req">-a <replaceable class="parameter">algorithm</replaceable></arg> |
|
+ <arg><option>-b <replaceable class="parameter">keysize</replaceable></option></arg> |
|
<arg><option>-e</option></arg> |
|
- <arg choice="req">-b <replaceable class="parameter">keysize</replaceable></arg> |
|
- <arg choice="req">-l <replaceable class="parameter">label</replaceable></arg> |
|
<arg><option>-i <replaceable class="parameter">id</replaceable></option></arg> |
|
+ <arg><option>-m <replaceable class="parameter">module</replaceable></option></arg> |
|
+ <arg><option>-P</option></arg> |
|
<arg><option>-p <replaceable class="parameter">PIN</replaceable></option></arg> |
|
+ <arg><option>-q</option></arg> |
|
+ <arg><option>-S</option></arg> |
|
+ <arg><option>-s <replaceable class="parameter">slot</replaceable></option></arg> |
|
+ <arg choice="req">label</arg> |
|
</cmdsynopsis> |
|
</refsynopsisdiv> |
|
|
|
@@ -59,8 +63,8 @@ |
|
<title>DESCRIPTION</title> |
|
<para> |
|
<command>pkcs11-keygen</command> causes a PKCS#11 device to generate |
|
- a new RSA key pair with the specified <option>label</option> and |
|
- with <option>keysize</option> bits of modulus. |
|
+ a new key pair with the given <option>label</option> (which must be |
|
+ unique) and with <option>keysize</option> bits of prime. |
|
</para> |
|
</refsect1> |
|
|
|
@@ -68,83 +72,109 @@ |
|
<title>ARGUMENTS</title> |
|
<variablelist> |
|
<varlistentry> |
|
- <term>-P</term> |
|
+ <term>-a <replaceable class="parameter">algorithm</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Set the new private key to be non-sensitive and extractable. |
|
- The allows the private key data to be read from the PKCS#11 |
|
- device. The default is for private keys to be sensitive and |
|
- non-extractable. |
|
+ Specify the key algorithm class: Supported classes are RSA, |
|
+ DSA, DH, and ECC. In addition to these strings, the |
|
+ <option>algorithm</option> can be specified as a DNSSEC |
|
+ signing algorithm that will be used with this key; for |
|
+ example, NSEC3RSASHA1 maps to RSA, and ECDSAP256SHA256 maps |
|
+ to ECC. The default class is "RSA". |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
|
|
<varlistentry> |
|
- <term>-m <replaceable class="parameter">module</replaceable></term> |
|
+ <term>-b <replaceable class="parameter">keysize</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Specify the PKCS#11 provider module. This must be the full |
|
- path to a shared library object implementing the PKCS#11 API |
|
- for the device. |
|
+ Create the key pair with <option>keysize</option> bits of |
|
+ prime. For ECC keys, the only valid values are 256 and 384, |
|
+ and the default is 256. |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
|
|
<varlistentry> |
|
- <term>-s <replaceable class="parameter">slot</replaceable></term> |
|
+ <term>-e</term> |
|
<listitem> |
|
<para> |
|
- Open the session with the given PKCS#11 slot. The default is |
|
- slot 0. |
|
+ For RSA keys only, use a large exponent. |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
|
|
<varlistentry> |
|
- <term>-e</term> |
|
+ <term>-i <replaceable class="parameter">id</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Use a large exponent. |
|
+ Create key objects with id. The id is either |
|
+ an unsigned short 2 byte or an unsigned long 4 byte number. |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
|
|
<varlistentry> |
|
- <term>-b <replaceable class="parameter">keysize</replaceable></term> |
|
+ <term>-m <replaceable class="parameter">module</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Create the key pair with <option>keysize</option> bits of |
|
- modulus. |
|
+ Specify the PKCS#11 provider module. This must be the full |
|
+ path to a shared library object implementing the PKCS#11 API |
|
+ for the device. |
|
+ </para> |
|
+ </listitem> |
|
+ </varlistentry> |
|
+ |
|
+ <varlistentry> |
|
+ <term>-P</term> |
|
+ <listitem> |
|
+ <para> |
|
+ Set the new private key to be non-sensitive and extractable. |
|
+ The allows the private key data to be read from the PKCS#11 |
|
+ device. The default is for private keys to be sensitive and |
|
+ non-extractable. |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
|
|
<varlistentry> |
|
- <term>-l <replaceable class="parameter">label</replaceable></term> |
|
+ <term>-p <replaceable class="parameter">PIN</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Create key objects with the given label. |
|
- This name must be unique. |
|
+ Specify the PIN for the device. If no PIN is provided on |
|
+ the command line, <command>pkcs11-ecgen</command> will |
|
+ prompt for it. |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
|
|
<varlistentry> |
|
- <term>-i <replaceable class="parameter">id</replaceable></term> |
|
+ <term>-q</term> |
|
<listitem> |
|
<para> |
|
- Create key objects with id. The id is either |
|
- an unsigned short 2 byte or an unsigned long 4 byte number. |
|
+ Quiet mode: suppress unnecessary output. |
|
+ </para> |
|
+ </listitem> |
|
+ </varlistentry> |
|
+ |
|
+ <varlistentry> |
|
+ <term>-S</term> |
|
+ <listitem> |
|
+ <para> |
|
+ For Diffie-Hellman (DH) keys only, use a special prime of |
|
+ 768, 1024 or 1536 bit size and base (aka generator) 2. |
|
+ If not specified, bit size will default to 1024. |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
|
|
<varlistentry> |
|
- <term>-p <replaceable class="parameter">PIN</replaceable></term> |
|
+ <term>-s <replaceable class="parameter">slot</replaceable></term> |
|
<listitem> |
|
<para> |
|
- Specify the PIN for the device. If no PIN is provided on the |
|
- command line, <command>pkcs11-keygen</command> will prompt for it. |
|
+ Open the session with the given PKCS#11 slot. The default is |
|
+ slot 0. |
|
</para> |
|
</listitem> |
|
</varlistentry> |
|
@@ -155,6 +185,12 @@ |
|
<title>SEE ALSO</title> |
|
<para> |
|
<citerefentry> |
|
+ <refentrytitle>pkcs11-rsagen</refentrytitle><manvolnum>3</manvolnum> |
|
+ </citerefentry>, |
|
+ <citerefentry> |
|
+ <refentrytitle>pkcs11-dsagen</refentrytitle><manvolnum>3</manvolnum> |
|
+ </citerefentry>, |
|
+ <citerefentry> |
|
<refentrytitle>pkcs11-list</refentrytitle><manvolnum>3</manvolnum> |
|
</citerefentry>, |
|
<citerefentry> |
|
@@ -167,11 +203,6 @@ |
|
</refsect1> |
|
|
|
<refsect1> |
|
- <title>CAVEAT</title> |
|
- <para>Some PKCS#11 providers crash with big public exponent.</para> |
|
- </refsect1> |
|
- |
|
- <refsect1> |
|
<title>AUTHOR</title> |
|
<para><corpauthor>Internet Systems Consortium</corpauthor> |
|
</para> |
|
diff --git a/bin/pkcs11/pkcs11-keygen.html b/bin/pkcs11/pkcs11-keygen.html |
|
index 41378fc..c7fdecf 100644 |
|
--- a/bin/pkcs11/pkcs11-keygen.html |
|
+++ b/bin/pkcs11/pkcs11-keygen.html |
|
@@ -18,36 +18,53 @@ |
|
<html> |
|
<head> |
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
|
-<title>pkcs11-keygen</title> |
|
+<title>pkcs11-ecgen</title> |
|
<meta name="generator" content="DocBook XSL Stylesheets V1.71.1"> |
|
</head> |
|
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en"> |
|
-<a name="man.pkcs11-keygen"></a><div class="titlepage"></div> |
|
+<a name="man.pkcs11-ecgen"></a><div class="titlepage"></div> |
|
<div class="refnamediv"> |
|
<h2>Name</h2> |
|
-<p><span class="application">pkcs11-keygen</span> — generate RSA keys on a PKCS#11 device</p> |
|
+<p><span class="application">pkcs11-keygen</span> — generate keys on a PKCS#11 device</p> |
|
</div> |
|
<div class="refsynopsisdiv"> |
|
<h2>Synopsis</h2> |
|
-<div class="cmdsynopsis"><p><code class="command">pkcs11-keygen</code> [<code class="option">-P</code>] [<code class="option">-m <em class="replaceable"><code>module</code></em></code>] [<code class="option">-s <em class="replaceable"><code>slot</code></em></code>] [<code class="option">-e</code>] {-b <em class="replaceable"><code>keysize</code></em>} {-l <em class="replaceable"><code>label</code></em>} [<code class="option">-i <em class="replaceable"><code>id</code></em></code>] [<code class="option">-p <em class="replaceable"><code>PIN</code></em></code>]</p></div> |
|
+<div class="cmdsynopsis"><p><code class="command">pkcs11-keygen</code> {-a <em class="replaceable"><code>algorithm</code></em>} [<code class="option">-b <em class="replaceable"><code>keysize</code></em></code>] [<code class="option">-e</code>] [<code class="option">-i <em class="replaceable"><code>id</code></em></code>] [<code class="option">-m <em class="replaceable"><code>module</code></em></code>] [<code class="option">-P</code>] [<code class="option">-p <em class="replaceable"><code>PIN</code></em></code>] [<code class="option">-q</code>] [<code class="option">-S</code>] [<code class="option">-s <em class="replaceable"><code>slot</code></em></code>] {label}</p></div> |
|
</div> |
|
<div class="refsect1" lang="en"> |
|
-<a name="id2543397"></a><h2>DESCRIPTION</h2> |
|
+<a name="id2543410"></a><h2>DESCRIPTION</h2> |
|
<p> |
|
<span><strong class="command">pkcs11-keygen</strong></span> causes a PKCS#11 device to generate |
|
- a new RSA key pair with the specified <code class="option">label</code> and |
|
- with <code class="option">keysize</code> bits of modulus. |
|
+ a new key pair with the given <code class="option">label</code> (which must be |
|
+ unique) and with <code class="option">keysize</code> bits of prime. |
|
</p> |
|
</div> |
|
<div class="refsect1" lang="en"> |
|
-<a name="id2543416"></a><h2>ARGUMENTS</h2> |
|
+<a name="id2543430"></a><h2>ARGUMENTS</h2> |
|
<div class="variablelist"><dl> |
|
-<dt><span class="term">-P</span></dt> |
|
+<dt><span class="term">-a <em class="replaceable"><code>algorithm</code></em></span></dt> |
|
<dd><p> |
|
- Set the new private key to be non-sensitive and extractable. |
|
- The allows the private key data to be read from the PKCS#11 |
|
- device. The default is for private keys to be sensitive and |
|
- non-extractable. |
|
+ Specify the key algorithm class: Supported classes are RSA, |
|
+ DSA, DH, and ECC. In addition to these strings, the |
|
+ <code class="option">algorithm</code> can be specified as a DNSSEC |
|
+ signing algorithm that will be used with this key; for |
|
+ example, NSEC3RSASHA1 maps to RSA, and ECDSAP256SHA256 maps |
|
+ to ECC. The default class is "RSA". |
|
+ </p></dd> |
|
+<dt><span class="term">-b <em class="replaceable"><code>keysize</code></em></span></dt> |
|
+<dd><p> |
|
+ Create the key pair with <code class="option">keysize</code> bits of |
|
+ prime. For ECC keys, the only valid values are 256 and 384, |
|
+ and the default is 256. |
|
+ </p></dd> |
|
+<dt><span class="term">-e</span></dt> |
|
+<dd><p> |
|
+ For RSA keys only, use a large exponent. |
|
+ </p></dd> |
|
+<dt><span class="term">-i <em class="replaceable"><code>id</code></em></span></dt> |
|
+<dd><p> |
|
+ Create key objects with id. The id is either |
|
+ an unsigned short 2 byte or an unsigned long 4 byte number. |
|
</p></dd> |
|
<dt><span class="term">-m <em class="replaceable"><code>module</code></em></span></dt> |
|
<dd><p> |
|
@@ -55,51 +72,48 @@ |
|
path to a shared library object implementing the PKCS#11 API |
|
for the device. |
|
</p></dd> |
|
-<dt><span class="term">-s <em class="replaceable"><code>slot</code></em></span></dt> |
|
-<dd><p> |
|
- Open the session with the given PKCS#11 slot. The default is |
|
- slot 0. |
|
- </p></dd> |
|
-<dt><span class="term">-e</span></dt> |
|
+<dt><span class="term">-P</span></dt> |
|
<dd><p> |
|
- Use a large exponent. |
|
+ Set the new private key to be non-sensitive and extractable. |
|
+ The allows the private key data to be read from the PKCS#11 |
|
+ device. The default is for private keys to be sensitive and |
|
+ non-extractable. |
|
</p></dd> |
|
-<dt><span class="term">-b <em class="replaceable"><code>keysize</code></em></span></dt> |
|
+<dt><span class="term">-p <em class="replaceable"><code>PIN</code></em></span></dt> |
|
<dd><p> |
|
- Create the key pair with <code class="option">keysize</code> bits of |
|
- modulus. |
|
+ Specify the PIN for the device. If no PIN is provided on |
|
+ the command line, <span><strong class="command">pkcs11-ecgen</strong></span> will |
|
+ prompt for it. |
|
</p></dd> |
|
-<dt><span class="term">-l <em class="replaceable"><code>label</code></em></span></dt> |
|
+<dt><span class="term">-q</span></dt> |
|
<dd><p> |
|
- Create key objects with the given label. |
|
- This name must be unique. |
|
+ Quiet mode: suppress unnecessary output. |
|
</p></dd> |
|
-<dt><span class="term">-i <em class="replaceable"><code>id</code></em></span></dt> |
|
+<dt><span class="term">-S</span></dt> |
|
<dd><p> |
|
- Create key objects with id. The id is either |
|
- an unsigned short 2 byte or an unsigned long 4 byte number. |
|
+ For Diffie-Hellman (DH) keys only, use a special prime of |
|
+ 768, 1024 or 1536 bit size and base (aka generator) 2. |
|
+ If not specified, bit size will default to 1024. |
|
</p></dd> |
|
-<dt><span class="term">-p <em class="replaceable"><code>PIN</code></em></span></dt> |
|
+<dt><span class="term">-s <em class="replaceable"><code>slot</code></em></span></dt> |
|
<dd><p> |
|
- Specify the PIN for the device. If no PIN is provided on the |
|
- command line, <span><strong class="command">pkcs11-keygen</strong></span> will prompt for it. |
|
+ Open the session with the given PKCS#11 slot. The default is |
|
+ slot 0. |
|
</p></dd> |
|
</dl></div> |
|
</div> |
|
<div class="refsect1" lang="en"> |
|
-<a name="id2543563"></a><h2>SEE ALSO</h2> |
|
+<a name="id2543605"></a><h2>SEE ALSO</h2> |
|
<p> |
|
+ <span class="citerefentry"><span class="refentrytitle">pkcs11-rsagen</span>(3)</span>, |
|
+ <span class="citerefentry"><span class="refentrytitle">pkcs11-dsagen</span>(3)</span>, |
|
<span class="citerefentry"><span class="refentrytitle">pkcs11-list</span>(3)</span>, |
|
<span class="citerefentry"><span class="refentrytitle">pkcs11-destroy</span>(3)</span>, |
|
<span class="citerefentry"><span class="refentrytitle">dnssec-keyfromlabel</span>(3)</span>, |
|
</p> |
|
</div> |
|
<div class="refsect1" lang="en"> |
|
-<a name="id2543598"></a><h2>CAVEAT</h2> |
|
-<p>Some PKCS#11 providers crash with big public exponent.</p> |
|
-</div> |
|
-<div class="refsect1" lang="en"> |
|
-<a name="id2543609"></a><h2>AUTHOR</h2> |
|
+<a name="id2543657"></a><h2>AUTHOR</h2> |
|
<p><span class="corpauthor">Internet Systems Consortium</span> |
|
</p> |
|
</div> |
|
diff --git a/bin/pkcs11/pkcs11-list.c b/bin/pkcs11/pkcs11-list.c |
|
index 336bf41..bc6ad28 100644 |
|
--- a/bin/pkcs11/pkcs11-list.c |
|
+++ b/bin/pkcs11/pkcs11-list.c |
|
@@ -52,74 +52,68 @@ |
|
#include <errno.h> |
|
#include <string.h> |
|
#include <sys/types.h> |
|
-#include "cryptoki.h" |
|
|
|
-#ifdef WIN32 |
|
-#include "win32.c" |
|
-#else |
|
-#ifndef FORCE_STATIC_PROVIDER |
|
-#include "unix.c" |
|
-#endif |
|
-#endif |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
|
|
#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
#define getpassphrase(x) getpass(x) |
|
#endif |
|
|
|
int |
|
-main(int argc, char *argv[]) |
|
-{ |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
CK_RV rv; |
|
CK_SLOT_ID slot = 0; |
|
CK_SESSION_HANDLE hSession; |
|
- CK_UTF8CHAR *pin = NULL; |
|
CK_BYTE attr_id[2]; |
|
CK_OBJECT_HANDLE akey[50]; |
|
+ pk11_context_t pctx; |
|
+ char *lib_name = NULL; |
|
char *label = NULL; |
|
- int error = 0, public = 0, all = 0; |
|
+ char *pin = NULL; |
|
+ isc_boolean_t error = ISC_FALSE, logon = ISC_TRUE, all = ISC_FALSE; |
|
unsigned int i = 0, id = 0; |
|
int c, errflg = 0; |
|
CK_ULONG ulObjectCount; |
|
CK_ATTRIBUTE search_template[] = { |
|
{CKA_ID, &attr_id, sizeof(attr_id)} |
|
}; |
|
- char *pk11_provider; |
|
- extern char *optarg; |
|
- extern int optopt; |
|
|
|
- pk11_provider = getenv("PKCS11_PROVIDER"); |
|
- if (pk11_provider != NULL) |
|
- pk11_libname = pk11_provider; |
|
- |
|
- while ((c = getopt(argc, argv, ":m:s:i:l:p:P")) != -1) { |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:i:l:p:P")) != -1) { |
|
switch (c) { |
|
case 'P': |
|
- public = 1; |
|
+ logon = ISC_FALSE; |
|
break; |
|
case 'm': |
|
- pk11_libname = optarg; |
|
+ lib_name = isc_commandline_argument; |
|
break; |
|
case 's': |
|
- slot = atoi(optarg); |
|
+ slot = atoi(isc_commandline_argument); |
|
break; |
|
case 'i': |
|
- id = atoi(optarg); |
|
+ id = atoi(isc_commandline_argument); |
|
id &= 0xffff; |
|
break; |
|
case 'l': |
|
- label = optarg; |
|
+ label = isc_commandline_argument; |
|
break; |
|
case 'p': |
|
- pin = (CK_UTF8CHAR *)optarg; |
|
+ pin = isc_commandline_argument; |
|
break; |
|
case ':': |
|
fprintf(stderr, "Option -%c requires an operand\n", |
|
- optopt); |
|
+ isc_commandline_option); |
|
errflg++; |
|
break; |
|
case '?': |
|
default: |
|
- fprintf(stderr, "Unrecognised option: -%c\n", optopt); |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
errflg++; |
|
} |
|
} |
|
@@ -132,7 +126,7 @@ main(int argc, char *argv[]) |
|
} |
|
|
|
if (!id && (label == NULL)) |
|
- all = 1; |
|
+ all = ISC_TRUE; |
|
|
|
if (slot) |
|
printf("slot %lu\n", slot); |
|
@@ -148,41 +142,37 @@ main(int argc, char *argv[]) |
|
search_template[0].ulValueLen = strlen(label); |
|
} |
|
|
|
+ pk11_result_register(); |
|
+ |
|
/* Initialize the CRYPTOKI library */ |
|
- rv = C_Initialize(NULL_PTR); |
|
- if (rv != CKR_OK) { |
|
- if (rv == 0xfe) |
|
- fprintf(stderr, |
|
- "Can't load or link module \"%s\"\n", |
|
- pk11_libname); |
|
- else |
|
- fprintf(stderr, "C_Initialize: Error = 0x%.8lX\n", rv); |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ if (logon && pin == NULL) |
|
+ pin = getpassphrase("Enter Pin: "); |
|
+ |
|
+ result = pk11_get_session(&pctx, OP_ANY, ISC_FALSE, ISC_FALSE, |
|
+ logon, pin, slot); |
|
+ if (result == PK11_R_NORANDOMSERVICE || |
|
+ result == PK11_R_NODIGESTSERVICE || |
|
+ result == PK11_R_NOAESSERVICE) { |
|
+ fprintf(stderr, "Warning: %s\n", isc_result_totext(result)); |
|
+ fprintf(stderr, "This HSM will not work with BIND 9 " |
|
+ "using native PKCS#11.\n"); |
|
+ } else if (result != ISC_R_SUCCESS) { |
|
+ fprintf(stderr, "Unrecoverable error initializing " |
|
+ "PKCS#11: %s\n", isc_result_totext(result)); |
|
+ fprintf(stderr, "Unrecoverable error initializing " |
|
+ "PKCS#11: %s\n", isc_result_totext(result)); |
|
exit(1); |
|
} |
|
|
|
- /* Open a session on the slot found */ |
|
- rv = C_OpenSession(slot, CKF_SERIAL_SESSION, |
|
- NULL_PTR, NULL_PTR, &hSession); |
|
- if (rv != CKR_OK) { |
|
- fprintf(stderr, "C_OpenSession: Error = 0x%.8lX\n", rv); |
|
- error = 1; |
|
- goto exit_program; |
|
- } |
|
+ if (pin != NULL) |
|
+ memset(pin, 0, strlen(pin)); |
|
|
|
- /* Login to the Token (Keystore) */ |
|
- if (!public) { |
|
- if (pin == NULL) |
|
- pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: "); |
|
- rv = C_Login(hSession, CKU_USER, pin, strlen((char *)pin)); |
|
- memset(pin, 0, strlen((char *)pin)); |
|
- if (rv != CKR_OK) { |
|
- fprintf(stderr, "C_Login: Error = 0x%.8lX\n", rv); |
|
- error = 1; |
|
- goto exit_session; |
|
- } |
|
- } |
|
+ hSession = pctx.session; |
|
|
|
- rv = C_FindObjectsInit(hSession, search_template, all ? 0 : 1); |
|
+ rv = pkcs_C_FindObjectsInit(hSession, search_template, all ? 0 : 1); |
|
if (rv != CKR_OK) { |
|
fprintf(stderr, "C_FindObjectsInit: Error = 0x%.8lX\n", rv); |
|
error = 1; |
|
@@ -191,7 +181,7 @@ main(int argc, char *argv[]) |
|
|
|
ulObjectCount = 1; |
|
while (ulObjectCount) { |
|
- rv = C_FindObjects(hSession, akey, 50, &ulObjectCount); |
|
+ rv = pkcs_C_FindObjects(hSession, akey, 50, &ulObjectCount); |
|
if (rv != CKR_OK) { |
|
fprintf(stderr, |
|
"C_FindObjects: Error = 0x%.8lX\n", |
|
@@ -215,7 +205,7 @@ main(int argc, char *argv[]) |
|
memset(labelbuf, 0, sizeof(labelbuf)); |
|
memset(idbuf, 0, sizeof(idbuf)); |
|
|
|
- rv = C_GetAttributeValue(hSession, akey[i], |
|
+ rv = pkcs_C_GetAttributeValue(hSession, akey[i], |
|
template, 3); |
|
if (rv != CKR_OK) { |
|
fprintf(stderr, |
|
@@ -260,17 +250,15 @@ main(int argc, char *argv[]) |
|
} |
|
|
|
exit_search: |
|
- rv = C_FindObjectsFinal(hSession); |
|
+ rv = pkcs_C_FindObjectsFinal(hSession); |
|
if (rv != CKR_OK) { |
|
fprintf(stderr, "C_FindObjectsFinal: Error = 0x%.8lX\n", rv); |
|
error = 1; |
|
} |
|
|
|
exit_session: |
|
- (void)C_CloseSession(hSession); |
|
- |
|
- exit_program: |
|
- (void)C_Finalize(NULL_PTR); |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
|
|
exit(error); |
|
} |
|
diff --git a/bin/pkcs11/pkcs11-tokens.8 b/bin/pkcs11/pkcs11-tokens.8 |
|
new file mode 100644 |
|
index 0000000..7c2be83 |
|
--- /dev/null |
|
+++ b/bin/pkcs11/pkcs11-tokens.8 |
|
@@ -0,0 +1,51 @@ |
|
+.\" Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") |
|
+.\" |
|
+.\" Permission to use, copy, modify, and/or distribute this software for any |
|
+.\" purpose with or without fee is hereby granted, provided that the above |
|
+.\" copyright notice and this permission notice appear in all copies. |
|
+.\" |
|
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+.\" AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+.\" INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+.\" LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+.\" OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+.\" PERFORMANCE OF THIS SOFTWARE. |
|
+.\" |
|
+.\" $Id$ |
|
+.\" |
|
+.hy 0 |
|
+.ad l |
|
+.\" Title: pkcs11\-tokens |
|
+.\" Author: |
|
+.\" Generator: DocBook XSL Stylesheets v1.71.1 <http://docbook.sf.net/> |
|
+.\" Date: August 25, 2013 |
|
+.\" Manual: BIND9 |
|
+.\" Source: BIND9 |
|
+.\" |
|
+.TH "PKCS11\-TOKENS" "8" "August 25, 2013" "BIND9" "BIND9" |
|
+.\" disable hyphenation |
|
+.nh |
|
+.\" disable justification (adjust text to left margin only) |
|
+.ad l |
|
+.SH "NAME" |
|
+pkcs11\-tokens \- list PKCS#11 available tokens |
|
+.SH "SYNOPSIS" |
|
+.HP 14 |
|
+\fBpkcs11\-tokens\fR [\fB\-m\ \fR\fB\fImodule\fR\fR] |
|
+.SH "DESCRIPTION" |
|
+.PP |
|
+\fBpkcs11\-tokens\fR |
|
+lists the PKCS#11 available tokens with defaults from the slot/token scan performed at application initialization. |
|
+.SH "ARGUMENTS" |
|
+.PP |
|
+\-m \fImodule\fR |
|
+.RS 4 |
|
+Specify the PKCS#11 provider module. This must be the full path to a shared library object implementing the PKCS#11 API for the device. |
|
+.RE |
|
+.SH "AUTHOR" |
|
+.PP |
|
+Internet Systems Consortium |
|
+.SH "COPYRIGHT" |
|
+Copyright \(co 2013 Internet Systems Consortium, Inc. ("ISC") |
|
+.br |
|
diff --git a/bin/pkcs11/pkcs11-tokens.c b/bin/pkcs11/pkcs11-tokens.c |
|
new file mode 100644 |
|
index 0000000..ff4e030 |
|
--- /dev/null |
|
+++ b/bin/pkcs11/pkcs11-tokens.c |
|
@@ -0,0 +1,106 @@ |
|
+/* |
|
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* pkcs11-tokens [-m module] */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <fcntl.h> |
|
+#include <errno.h> |
|
+#include <string.h> |
|
+#include <sys/types.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/mem.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
+ char *lib_name = NULL; |
|
+ int c, errflg = 0; |
|
+ isc_mem_t *mctx = NULL; |
|
+ pk11_context_t pctx; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, "\tpkcs11-tokens [-m module]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ if (isc_mem_create(0, 0, &mctx) != ISC_R_SUCCESS) { |
|
+ fprintf(stderr, "isc_mem_create() failed\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ pk11_result_register(); |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ result = pk11_get_session(&pctx, OP_ANY, ISC_FALSE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0); |
|
+ if (result == PK11_R_NORANDOMSERVICE || |
|
+ result == PK11_R_NODIGESTSERVICE || |
|
+ result == PK11_R_NOAESSERVICE) { |
|
+ fprintf(stderr, "Warning: %s\n", isc_result_totext(result)); |
|
+ fprintf(stderr, "This HSM will not work with BIND 9 " |
|
+ "using native PKCS#11.\n\n"); |
|
+ } else if (result != ISC_R_SUCCESS) { |
|
+ fprintf(stderr, "Unrecoverable error initializing " |
|
+ "PKCS#11: %s\n", isc_result_totext(result)); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ pk11_dump_tokens(); |
|
+ |
|
+ if (pctx.handle != NULL) |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
+ |
|
+ isc_mem_destroy(&mctx); |
|
+ |
|
+ exit(0); |
|
+} |
|
diff --git a/bin/pkcs11/pkcs11-tokens.docbook b/bin/pkcs11/pkcs11-tokens.docbook |
|
new file mode 100644 |
|
index 0000000..44dc7cd |
|
--- /dev/null |
|
+++ b/bin/pkcs11/pkcs11-tokens.docbook |
|
@@ -0,0 +1,86 @@ |
|
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" |
|
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" |
|
+ [<!ENTITY mdash "—">]> |
|
+<!-- |
|
+ - Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") |
|
+ - |
|
+ - Permission to use, copy, modify, and/or distribute this software for any |
|
+ - purpose with or without fee is hereby granted, provided that the above |
|
+ - copyright notice and this permission notice appear in all copies. |
|
+ - |
|
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ - PERFORMANCE OF THIS SOFTWARE. |
|
+--> |
|
+ |
|
+<!-- $Id$ --> |
|
+<refentry id="man.pkcs11-tokens"> |
|
+ <refentryinfo> |
|
+ <date>August 25, 2013</date> |
|
+ </refentryinfo> |
|
+ |
|
+ <refmeta> |
|
+ <refentrytitle><application>pkcs11-tokens</application></refentrytitle> |
|
+ <manvolnum>8</manvolnum> |
|
+ <refmiscinfo>BIND9</refmiscinfo> |
|
+ </refmeta> |
|
+ |
|
+ <refnamediv> |
|
+ <refname><application>pkcs11-tokens</application></refname> |
|
+ <refpurpose>list PKCS#11 available tokens</refpurpose> |
|
+ </refnamediv> |
|
+ |
|
+ <docinfo> |
|
+ <copyright> |
|
+ <year>2013</year> |
|
+ <holder>Internet Systems Consortium, Inc. ("ISC")</holder> |
|
+ </copyright> |
|
+ </docinfo> |
|
+ |
|
+ <refsynopsisdiv> |
|
+ <cmdsynopsis> |
|
+ <command>pkcs11-tokens</command> |
|
+ <arg><option>-m <replaceable class="parameter">module</replaceable></option></arg> |
|
+ </cmdsynopsis> |
|
+ </refsynopsisdiv> |
|
+ |
|
+ <refsect1> |
|
+ <title>DESCRIPTION</title> |
|
+ <para> |
|
+ <command>pkcs11-tokens</command> |
|
+ lists the PKCS#11 available tokens with defaults from the slot/token |
|
+ scan performed at application initialization. |
|
+ </para> |
|
+ </refsect1> |
|
+ |
|
+ <refsect1> |
|
+ <title>ARGUMENTS</title> |
|
+ <variablelist> |
|
+ <varlistentry> |
|
+ <term>-m <replaceable class="parameter">module</replaceable></term> |
|
+ <listitem> |
|
+ <para> |
|
+ Specify the PKCS#11 provider module. This must be the full |
|
+ path to a shared library object implementing the PKCS#11 API |
|
+ for the device. |
|
+ </para> |
|
+ </listitem> |
|
+ </varlistentry> |
|
+ </variablelist> |
|
+ </refsect1> |
|
+ |
|
+ <refsect1> |
|
+ <title>AUTHOR</title> |
|
+ <para><corpauthor>Internet Systems Consortium</corpauthor> |
|
+ </para> |
|
+ </refsect1> |
|
+ |
|
+</refentry><!-- |
|
+ - Local variables: |
|
+ - mode: sgml |
|
+ - End: |
|
+--> |
|
diff --git a/bin/pkcs11/pkcs11-tokens.html b/bin/pkcs11/pkcs11-tokens.html |
|
new file mode 100644 |
|
index 0000000..45d7243 |
|
--- /dev/null |
|
+++ b/bin/pkcs11/pkcs11-tokens.html |
|
@@ -0,0 +1,58 @@ |
|
+<!-- |
|
+ - Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") |
|
+ - |
|
+ - Permission to use, copy, modify, and/or distribute this software for any |
|
+ - purpose with or without fee is hereby granted, provided that the above |
|
+ - copyright notice and this permission notice appear in all copies. |
|
+ - |
|
+ - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ - PERFORMANCE OF THIS SOFTWARE. |
|
+--> |
|
+<!-- $Id$ --> |
|
+<html> |
|
+<head> |
|
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> |
|
+<title>pkcs11-tokens</title> |
|
+<meta name="generator" content="DocBook XSL Stylesheets V1.71.1"> |
|
+</head> |
|
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="refentry" lang="en"> |
|
+<a name="man.pkcs11-tokens"></a><div class="titlepage"></div> |
|
+<div class="refnamediv"> |
|
+<h2>Name</h2> |
|
+<p><span class="application">pkcs11-tokens</span> — list PKCS#11 available tokens</p> |
|
+</div> |
|
+<div class="refsynopsisdiv"> |
|
+<h2>Synopsis</h2> |
|
+<div class="cmdsynopsis"><p><code class="command">pkcs11-tokens</code> [<code class="option">-m <em class="replaceable"><code>module</code></em></code>]</p></div> |
|
+</div> |
|
+<div class="refsect1" lang="en"> |
|
+<a name="id2543342"></a><h2>DESCRIPTION</h2> |
|
+<p> |
|
+ <span><strong class="command">pkcs11-tokens</strong></span> |
|
+ lists the PKCS#11 available tokens with defaults from the slot/token |
|
+ scan performed at application initialization. |
|
+ </p> |
|
+</div> |
|
+<div class="refsect1" lang="en"> |
|
+<a name="id2543355"></a><h2>ARGUMENTS</h2> |
|
+<div class="variablelist"><dl> |
|
+<dt><span class="term">-m <em class="replaceable"><code>module</code></em></span></dt> |
|
+<dd><p> |
|
+ Specify the PKCS#11 provider module. This must be the full |
|
+ path to a shared library object implementing the PKCS#11 API |
|
+ for the device. |
|
+ </p></dd> |
|
+</dl></div> |
|
+</div> |
|
+<div class="refsect1" lang="en"> |
|
+<a name="id2543382"></a><h2>AUTHOR</h2> |
|
+<p><span class="corpauthor">Internet Systems Consortium</span> |
|
+ </p> |
|
+</div> |
|
+</div></body> |
|
+</html> |
|
diff --git a/bin/rndc/Makefile.in b/bin/rndc/Makefile.in |
|
index f6100df..bc0657a 100644 |
|
--- a/bin/rndc/Makefile.in |
|
+++ b/bin/rndc/Makefile.in |
|
@@ -45,7 +45,8 @@ BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@ |
|
LIBS = ${ISCLIBS} @LIBS@ |
|
NOSYMLIBS = ${ISCNOSYMLIBS} @LIBS@ |
|
|
|
-RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${BIND9DEPLIBS} ${DNSDEPLIBS} ${ISCDEPLIBS} |
|
+RNDCDEPLIBS = ${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${BIND9DEPLIBS} \ |
|
+ ${DNSDEPLIBS} ${ISCDEPLIBS} |
|
|
|
CONFDEPLIBS = ${DNSDEPLIBS} ${ISCDEPLIBS} |
|
|
|
diff --git a/bin/tests/Makefile.in b/bin/tests/Makefile.in |
|
index bc040a3..2020bf4 100644 |
|
--- a/bin/tests/Makefile.in |
|
+++ b/bin/tests/Makefile.in |
|
@@ -42,7 +42,7 @@ LWRESDEPLIBS = ../../lib/lwres/liblwres.@A@ |
|
LIBS = @LIBS@ |
|
|
|
SUBDIRS = atomic db dst master mem hashes names net rbt resolver \ |
|
- sockaddr tasks timers system |
|
+ sockaddr tasks timers system @PKCS11_TOOLS@ |
|
|
|
# Test programs that are built by default: |
|
# cfg_test is needed for regenerating doc/misc/options |
|
@@ -173,139 +173,139 @@ backtrace_test@EXEEXT@: backtrace_test_nosymtbl@EXEEXT@ |
|
nsecify@EXEEXT@: nsecify.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ nsecify.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
byaddr_test@EXEEXT@: byaddr_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ byaddr_test.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
byname_test@EXEEXT@: byname_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ byname_test.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
lex_test@EXEEXT@: lex_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ lex_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
lfsr_test@EXEEXT@: lfsr_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ lfsr_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
log_test@EXEEXT@: log_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ log_test.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
name_test@EXEEXT@: name_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ name_test.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
hash_test@EXEEXT@: hash_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ hash_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
entropy_test@EXEEXT@: entropy_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ entropy_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
entropy2_test@EXEEXT@: entropy2_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ entropy2_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
sock_test@EXEEXT@: sock_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ sock_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
sym_test@EXEEXT@: sym_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ sym_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
task_test@EXEEXT@: task_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ task_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
shutdown_test@EXEEXT@: shutdown_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ shutdown_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
timer_test@EXEEXT@: timer_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ timer_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
ratelimiter_test@EXEEXT@: ratelimiter_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ratelimiter_test.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
rbt_test@EXEEXT@: rbt_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rbt_test.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
rdata_test@EXEEXT@: rdata_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rdata_test.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
rwlock_test@EXEEXT@: rwlock_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ rwlock_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
wire_test@EXEEXT@: wire_test.@O@ printmsg.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ wire_test.@O@ printmsg.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
master_test@EXEEXT@: master_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ master_test.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
db_test@EXEEXT@: db_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ db_test.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
compress_test@EXEEXT@: compress_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ compress_test.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
mempool_test@EXEEXT@: mempool_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ mempool_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
serial_test@EXEEXT@: serial_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ serial_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
zone_test@EXEEXT@: zone_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ zone_test.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
fsaccess_test@EXEEXT@: fsaccess_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ fsaccess_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
inter_test@EXEEXT@: inter_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ inter_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
keyboard_test@EXEEXT@: keyboard_test.@O@ ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ keyboard_test.@O@ \ |
|
${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
lwresconf_test@EXEEXT@: lwresconf_test.@O@ ${ISCDEPLIBS} ${LWRESDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ lwresconf_test.@O@ \ |
|
${LWRESLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
lwres_test@EXEEXT@: lwres_test.@O@ ${ISCDEPLIBS} ${LWRESDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ lwres_test.@O@ \ |
|
- ${LWRESLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
-gxbn_test@EXEEXT@: gxbn_test.@O@ ${LWRESDEPLIBS} |
|
+ ${LWRESLIBS} ${ISCLIBS} ${LIBS} |
|
+ |
|
+ gxbn_test@EXEEXT@: gxbn_test.@O@ ${LWRESDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ gxbn_test.@O@ \ |
|
${LWRESLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
-gxba_test@EXEEXT@: gxba_test.@O@ ${LWRESDEPLIBS} |
|
+ |
|
+ gxba_test@EXEEXT@: gxba_test.@O@ ${LWRESDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ gxba_test.@O@ \ |
|
${LWRESLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
sig0_test@EXEEXT@: sig0_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ sig0_test.@O@ \ |
|
${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
- |
|
+ |
|
cfg_test@EXEEXT@: cfg_test.@O@ ${ISCCFGDEPLIBS} ${ISCDEPLIBS} |
|
${LIBTOOL_MODE_LINK} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ cfg_test.@O@ \ |
|
${ISCCFGLIBS} ${DNSLIBS} ${ISCLIBS} ${LIBS} |
|
diff --git a/bin/tests/dst/dst_test.c b/bin/tests/dst/dst_test.c |
|
index bf305d8..240dc6f 100644 |
|
--- a/bin/tests/dst/dst_test.c |
|
+++ b/bin/tests/dst/dst_test.c |
|
@@ -30,6 +30,7 @@ |
|
#include <isc/string.h> /* Required for HP/UX (and others?) */ |
|
|
|
#include <dns/fixedname.h> |
|
+#include <dns/log.h> |
|
#include <dns/name.h> |
|
#include <dns/result.h> |
|
|
|
@@ -58,7 +59,8 @@ use(dst_key_t *key, isc_mem_t *mctx) { |
|
isc_buffer_add(&databuf, strlen(data)); |
|
isc_buffer_usedregion(&databuf, &datareg); |
|
|
|
- ret = dst_context_create(key, mctx, &ctx); |
|
+ ret = dst_context_create3(key, mctx, |
|
+ DNS_LOGCATEGORY_GENERAL, ISC_TRUE, &ctx); |
|
if (ret != ISC_R_SUCCESS) { |
|
printf("contextcreate(%d) returned: %s\n", dst_key_alg(key), |
|
isc_result_totext(ret)); |
|
@@ -78,7 +80,8 @@ use(dst_key_t *key, isc_mem_t *mctx) { |
|
|
|
isc_buffer_forward(&sigbuf, 1); |
|
isc_buffer_remainingregion(&sigbuf, &sigreg); |
|
- ret = dst_context_create(key, mctx, &ctx); |
|
+ ret = dst_context_create3(key, mctx, |
|
+ DNS_LOGCATEGORY_GENERAL, ISC_FALSE, &ctx); |
|
if (ret != ISC_R_SUCCESS) { |
|
printf("contextcreate(%d) returned: %s\n", dst_key_alg(key), |
|
isc_result_totext(ret)); |
|
diff --git a/bin/tests/dst/t_dst.c b/bin/tests/dst/t_dst.c |
|
index e431c95..59c7835 100644 |
|
--- a/bin/tests/dst/t_dst.c |
|
+++ b/bin/tests/dst/t_dst.c |
|
@@ -108,7 +108,8 @@ use(dst_key_t *key, isc_mem_t *mctx, isc_result_t exp_result, int *nfails) { |
|
isc_buffer_add(&databuf, strlen(data)); |
|
isc_buffer_usedregion(&databuf, &datareg); |
|
|
|
- ret = dst_context_create(key, mctx, &ctx); |
|
+ ret = dst_context_create3(key, mctx, |
|
+ DNS_LOGCATEGORY_GENERAL, ISC_TRUE, &ctx); |
|
if (ret != exp_result) { |
|
t_info("dst_context_create(%d) returned (%s) expected (%s)\n", |
|
dst_key_alg(key), dst_result_totext(ret), |
|
@@ -137,7 +138,8 @@ use(dst_key_t *key, isc_mem_t *mctx, isc_result_t exp_result, int *nfails) { |
|
dst_context_destroy(&ctx); |
|
|
|
isc_buffer_remainingregion(&sigbuf, &sigreg); |
|
- ret = dst_context_create(key, mctx, &ctx); |
|
+ ret = dst_context_create3(key, mctx, |
|
+ DNS_LOGCATEGORY_GENERAL, ISC_FALSE, &ctx); |
|
if (ret != ISC_R_SUCCESS) { |
|
t_info("dst_context_create(%d) returned (%s)\n", |
|
dst_key_alg(key), dst_result_totext(ret)); |
|
@@ -783,7 +785,9 @@ t2_sigchk(char *datapath, char *sigpath, char *keyname, |
|
memset(sig, 0, sizeof(sig)); |
|
isc_buffer_init(&sigbuf, sig, sizeof(sig)); |
|
|
|
- isc_result = dst_context_create(key, mctx, &ctx); |
|
+ isc_result = dst_context_create3(key, mctx, |
|
+ DNS_LOGCATEGORY_GENERAL, |
|
+ ISC_TRUE, &ctx); |
|
if (isc_result != ISC_R_SUCCESS) { |
|
t_info("dst_context_create(%d) failed %s\n", |
|
dst_result_totext(isc_result)); |
|
@@ -849,7 +853,9 @@ t2_sigchk(char *datapath, char *sigpath, char *keyname, |
|
if (strstr(expected_result, "!")) |
|
exp_res = 1; |
|
|
|
- isc_result = dst_context_create(key, mctx, &ctx); |
|
+ isc_result = dst_context_create3(key, mctx, |
|
+ DNS_LOGCATEGORY_GENERAL, |
|
+ ISC_FALSE, &ctx); |
|
if (isc_result != ISC_R_SUCCESS) { |
|
t_info("dst_context_create returned %s\n", |
|
isc_result_totext(isc_result)); |
|
diff --git a/bin/tests/pkcs11/Makefile.in b/bin/tests/pkcs11/Makefile.in |
|
new file mode 100644 |
|
index 0000000..0a6281f |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/Makefile.in |
|
@@ -0,0 +1,49 @@ |
|
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+# |
|
+# Permission to use, copy, modify, and/or distribute this software for any |
|
+# purpose with or without fee is hereby granted, provided that the above |
|
+# copyright notice and this permission notice appear in all copies. |
|
+# |
|
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+# PERFORMANCE OF THIS SOFTWARE. |
|
+ |
|
+srcdir = @srcdir@ |
|
+VPATH = @srcdir@ |
|
+top_srcdir = @top_srcdir@ |
|
+ |
|
+@BIND9_MAKE_INCLUDES@ |
|
+ |
|
+PROVIDER = @PKCS11_PROVIDER@ |
|
+ |
|
+CINCLUDES = ${ISC_INCLUDES} |
|
+ |
|
+CDEFINES = -DPK11_LIB_LOCATION=\"${PROVIDER}\" |
|
+ |
|
+ISCLIBS = ../../../lib/isc/libisc.@A@ |
|
+ |
|
+LIBS = ${ISCLIBS} @LIBS@ |
|
+ |
|
+SUBDIRS = benchmarks |
|
+ |
|
+TARGETS = pkcs11-md5sum@EXEEXT@ pkcs11-hmacmd5@EXEEXT@ |
|
+SRCS = pkcs11-md5sum.c pkcs11-hmacmd5.c |
|
+ |
|
+@BIND9_MAKE_RULES@ |
|
+ |
|
+pkcs11-md5sum@EXEEXT@: @srcdir@/pkcs11-md5sum.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ |
|
+ -o $@ @srcdir@/pkcs11-md5sum.c ${LIBS} |
|
+ |
|
+pkcs11-hmacmd5@EXEEXT@: @srcdir@/pkcs11-hmacmd5.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} \ |
|
+ -o $@ @srcdir@/pkcs11-hmacmd5.c ${LIBS} |
|
+ |
|
+test: |
|
+ |
|
+clean distclean:: |
|
+ rm -f ${TARGETS} |
|
diff --git a/bin/tests/pkcs11/benchmarks/Makefile.in b/bin/tests/pkcs11/benchmarks/Makefile.in |
|
new file mode 100644 |
|
index 0000000..cd0347c |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/benchmarks/Makefile.in |
|
@@ -0,0 +1,79 @@ |
|
+# Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+# |
|
+# Permission to use, copy, modify, and/or distribute this software for any |
|
+# purpose with or without fee is hereby granted, provided that the above |
|
+# copyright notice and this permission notice appear in all copies. |
|
+# |
|
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+# PERFORMANCE OF THIS SOFTWARE. |
|
+ |
|
+# $Id$ |
|
+ |
|
+srcdir = @srcdir@ |
|
+VPATH = @srcdir@ |
|
+top_srcdir = @top_srcdir@ |
|
+ |
|
+@BIND9_MAKE_INCLUDES@ |
|
+ |
|
+PROVIDER = @PKCS11_PROVIDER@ |
|
+ |
|
+CINCLUDES = ${ISC_INCLUDES} |
|
+ |
|
+CDEFINES = -DPK11_LIB_LOCATION=\"${PROVIDER}\" |
|
+ |
|
+ISCLIBS = ../../../../lib/isc/libisc.@A@ |
|
+ |
|
+LIBS = ${ISCLIBS} @LIBS@ |
|
+ |
|
+SUBDIRS = |
|
+ |
|
+TARGETS = session@EXEEXT@ login@EXEEXT@ random@EXEEXT@ \ |
|
+ sha1@EXEEXT@ create@EXEEXT@ find@EXEEXT@ \ |
|
+ pubrsa@EXEEXT@ privrsa@EXEEXT@ genrsa@EXEEXT@ \ |
|
+ sign@EXEEXT@ verify@EXEEXT@ |
|
+ |
|
+SRCS = session.c login.c random.c sha1.c create.c find.c \ |
|
+ pubrsa.c privrsa.c genrsa.c sign.c verify.c |
|
+ |
|
+@BIND9_MAKE_RULES@ |
|
+ |
|
+session@EXEEXT@: @srcdir@/session.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ @srcdir@/session.c ${LIBS} |
|
+ |
|
+login@EXEEXT@: @srcdir@/login.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ @srcdir@/login.c ${LIBS} |
|
+ |
|
+random@EXEEXT@: @srcdir@/random.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ @srcdir@/random.c ${LIBS} |
|
+ |
|
+sha1@EXEEXT@: @srcdir@/sha1.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ @srcdir@/sha1.c ${LIBS} |
|
+ |
|
+create@EXEEXT@: @srcdir@/create.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ @srcdir@/create.c ${LIBS} |
|
+ |
|
+find@EXEEXT@: @srcdir@/find.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ @srcdir@/find.c ${LIBS} |
|
+ |
|
+pubrsa@EXEEXT@: @srcdir@/pubrsa.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ @srcdir@/pubrsa.c ${LIBS} |
|
+ |
|
+privrsa@EXEEXT@: @srcdir@/privrsa.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ @srcdir@/privrsa.c ${LIBS} |
|
+ |
|
+genrsa@EXEEXT@: @srcdir@/genrsa.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ @srcdir@/genrsa.c ${LIBS} |
|
+ |
|
+sign@EXEEXT@: @srcdir@/sign.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ @srcdir@/sign.c ${LIBS} |
|
+ |
|
+verify@EXEEXT@: @srcdir@/verify.c |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ @srcdir@/verify.c ${LIBS} |
|
+ |
|
+clean distclean:: |
|
+ rm -f ${TARGETS} |
|
diff --git a/bin/tests/pkcs11/benchmarks/create.c b/bin/tests/pkcs11/benchmarks/create.c |
|
new file mode 100644 |
|
index 0000000..d0d8c77 |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/benchmarks/create.c |
|
@@ -0,0 +1,260 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* create [-m module] [-s $slot] [-p pin] [-t] [-n count] */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <time.h> |
|
+#include <unistd.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
+#define getpassphrase(x) getpass(x) |
|
+#endif |
|
+ |
|
+#ifndef HAVE_CLOCK_GETTIME |
|
+#ifndef CLOCK_REALTIME |
|
+#define CLOCK_REALTIME 0 |
|
+#endif |
|
+ |
|
+int |
|
+clock_gettime(int32_t id, struct timespec *tp) |
|
+{ |
|
+ struct timeval tv; |
|
+ int result; |
|
+ |
|
+ result = gettimeofday(&tv, NULL); |
|
+ if (result) |
|
+ return (result); |
|
+ tp->tv_sec = tv.tv_sec; |
|
+ tp->tv_nsec = (long) tv.tv_usec * 1000; |
|
+ return (result); |
|
+} |
|
+#endif |
|
+ |
|
+CK_BYTE buf[1024]; |
|
+char label[16]; |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_HANDLE *hKey; |
|
+ CK_OBJECT_CLASS kClass = CKO_DATA; |
|
+ CK_ULONG len = sizeof(buf); |
|
+ CK_ATTRIBUTE kTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &kClass, (CK_ULONG) sizeof(kClass) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_LABEL, (CK_BYTE_PTR) label, (CK_ULONG) sizeof(label) }, |
|
+ { CKA_VALUE, buf, (CK_ULONG) sizeof(buf) } |
|
+ }; |
|
+ pk11_context_t pctx; |
|
+ char *lib_name = NULL; |
|
+ char *pin = NULL; |
|
+ int error = 0; |
|
+ int c, errflg = 0; |
|
+ int ontoken = 0; |
|
+ unsigned int count = 1000; |
|
+ unsigned int i; |
|
+ struct timespec starttime; |
|
+ struct timespec endtime; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tn:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 't': |
|
+ ontoken = 1; |
|
+ break; |
|
+ case 'p': |
|
+ pin = isc_commandline_argument; |
|
+ break; |
|
+ case 'n': |
|
+ count = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\tcreate [-m module] [-s slot] [-t] [-n count]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ pk11_result_register(); |
|
+ |
|
+ /* Allocate hanles */ |
|
+ hKey = (CK_SESSION_HANDLE *) |
|
+ malloc(count * sizeof(CK_SESSION_HANDLE)); |
|
+ if (hKey == NULL) { |
|
+ perror("malloc"); |
|
+ exit(1); |
|
+ } |
|
+ for (i = 0; i < count; i++) |
|
+ hKey[i] = CK_INVALID_HANDLE; |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ if (pin == NULL) |
|
+ pin = getpassphrase("Enter Pin: "); |
|
+ |
|
+ result = pk11_get_session(&pctx, OP_ANY, ISC_TRUE, ISC_TRUE, |
|
+ ISC_TRUE, (const char *) pin, slot); |
|
+ if ((result != ISC_R_SUCCESS) && |
|
+ (result != PK11_R_NORANDOMSERVICE) && |
|
+ (result != PK11_R_NODIGESTSERVICE) && |
|
+ (result != PK11_R_NOAESSERVICE)) { |
|
+ fprintf(stderr, "Error initializing PKCS#11: %s\n", |
|
+ isc_result_totext(result)); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ if (pin != NULL) |
|
+ memset(pin, 0, strlen((char *)pin)); |
|
+ |
|
+ hSession = pctx.session; |
|
+ |
|
+ /* Randomize the buffer */ |
|
+ rv = pkcs_C_GenerateRandom(hSession, buf, len); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, "C_GenerateRandom: Error = 0x%.8lX\n", rv); |
|
+ goto exit_objects; |
|
+ } |
|
+ |
|
+ if (ontoken) |
|
+ kTemplate[1].pValue = &truevalue; |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { |
|
+ perror("clock_gettime(start)"); |
|
+ goto exit_objects; |
|
+ } |
|
+ |
|
+ for (i = 0; i < count; i++) { |
|
+ (void) snprintf(label, sizeof(label), "obj%u", i); |
|
+ kTemplate[3].ulValueLen = strlen(label); |
|
+ rv = pkcs_C_CreateObject(hSession, kTemplate, 5, &hKey[i]); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_CreateObject[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ if (i == 0) |
|
+ goto exit_objects; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { |
|
+ perror("clock_gettime(end)"); |
|
+ goto exit_objects; |
|
+ } |
|
+ |
|
+ endtime.tv_sec -= starttime.tv_sec; |
|
+ endtime.tv_nsec -= starttime.tv_nsec; |
|
+ while (endtime.tv_nsec < 0) { |
|
+ endtime.tv_sec -= 1; |
|
+ endtime.tv_nsec += 1000000000; |
|
+ } |
|
+ printf("%u created objects in %ld.%09lds\n", i, |
|
+ endtime.tv_sec, endtime.tv_nsec); |
|
+ if (i > 0) |
|
+ printf("%g created objects/s\n", |
|
+ 1024 * i / ((double) endtime.tv_sec + |
|
+ (double) endtime.tv_nsec / 1000000000.)); |
|
+ |
|
+ exit_objects: |
|
+ for (i = 0; i < count; i++) { |
|
+ /* Destroy objects */ |
|
+ if (hKey[i] == CK_INVALID_HANDLE) |
|
+ continue; |
|
+ rv = pkcs_C_DestroyObject(hSession, hKey[i]); |
|
+ if ((rv != CKR_OK) && !errflg) { |
|
+ fprintf(stderr, |
|
+ "C_DestroyObject[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ errflg = 1; |
|
+ } |
|
+ } |
|
+ |
|
+ free(hKey); |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/pkcs11/benchmarks/find.c b/bin/tests/pkcs11/benchmarks/find.c |
|
new file mode 100644 |
|
index 0000000..e22b17e |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/benchmarks/find.c |
|
@@ -0,0 +1,227 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* find [-m module] [-s $slot] [-p pin] [-n count] */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <time.h> |
|
+#include <unistd.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
+#define getpassphrase(x) getpass(x) |
|
+#endif |
|
+ |
|
+#ifndef HAVE_CLOCK_GETTIME |
|
+#ifndef CLOCK_REALTIME |
|
+#define CLOCK_REALTIME 0 |
|
+#endif |
|
+ |
|
+int |
|
+clock_gettime(int32_t id, struct timespec *tp) |
|
+{ |
|
+ struct timeval tv; |
|
+ int result; |
|
+ |
|
+ result = gettimeofday(&tv, NULL); |
|
+ if (result) |
|
+ return (result); |
|
+ tp->tv_sec = tv.tv_sec; |
|
+ tp->tv_nsec = (long) tv.tv_usec * 1000; |
|
+ return (result); |
|
+} |
|
+#endif |
|
+ |
|
+CK_BYTE label[] = "foo??bar!!"; |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; |
|
+ CK_ATTRIBUTE sTemplate[] = |
|
+ { |
|
+ { CKA_LABEL, label, (CK_ULONG) sizeof(label) }, |
|
+ }; |
|
+ CK_OBJECT_HANDLE sKey = CK_INVALID_HANDLE; |
|
+ CK_ULONG found = 0; |
|
+ pk11_context_t pctx; |
|
+ pk11_optype_t op_type = OP_RSA; |
|
+ char *lib_name = NULL; |
|
+ char *pin = NULL; |
|
+ int error = 0; |
|
+ int c, errflg = 0; |
|
+ unsigned int count = 1000; |
|
+ unsigned int i; |
|
+ struct timespec starttime; |
|
+ struct timespec endtime; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:p:n:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ op_type = OP_ANY; |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'p': |
|
+ pin = isc_commandline_argument; |
|
+ break; |
|
+ case 'n': |
|
+ count = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\tfind [-m module] [-s slot] [-p pin] [-n count]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ pk11_result_register(); |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ if (pin == NULL) |
|
+ pin = getpassphrase("Enter Pin: "); |
|
+ |
|
+ result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_FALSE, |
|
+ ISC_TRUE, (const char *) pin, slot); |
|
+ if ((result != ISC_R_SUCCESS) && |
|
+ (result != PK11_R_NORANDOMSERVICE) && |
|
+ (result != PK11_R_NODIGESTSERVICE) && |
|
+ (result != PK11_R_NOAESSERVICE)) { |
|
+ fprintf(stderr, "Error initializing PKCS#11: %s\n", |
|
+ isc_result_totext(result)); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ if (pin != NULL) |
|
+ memset(pin, 0, strlen((char *)pin)); |
|
+ |
|
+ hSession = pctx.session; |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { |
|
+ perror("clock_gettime(start)"); |
|
+ goto exit_objects; |
|
+ } |
|
+ |
|
+ for (i = 0; !error && (i < count); i++) { |
|
+ rv = pkcs_C_FindObjectsInit(hSession, sTemplate, 1); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_FindObjectsInit[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ break; |
|
+ } |
|
+ |
|
+ rv = pkcs_C_FindObjects(hSession, &sKey, 1, &found); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_FindObjects[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ /* no break here! */ |
|
+ } |
|
+ |
|
+ rv = pkcs_C_FindObjectsFinal(hSession); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_FindObjectsFinal[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { |
|
+ perror("clock_gettime(end)"); |
|
+ goto exit_objects; |
|
+ } |
|
+ |
|
+ endtime.tv_sec -= starttime.tv_sec; |
|
+ endtime.tv_nsec -= starttime.tv_nsec; |
|
+ while (endtime.tv_nsec < 0) { |
|
+ endtime.tv_sec -= 1; |
|
+ endtime.tv_nsec += 1000000000; |
|
+ } |
|
+ printf("%u object searches in %ld.%09lds\n", i, |
|
+ endtime.tv_sec, endtime.tv_nsec); |
|
+ if (i > 0) |
|
+ printf("%g object searches/s\n", |
|
+ 1024 * i / ((double) endtime.tv_sec + |
|
+ (double) endtime.tv_nsec / 1000000000.)); |
|
+ |
|
+ exit_objects: |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/pkcs11/benchmarks/genrsa.c b/bin/tests/pkcs11/benchmarks/genrsa.c |
|
new file mode 100644 |
|
index 0000000..e9d3c2a |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/benchmarks/genrsa.c |
|
@@ -0,0 +1,295 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* genrsa [-m module] [-s $slot] [-p pin] [-t] [-b bits] [-n count] */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <time.h> |
|
+#include <unistd.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
+#define getpassphrase(x) getpass(x) |
|
+#endif |
|
+ |
|
+#ifndef HAVE_CLOCK_GETTIME |
|
+#ifndef CLOCK_REALTIME |
|
+#define CLOCK_REALTIME 0 |
|
+#endif |
|
+ |
|
+int |
|
+clock_gettime(int32_t id, struct timespec *tp) |
|
+{ |
|
+ struct timeval tv; |
|
+ int result; |
|
+ |
|
+ result = gettimeofday(&tv, NULL); |
|
+ if (result) |
|
+ return (result); |
|
+ tp->tv_sec = tv.tv_sec; |
|
+ tp->tv_nsec = (long) tv.tv_usec * 1000; |
|
+ return (result); |
|
+} |
|
+#endif |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; |
|
+ CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0 }; |
|
+ CK_OBJECT_HANDLE *pubKey; |
|
+ CK_OBJECT_HANDLE *privKey; |
|
+ CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; |
|
+ CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY; |
|
+ CK_KEY_TYPE kType = CKK_RSA; |
|
+ CK_ULONG bits = 1024; |
|
+ CK_BYTE exponent[] = { 0x01, 0x00, 0x01 }; |
|
+ CK_ATTRIBUTE pubTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, |
|
+ { CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_MODULUS_BITS, &bits, (CK_ULONG) sizeof(bits) }, |
|
+ { CKA_PUBLIC_EXPONENT, exponent, (CK_ULONG) sizeof(exponent) } |
|
+ }; |
|
+ CK_ATTRIBUTE privTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, |
|
+ { CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ }; |
|
+ pk11_context_t pctx; |
|
+ pk11_optype_t op_type = OP_RSA; |
|
+ char *lib_name = NULL; |
|
+ char *pin = NULL; |
|
+ int error = 0; |
|
+ int c, errflg = 0; |
|
+ int ontoken = 0; |
|
+ unsigned int count = 1000; |
|
+ unsigned int i; |
|
+ struct timespec starttime; |
|
+ struct timespec endtime; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tb:n:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ op_type = OP_ANY; |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'p': |
|
+ pin = isc_commandline_argument; |
|
+ break; |
|
+ case 't': |
|
+ ontoken = 1; |
|
+ break; |
|
+ case 'b': |
|
+ bits = (CK_ULONG)atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'n': |
|
+ count = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\tgenrsa [-m module] [-s slot] [-p pin] " |
|
+ "[-t] [-b bits] [-n count]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ pk11_result_register(); |
|
+ |
|
+ /* Allocate hanles */ |
|
+ pubKey = (CK_SESSION_HANDLE *) |
|
+ malloc(count * sizeof(CK_SESSION_HANDLE)); |
|
+ if (pubKey == NULL) { |
|
+ perror("malloc"); |
|
+ exit(1); |
|
+ } |
|
+ privKey = (CK_SESSION_HANDLE *) |
|
+ malloc(count * sizeof(CK_SESSION_HANDLE)); |
|
+ if (privKey == NULL) { |
|
+ free(pubKey); |
|
+ perror("malloc"); |
|
+ exit(1); |
|
+ } |
|
+ for (i = 0; i < count; i++) { |
|
+ pubKey[i] = CK_INVALID_HANDLE; |
|
+ privKey[i] = CK_INVALID_HANDLE; |
|
+ } |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ if (pin == NULL) |
|
+ pin = getpassphrase("Enter Pin: "); |
|
+ |
|
+ result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_TRUE, |
|
+ ISC_TRUE, (const char *) pin, slot); |
|
+ if ((result != ISC_R_SUCCESS) && |
|
+ (result != PK11_R_NORANDOMSERVICE) && |
|
+ (result != PK11_R_NODIGESTSERVICE) && |
|
+ (result != PK11_R_NOAESSERVICE)) { |
|
+ fprintf(stderr, "Error initializing PKCS#11: %s\n", |
|
+ isc_result_totext(result)); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ if (pin != NULL) |
|
+ memset(pin, 0, strlen((char *)pin)); |
|
+ |
|
+ hSession = pctx.session; |
|
+ |
|
+ if (ontoken) { |
|
+ pubTemplate[2].pValue = &truevalue; |
|
+ privTemplate[2].pValue = &truevalue; |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { |
|
+ perror("clock_gettime(start)"); |
|
+ goto exit_keys; |
|
+ } |
|
+ |
|
+ for (i = 0; i < count; i++) { |
|
+ rv = pkcs_C_GenerateKeyPair(hSession, &mech, |
|
+ pubTemplate, 7, |
|
+ privTemplate, 5, |
|
+ &pubKey[i], &privKey[i]); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_GenerateKeyPair[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ if (i == 0) |
|
+ goto exit_keys; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { |
|
+ perror("clock_gettime(end)"); |
|
+ goto exit_keys; |
|
+ } |
|
+ |
|
+ endtime.tv_sec -= starttime.tv_sec; |
|
+ endtime.tv_nsec -= starttime.tv_nsec; |
|
+ while (endtime.tv_nsec < 0) { |
|
+ endtime.tv_sec -= 1; |
|
+ endtime.tv_nsec += 1000000000; |
|
+ } |
|
+ printf("%u generated RSA in %ld.%09lds\n", i, |
|
+ endtime.tv_sec, endtime.tv_nsec); |
|
+ if (i > 0) |
|
+ printf("%g generated RSA/s\n", |
|
+ 1024 * i / ((double) endtime.tv_sec + |
|
+ (double) endtime.tv_nsec / 1000000000.)); |
|
+ |
|
+ exit_keys: |
|
+ for (i = 0; i < count; i++) { |
|
+ /* Destroy keys */ |
|
+ if (pubKey[i] == CK_INVALID_HANDLE) |
|
+ goto destroy_priv; |
|
+ rv = pkcs_C_DestroyObject(hSession, pubKey[i]); |
|
+ if ((rv != CKR_OK) && !errflg) { |
|
+ fprintf(stderr, |
|
+ "C_DestroyObject[pub%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ errflg = 1; |
|
+ } |
|
+ destroy_priv: |
|
+ if (privKey[i] == CK_INVALID_HANDLE) |
|
+ continue; |
|
+ rv = pkcs_C_DestroyObject(hSession, privKey[i]); |
|
+ if ((rv != CKR_OK) && !errflg) { |
|
+ fprintf(stderr, |
|
+ "C_DestroyObject[priv%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ errflg = 1; |
|
+ } |
|
+ } |
|
+ |
|
+ free(pubKey); |
|
+ free(privKey); |
|
+ |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/pkcs11/benchmarks/login.c b/bin/tests/pkcs11/benchmarks/login.c |
|
new file mode 100644 |
|
index 0000000..fe597fa |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/benchmarks/login.c |
|
@@ -0,0 +1,249 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* login [-m module] [-s $slot] [-p pin] [-n count] */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <time.h> |
|
+#include <unistd.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/internal.h> |
|
+ |
|
+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
+#define getpassphrase(x) getpass(x) |
|
+#endif |
|
+ |
|
+#ifndef HAVE_CLOCK_GETTIME |
|
+#ifndef CLOCK_REALTIME |
|
+#define CLOCK_REALTIME 0 |
|
+#endif |
|
+ |
|
+int |
|
+clock_gettime(int32_t id, struct timespec *tp) |
|
+{ |
|
+ struct timeval tv; |
|
+ int result; |
|
+ |
|
+ result = gettimeofday(&tv, NULL); |
|
+ if (result) |
|
+ return (result); |
|
+ tp->tv_sec = tv.tv_sec; |
|
+ tp->tv_nsec = (long) tv.tv_usec * 1000; |
|
+ return (result); |
|
+} |
|
+#endif |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE *hSession; |
|
+ CK_UTF8CHAR *pin = NULL; |
|
+ char *lib_name = NULL; |
|
+ int error = 0; |
|
+ int c, errflg = 0; |
|
+ unsigned int count = 1000; |
|
+ unsigned int i, j; |
|
+ struct timespec starttime; |
|
+ struct timespec endtime; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:p:n:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'p': |
|
+ pin = (CK_UTF8CHAR *)isc_commandline_argument; |
|
+ break; |
|
+ case 'n': |
|
+ count = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\tlogin [-m module] [-s slot] [-p pin] [-n count]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ /* allocate sessions */ |
|
+ hSession = (CK_SESSION_HANDLE *) |
|
+ malloc(count * sizeof(CK_SESSION_HANDLE)); |
|
+ if (hSession == NULL) { |
|
+ perror("malloc"); |
|
+ exit(1); |
|
+ } |
|
+ for (i = 0; i < count; i++) |
|
+ hSession[i] = CK_INVALID_HANDLE; |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ if (pin == NULL) |
|
+ pin = (CK_UTF8CHAR *)getpassphrase("Enter Pin: "); |
|
+ |
|
+ rv = pkcs_C_Initialize(NULL_PTR); |
|
+ if (rv != CKR_OK) { |
|
+ if (rv == 0xfe) |
|
+ fprintf(stderr, |
|
+ "Can't load or link module \"%s\"\n", |
|
+ pk11_get_lib_name()); |
|
+ else |
|
+ fprintf(stderr, "C_Initialize: Error = 0x%.8lX\n", rv); |
|
+ free(hSession); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { |
|
+ perror("clock_gettime(start)"); |
|
+ goto exit_program; |
|
+ } |
|
+ |
|
+ /* loop */ |
|
+ for (i = 0; i < count; i++) { |
|
+ /* Open sessions */ |
|
+ rv = pkcs_C_OpenSession(slot, CKF_SERIAL_SESSION, |
|
+ NULL_PTR, NULL_PTR, &hSession[i]); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_OpenSession[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ if (i == 0) |
|
+ goto exit_program; |
|
+ break; |
|
+ } |
|
+ |
|
+ /* Logon */ |
|
+ rv = pkcs_C_Login(hSession[i], CKU_USER, |
|
+ pin, strlen((char *)pin)); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_Login[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ if (i == 0) |
|
+ goto exit_program; |
|
+ break; |
|
+ } |
|
+ |
|
+ /* Logoff */ |
|
+ rv = pkcs_C_Logout(hSession[i]); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_Logout[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ if (i == 0) |
|
+ goto exit_program; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { |
|
+ perror("clock_gettime(end)"); |
|
+ goto exit_program; |
|
+ } |
|
+ |
|
+ endtime.tv_sec -= starttime.tv_sec; |
|
+ endtime.tv_nsec -= starttime.tv_nsec; |
|
+ while (endtime.tv_nsec < 0) { |
|
+ endtime.tv_sec -= 1; |
|
+ endtime.tv_nsec += 1000000000; |
|
+ } |
|
+ printf("%u logins in %ld.%09lds\n", i, |
|
+ endtime.tv_sec, endtime.tv_nsec); |
|
+ if (i > 0) |
|
+ printf("%g logins/s\n", |
|
+ i / ((double) endtime.tv_sec + |
|
+ (double) endtime.tv_nsec / 1000000000.)); |
|
+ |
|
+ for (j = 0; j < i; j++) { |
|
+ if (hSession[j] == CK_INVALID_HANDLE) |
|
+ continue; |
|
+ /* Close sessions */ |
|
+ rv = pkcs_C_CloseSession(hSession[j]); |
|
+ if ((rv != CKR_OK) && !errflg) { |
|
+ fprintf(stderr, |
|
+ "C_CloseSession[%u]: Error = 0x%.8lX\n", |
|
+ j, rv); |
|
+ errflg = 1; |
|
+ } |
|
+ } |
|
+ |
|
+ exit_program: |
|
+ free(hSession); |
|
+ |
|
+ rv = pkcs_C_Finalize(NULL_PTR); |
|
+ if (rv != CKR_OK) |
|
+ fprintf(stderr, "C_Finalize: Error = 0x%.8lX\n", rv); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/pkcs11/benchmarks/privrsa.c b/bin/tests/pkcs11/benchmarks/privrsa.c |
|
new file mode 100644 |
|
index 0000000..c50d8d2 |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/benchmarks/privrsa.c |
|
@@ -0,0 +1,360 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* privrsa [-m module] [-s $slot] [-p pin] [-t] [-n count] */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <time.h> |
|
+#include <unistd.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
+#define getpassphrase(x) getpass(x) |
|
+#endif |
|
+ |
|
+#ifndef HAVE_CLOCK_GETTIME |
|
+#ifndef CLOCK_REALTIME |
|
+#define CLOCK_REALTIME 0 |
|
+#endif |
|
+ |
|
+int |
|
+clock_gettime(int32_t id, struct timespec *tp) |
|
+{ |
|
+ struct timeval tv; |
|
+ int result; |
|
+ |
|
+ result = gettimeofday(&tv, NULL); |
|
+ if (result) |
|
+ return (result); |
|
+ tp->tv_sec = tv.tv_sec; |
|
+ tp->tv_nsec = (long) tv.tv_usec * 1000; |
|
+ return (result); |
|
+} |
|
+#endif |
|
+ |
|
+CK_BYTE modulus[] = { |
|
+ 0x00, 0xb7, 0x9c, 0x1f, 0x05, 0xa3, 0xc2, 0x99, |
|
+ 0x44, 0x82, 0x20, 0x78, 0x43, 0x7f, 0x5f, 0x3b, |
|
+ 0x10, 0xd7, 0x9e, 0x61, 0x42, 0xd2, 0x7a, 0x90, |
|
+ 0x50, 0x8a, 0x99, 0x33, 0xe7, 0xca, 0xc8, 0x5f, |
|
+ 0x16, 0x1c, 0x56, 0xf8, 0xc1, 0x06, 0x2f, 0x96, |
|
+ 0xe7, 0x54, 0xf2, 0x85, 0x89, 0x41, 0x36, 0xf5, |
|
+ 0x4c, 0xa4, 0x0d, 0x62, 0xd3, 0x42, 0x51, 0x6b, |
|
+ 0x9f, 0xdc, 0x36, 0xcb, 0xad, 0x56, 0xf4, 0xbd, |
|
+ 0x2a, 0x60, 0x33, 0xb1, 0x7a, 0x99, 0xad, 0x08, |
|
+ 0x9f, 0x95, 0xe8, 0xe5, 0x14, 0xd9, 0x68, 0x79, |
|
+ 0xca, 0x4e, 0x72, 0xeb, 0xfb, 0x2c, 0xf1, 0x45, |
|
+ 0xd3, 0x33, 0x65, 0xe7, 0xc5, 0x11, 0xdd, 0xe7, |
|
+ 0x09, 0x83, 0x13, 0xd5, 0x17, 0x1b, 0xf4, 0xbd, |
|
+ 0x49, 0xdd, 0x8a, 0x3c, 0x3c, 0xf7, 0xa1, 0x5d, |
|
+ 0x7b, 0xb4, 0xd3, 0x80, 0x25, 0xf4, 0x05, 0x8f, |
|
+ 0xbc, 0x2c, 0x2a, 0x47, 0xff, 0xd1, 0xc8, 0x34, |
|
+ 0xbf |
|
+}; |
|
+CK_BYTE pubexp[] = { 0x01, 0x00, 0x01 }; |
|
+CK_BYTE privexp[] = { |
|
+ 0x00, 0xae, 0x02, 0xf1, 0x47, 0xa8, 0x07, 0x02, |
|
+ 0xb8, 0xf1, 0xd6, 0x92, 0x03, 0xee, 0x50, 0x33, |
|
+ 0xab, 0x67, 0x9e, 0x3b, 0xb1, 0x57, 0xc7, 0x3e, |
|
+ 0xc4, 0x86, 0x46, 0x61, 0xf1, 0xf8, 0xb6, 0x63, |
|
+ 0x9f, 0x91, 0xe6, 0x3f, 0x44, 0xb8, 0x77, 0x1b, |
|
+ 0xbe, 0x4c, 0x3c, 0xb8, 0x9f, 0xf7, 0x45, 0x7d, |
|
+ 0xbf, 0x4f, 0xef, 0x3b, 0xcc, 0xda, 0x1a, 0x4e, |
|
+ 0x34, 0xa8, 0x40, 0xea, 0x51, 0x72, 0x8a, 0xea, |
|
+ 0x47, 0x06, 0x04, 0xd0, 0x62, 0x31, 0xa0, 0x6c, |
|
+ 0x09, 0x60, 0xf9, 0xc7, 0x95, 0x88, 0x4a, 0xd7, |
|
+ 0x19, 0xce, 0x89, 0x08, 0x87, 0x14, 0xef, 0xcc, |
|
+ 0x0a, 0xef, 0x72, 0xb9, 0x21, 0xf5, 0xf0, 0xcd, |
|
+ 0x6d, 0xe5, 0xfa, 0x15, 0x7f, 0xae, 0x33, 0x9f, |
|
+ 0x26, 0xac, 0x2e, 0x52, 0x02, 0x07, 0xfb, 0x1d, |
|
+ 0x4b, 0xec, 0x9a, 0x6b, 0x3b, 0x26, 0x1f, 0x52, |
|
+ 0xfc, 0x47, 0xf8, 0x66, 0x33, 0xfa, 0x50, 0x6c, |
|
+ 0x41 |
|
+}; |
|
+CK_BYTE prime1[] = { |
|
+ 0x00, 0xe8, 0x98, 0xeb, 0xa1, 0xf0, 0xce, 0xde, |
|
+ 0xc2, 0x74, 0x01, 0x18, 0x2b, 0xd3, 0x8f, 0x58, |
|
+ 0xcd, 0xe9, 0x8e, 0x97, 0xbe, 0xfe, 0xe8, 0x6f, |
|
+ 0xd6, 0x0c, 0x0a, 0x47, 0xf8, 0x56, 0x84, 0x36, |
|
+ 0x15, 0xe6, 0x75, 0x1c, 0x69, 0x48, 0x8b, 0xf5, |
|
+ 0x0f, 0x84, 0xd2, 0x60, 0x8b, 0xa2, 0x2a, 0xa1, |
|
+ 0xeb, 0xed, 0xbe, 0x2d, 0xe9, 0x41, 0x0b, 0xed, |
|
+ 0x17, 0x7c, 0xd3, 0xa6, 0x35, 0x6e, 0xa6, 0xd8, |
|
+ 0x21 |
|
+}; |
|
+CK_BYTE prime2[] = { |
|
+ 0x00, 0xca, 0x15, 0x6a, 0x43, 0x5e, 0x83, 0xc9, |
|
+ 0x09, 0xeb, 0x14, 0x1e, 0x46, 0x46, 0x97, 0xfa, |
|
+ 0xfa, 0x3c, 0x61, 0x7e, 0xc1, 0xf8, 0x8c, 0x5e, |
|
+ 0xcb, 0xbf, 0xe4, 0xb9, 0x78, 0x7f, 0x4f, 0xab, |
|
+ 0x82, 0x15, 0x53, 0xaa, 0x04, 0xee, 0x11, 0x21, |
|
+ 0x2e, 0x23, 0x08, 0xa0, 0x14, 0x6d, 0x3a, 0x88, |
|
+ 0xe6, 0xf8, 0xbe, 0x61, 0x38, 0x99, 0xca, 0x36, |
|
+ 0x0d, 0x3e, 0x42, 0x0f, 0x63, 0x4d, 0x73, 0xf0, |
|
+ 0xdf |
|
+}; |
|
+CK_BYTE exp_1[] = { |
|
+ 0x66, 0x2d, 0xb7, 0x65, 0xbe, 0x99, 0xc2, 0x35, |
|
+ 0xfe, 0x2b, 0xf4, 0xe8, 0x5b, 0xd9, 0xdf, 0x13, |
|
+ 0x26, 0x04, 0xe4, 0x18, 0x9d, 0x76, 0x92, 0x9a, |
|
+ 0x9f, 0x53, 0x6c, 0xe6, 0x65, 0x6b, 0x53, 0x2f, |
|
+ 0x2f, 0xbc, 0x46, 0xac, 0xe1, 0x97, 0xca, 0x21, |
|
+ 0xf5, 0x21, 0x4e, 0x14, 0x49, 0x3b, 0x1d, 0x42, |
|
+ 0xbd, 0x80, 0x0c, 0x3f, 0x29, 0xba, 0x09, 0x7f, |
|
+ 0x85, 0xf0, 0x9c, 0x55, 0x60, 0xb4, 0x9e, 0xc1 |
|
+}; |
|
+CK_BYTE exp_2[] = { |
|
+ 0x00, 0x87, 0x22, 0x74, 0xf1, 0xe2, 0x15, 0x3c, |
|
+ 0x6d, 0xde, 0x7e, 0x90, 0x94, 0x2c, 0x06, 0xdb, |
|
+ 0xb5, 0x54, 0x85, 0x59, 0xcf, 0x7a, 0x56, 0xdb, |
|
+ 0xd9, 0x62, 0x54, 0x20, 0x56, 0xdc, 0xc3, 0xb9, |
|
+ 0x0b, 0xff, 0x18, 0xf8, 0x7b, 0xdd, 0x7b, 0x24, |
|
+ 0xf6, 0x06, 0x45, 0x71, 0x4e, 0xd7, 0x90, 0x2a, |
|
+ 0x16, 0x52, 0x46, 0x75, 0x1a, 0xf5, 0x74, 0x8c, |
|
+ 0x5a, 0xa4, 0xc4, 0x66, 0x27, 0xe0, 0x96, 0x64, |
|
+ 0x7f |
|
+}; |
|
+CK_BYTE coeff[] = { |
|
+ 0x00, 0xd0, 0x1f, 0xb3, 0x47, 0x40, 0x93, 0x8b, |
|
+ 0x99, 0xd7, 0xb5, 0xc6, 0x09, 0x82, 0x65, 0x94, |
|
+ 0x9d, 0x56, 0x0a, 0x05, 0x55, 0x7d, 0x93, 0x04, |
|
+ 0xa4, 0x26, 0xee, 0x42, 0x86, 0xa3, 0xf1, 0xd5, |
|
+ 0x7a, 0x42, 0x84, 0x3c, 0x21, 0x96, 0x9a, 0xd9, |
|
+ 0x36, 0xd4, 0x62, 0x01, 0xb0, 0x8b, 0x77, 0xe5, |
|
+ 0xcc, 0x1b, 0xd2, 0x12, 0xd2, 0x9c, 0x89, 0x67, |
|
+ 0x0c, 0x00, 0x09, 0x56, 0x8c, 0x33, 0x57, 0xf9, |
|
+ 0x8c |
|
+}; |
|
+ |
|
+char label[16]; |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_HANDLE *hKey; |
|
+ CK_OBJECT_CLASS kClass = CKO_PRIVATE_KEY; |
|
+ CK_KEY_TYPE kType = CKK_RSA; |
|
+ CK_ATTRIBUTE kTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &kClass, (CK_ULONG) sizeof(kClass) }, |
|
+ { CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_LABEL, (CK_BYTE_PTR) label, (CK_ULONG) sizeof(label) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_MODULUS, modulus, (CK_ULONG) sizeof(modulus) }, |
|
+ { CKA_PUBLIC_EXPONENT, pubexp, (CK_ULONG) sizeof(pubexp) }, |
|
+ { CKA_PRIVATE_EXPONENT, privexp, (CK_ULONG) sizeof(privexp) }, |
|
+ { CKA_PRIME_1, prime1, (CK_ULONG) sizeof(prime1) }, |
|
+ { CKA_PRIME_2, prime2, (CK_ULONG) sizeof(prime2) }, |
|
+ { CKA_EXPONENT_1, exp_1, (CK_ULONG) sizeof(exp_1) }, |
|
+ { CKA_EXPONENT_2, exp_2, (CK_ULONG) sizeof(exp_2) }, |
|
+ { CKA_COEFFICIENT, coeff, (CK_ULONG) sizeof(coeff) } |
|
+ }; |
|
+ pk11_context_t pctx; |
|
+ pk11_optype_t op_type = OP_RSA; |
|
+ char *lib_name = NULL; |
|
+ char *pin = NULL; |
|
+ int error = 0; |
|
+ int c, errflg = 0; |
|
+ int ontoken = 0; |
|
+ unsigned int count = 1000; |
|
+ unsigned int i; |
|
+ struct timespec starttime; |
|
+ struct timespec endtime; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tn:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ op_type = OP_ANY; |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'p': |
|
+ pin = isc_commandline_argument; |
|
+ break; |
|
+ case 't': |
|
+ ontoken = 1; |
|
+ break; |
|
+ case 'n': |
|
+ count = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\tprivrsa [-m module] [-s slot] [-p pin] " |
|
+ "[-t] [-n count]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ pk11_result_register(); |
|
+ |
|
+ /* Allocate hanles */ |
|
+ hKey = (CK_SESSION_HANDLE *) |
|
+ malloc(count * sizeof(CK_SESSION_HANDLE)); |
|
+ if (hKey == NULL) { |
|
+ perror("malloc"); |
|
+ exit(1); |
|
+ } |
|
+ for (i = 0; i < count; i++) |
|
+ hKey[i] = CK_INVALID_HANDLE; |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ if (pin == NULL) |
|
+ pin = getpassphrase("Enter Pin: "); |
|
+ |
|
+ result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_TRUE, |
|
+ ISC_TRUE, (const char *) pin, slot); |
|
+ if ((result != ISC_R_SUCCESS) && |
|
+ (result != PK11_R_NORANDOMSERVICE) && |
|
+ (result != PK11_R_NODIGESTSERVICE) && |
|
+ (result != PK11_R_NOAESSERVICE)) { |
|
+ fprintf(stderr, "Error initializing PKCS#11: %s\n", |
|
+ isc_result_totext(result)); |
|
+ free(hKey); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ if (pin != NULL) |
|
+ memset(pin, 0, strlen((char *)pin)); |
|
+ |
|
+ hSession = pctx.session; |
|
+ |
|
+ if (ontoken) |
|
+ kTemplate[2].pValue = &truevalue; |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { |
|
+ perror("clock_gettime(start)"); |
|
+ goto exit_objects; |
|
+ } |
|
+ |
|
+ for (i = 0; i < count; i++) { |
|
+ (void) snprintf(label, sizeof(label), "obj%u", i); |
|
+ kTemplate[4].ulValueLen = strlen(label); |
|
+ rv = pkcs_C_CreateObject(hSession, kTemplate, 14, &hKey[i]); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_CreateObject[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ if (i == 0) |
|
+ goto exit_objects; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { |
|
+ perror("clock_gettime(end)"); |
|
+ goto exit_objects; |
|
+ } |
|
+ |
|
+ endtime.tv_sec -= starttime.tv_sec; |
|
+ endtime.tv_nsec -= starttime.tv_nsec; |
|
+ while (endtime.tv_nsec < 0) { |
|
+ endtime.tv_sec -= 1; |
|
+ endtime.tv_nsec += 1000000000; |
|
+ } |
|
+ printf("%u private RSA keys in %ld.%09lds\n", i, |
|
+ endtime.tv_sec, endtime.tv_nsec); |
|
+ if (i > 0) |
|
+ printf("%g private RSA keys/s\n", |
|
+ 1024 * i / ((double) endtime.tv_sec + |
|
+ (double) endtime.tv_nsec / 1000000000.)); |
|
+ |
|
+ exit_objects: |
|
+ for (i = 0; i < count; i++) { |
|
+ /* Destroy objects */ |
|
+ if (hKey[i] == CK_INVALID_HANDLE) |
|
+ continue; |
|
+ rv = pkcs_C_DestroyObject(hSession, hKey[i]); |
|
+ if ((rv != CKR_OK) && !errflg) { |
|
+ fprintf(stderr, |
|
+ "C_DestroyObject[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ errflg = 1; |
|
+ } |
|
+ } |
|
+ |
|
+ free(hKey); |
|
+ |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/pkcs11/benchmarks/pubrsa.c b/bin/tests/pkcs11/benchmarks/pubrsa.c |
|
new file mode 100644 |
|
index 0000000..b27a999 |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/benchmarks/pubrsa.c |
|
@@ -0,0 +1,281 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* pubrsa [-m module] [-s $slot] [-p pin] [-t] [-n count] */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <time.h> |
|
+#include <unistd.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
+#define getpassphrase(x) getpass(x) |
|
+#endif |
|
+ |
|
+#ifndef HAVE_CLOCK_GETTIME |
|
+#ifndef CLOCK_REALTIME |
|
+#define CLOCK_REALTIME 0 |
|
+#endif |
|
+ |
|
+int |
|
+clock_gettime(int32_t id, struct timespec *tp) |
|
+{ |
|
+ struct timeval tv; |
|
+ int result; |
|
+ |
|
+ result = gettimeofday(&tv, NULL); |
|
+ if (result) |
|
+ return (result); |
|
+ tp->tv_sec = tv.tv_sec; |
|
+ tp->tv_nsec = (long) tv.tv_usec * 1000; |
|
+ return (result); |
|
+} |
|
+#endif |
|
+ |
|
+CK_BYTE modulus[] = { |
|
+ 0x00, 0xb7, 0x9c, 0x1f, 0x05, 0xa3, 0xc2, 0x99, |
|
+ 0x44, 0x82, 0x20, 0x78, 0x43, 0x7f, 0x5f, 0x3b, |
|
+ 0x10, 0xd7, 0x9e, 0x61, 0x42, 0xd2, 0x7a, 0x90, |
|
+ 0x50, 0x8a, 0x99, 0x33, 0xe7, 0xca, 0xc8, 0x5f, |
|
+ 0x16, 0x1c, 0x56, 0xf8, 0xc1, 0x06, 0x2f, 0x96, |
|
+ 0xe7, 0x54, 0xf2, 0x85, 0x89, 0x41, 0x36, 0xf5, |
|
+ 0x4c, 0xa4, 0x0d, 0x62, 0xd3, 0x42, 0x51, 0x6b, |
|
+ 0x9f, 0xdc, 0x36, 0xcb, 0xad, 0x56, 0xf4, 0xbd, |
|
+ 0x2a, 0x60, 0x33, 0xb1, 0x7a, 0x99, 0xad, 0x08, |
|
+ 0x9f, 0x95, 0xe8, 0xe5, 0x14, 0xd9, 0x68, 0x79, |
|
+ 0xca, 0x4e, 0x72, 0xeb, 0xfb, 0x2c, 0xf1, 0x45, |
|
+ 0xd3, 0x33, 0x65, 0xe7, 0xc5, 0x11, 0xdd, 0xe7, |
|
+ 0x09, 0x83, 0x13, 0xd5, 0x17, 0x1b, 0xf4, 0xbd, |
|
+ 0x49, 0xdd, 0x8a, 0x3c, 0x3c, 0xf7, 0xa1, 0x5d, |
|
+ 0x7b, 0xb4, 0xd3, 0x80, 0x25, 0xf4, 0x05, 0x8f, |
|
+ 0xbc, 0x2c, 0x2a, 0x47, 0xff, 0xd1, 0xc8, 0x34, |
|
+ 0xbf |
|
+}; |
|
+CK_BYTE exponent[] = { 0x01, 0x00, 0x01 }; |
|
+ |
|
+char label[16]; |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_HANDLE *hKey; |
|
+ CK_OBJECT_CLASS kClass = CKO_PUBLIC_KEY; |
|
+ CK_KEY_TYPE kType = CKK_RSA; |
|
+ CK_ATTRIBUTE kTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &kClass, (CK_ULONG) sizeof(kClass) }, |
|
+ { CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_LABEL, (CK_BYTE_PTR) label, (CK_ULONG) sizeof(label) }, |
|
+ { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_MODULUS, modulus, (CK_ULONG) sizeof(modulus) }, |
|
+ { CKA_PUBLIC_EXPONENT, exponent, (CK_ULONG) sizeof(exponent) } |
|
+ }; |
|
+ pk11_context_t pctx; |
|
+ pk11_optype_t op_type = OP_RSA; |
|
+ char *lib_name = NULL; |
|
+ char *pin = NULL; |
|
+ int error = 0; |
|
+ int c, errflg = 0; |
|
+ int ontoken = 0; |
|
+ unsigned int count = 1000; |
|
+ unsigned int i; |
|
+ struct timespec starttime; |
|
+ struct timespec endtime; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tn:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ op_type = OP_ANY; |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'p': |
|
+ pin = isc_commandline_argument; |
|
+ break; |
|
+ case 't': |
|
+ ontoken = 1; |
|
+ break; |
|
+ case 'n': |
|
+ count = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\tpubrsa [-m module] [-s slot] [-p pin] " |
|
+ "[-t] [-n count]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ pk11_result_register(); |
|
+ |
|
+ /* Allocate hanles */ |
|
+ hKey = (CK_SESSION_HANDLE *) |
|
+ malloc(count * sizeof(CK_SESSION_HANDLE)); |
|
+ if (hKey == NULL) { |
|
+ perror("malloc"); |
|
+ exit(1); |
|
+ } |
|
+ for (i = 0; i < count; i++) |
|
+ hKey[i] = CK_INVALID_HANDLE; |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ if (pin == NULL) |
|
+ pin = getpassphrase("Enter Pin: "); |
|
+ |
|
+ result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_TRUE, |
|
+ ISC_TRUE, (const char *) pin, slot); |
|
+ if ((result != ISC_R_SUCCESS) && |
|
+ (result != PK11_R_NORANDOMSERVICE) && |
|
+ (result != PK11_R_NODIGESTSERVICE) && |
|
+ (result != PK11_R_NOAESSERVICE)) { |
|
+ fprintf(stderr, "Error initializing PKCS#11: %s\n", |
|
+ isc_result_totext(result)); |
|
+ free(hKey); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ if (pin != NULL) |
|
+ memset(pin, 0, strlen((char *)pin)); |
|
+ |
|
+ hSession = pctx.session; |
|
+ |
|
+ if (ontoken) |
|
+ kTemplate[2].pValue = &truevalue; |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { |
|
+ perror("clock_gettime(start)"); |
|
+ goto exit_objects; |
|
+ } |
|
+ |
|
+ for (i = 0; i < count; i++) { |
|
+ (void) snprintf(label, sizeof(label), "obj%u", i); |
|
+ kTemplate[4].ulValueLen = strlen(label); |
|
+ rv = pkcs_C_CreateObject(hSession, kTemplate, 8, &hKey[i]); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_CreateObject[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ if (i == 0) |
|
+ goto exit_objects; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { |
|
+ perror("clock_gettime(end)"); |
|
+ goto exit_objects; |
|
+ } |
|
+ |
|
+ endtime.tv_sec -= starttime.tv_sec; |
|
+ endtime.tv_nsec -= starttime.tv_nsec; |
|
+ while (endtime.tv_nsec < 0) { |
|
+ endtime.tv_sec -= 1; |
|
+ endtime.tv_nsec += 1000000000; |
|
+ } |
|
+ printf("%u public RSA keys in %ld.%09lds\n", i, |
|
+ endtime.tv_sec, endtime.tv_nsec); |
|
+ if (i > 0) |
|
+ printf("%g public RSA keys/s\n", |
|
+ 1024 * i / ((double) endtime.tv_sec + |
|
+ (double) endtime.tv_nsec / 1000000000.)); |
|
+ |
|
+ exit_objects: |
|
+ for (i = 0; i < count; i++) { |
|
+ /* Destroy objects */ |
|
+ if (hKey[i] == CK_INVALID_HANDLE) |
|
+ continue; |
|
+ rv = pkcs_C_DestroyObject(hSession, hKey[i]); |
|
+ if ((rv != CKR_OK) && !errflg) { |
|
+ fprintf(stderr, |
|
+ "C_DestroyObject[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ errflg = 1; |
|
+ } |
|
+ } |
|
+ |
|
+ free(hKey); |
|
+ |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/pkcs11/benchmarks/random.c b/bin/tests/pkcs11/benchmarks/random.c |
|
new file mode 100644 |
|
index 0000000..10d6db0 |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/benchmarks/random.c |
|
@@ -0,0 +1,192 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* random [-m module] [-s $slot] [-n count] */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <time.h> |
|
+#include <unistd.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+#ifndef HAVE_CLOCK_GETTIME |
|
+#ifndef CLOCK_REALTIME |
|
+#define CLOCK_REALTIME 0 |
|
+#endif |
|
+ |
|
+int |
|
+clock_gettime(int32_t id, struct timespec *tp) |
|
+{ |
|
+ struct timeval tv; |
|
+ int result; |
|
+ |
|
+ result = gettimeofday(&tv, NULL); |
|
+ if (result) |
|
+ return (result); |
|
+ tp->tv_sec = tv.tv_sec; |
|
+ tp->tv_nsec = (long) tv.tv_usec * 1000; |
|
+ return (result); |
|
+} |
|
+#endif |
|
+ |
|
+CK_BYTE buf[1024]; |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; |
|
+ CK_ULONG len = sizeof(buf); |
|
+ pk11_context_t pctx; |
|
+ pk11_optype_t op_type = OP_RAND; |
|
+ char *lib_name = NULL; |
|
+ int error = 0; |
|
+ int c, errflg = 0; |
|
+ unsigned int count = 1000; |
|
+ unsigned int i; |
|
+ struct timespec starttime; |
|
+ struct timespec endtime; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:n:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ op_type = OP_ANY; |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'n': |
|
+ count = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\trandom [-m module] [-s slot] [-n count]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ pk11_result_register(); |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, slot); |
|
+ if ((result != ISC_R_SUCCESS) && |
|
+ (result != PK11_R_NODIGESTSERVICE) && |
|
+ (result != PK11_R_NOAESSERVICE)) { |
|
+ fprintf(stderr, "Error initializing PKCS#11: %s\n", |
|
+ isc_result_totext(result)); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ hSession = pctx.session; |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { |
|
+ perror("clock_gettime(start)"); |
|
+ goto exit_session; |
|
+ } |
|
+ |
|
+ for (i = 0; i < count; i++) { |
|
+ /* Get random bytes */ |
|
+ rv = pkcs_C_GenerateRandom(hSession, buf, len); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_GenerateRandom[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { |
|
+ perror("clock_gettime(end)"); |
|
+ goto exit_session; |
|
+ } |
|
+ |
|
+ endtime.tv_sec -= starttime.tv_sec; |
|
+ endtime.tv_nsec -= starttime.tv_nsec; |
|
+ while (endtime.tv_nsec < 0) { |
|
+ endtime.tv_sec -= 1; |
|
+ endtime.tv_nsec += 1000000000; |
|
+ } |
|
+ printf("%uK random bytes in %ld.%09lds\n", i, |
|
+ endtime.tv_sec, endtime.tv_nsec); |
|
+ if (i > 0) |
|
+ printf("%g random bytes/s\n", |
|
+ 1024 * i / ((double) endtime.tv_sec + |
|
+ (double) endtime.tv_nsec / 1000000000.)); |
|
+ |
|
+ exit_session: |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/pkcs11/benchmarks/session.c b/bin/tests/pkcs11/benchmarks/session.c |
|
new file mode 100644 |
|
index 0000000..74bd63a |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/benchmarks/session.c |
|
@@ -0,0 +1,213 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* session [-m module] [-s $slot] [-n count] */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <time.h> |
|
+#include <unistd.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/internal.h> |
|
+ |
|
+#ifndef HAVE_CLOCK_GETTIME |
|
+#ifndef CLOCK_REALTIME |
|
+#define CLOCK_REALTIME 0 |
|
+#endif |
|
+ |
|
+int |
|
+clock_gettime(int32_t id, struct timespec *tp) |
|
+{ |
|
+ struct timeval tv; |
|
+ int result; |
|
+ |
|
+ result = gettimeofday(&tv, NULL); |
|
+ if (result) |
|
+ return (result); |
|
+ tp->tv_sec = tv.tv_sec; |
|
+ tp->tv_nsec = (long) tv.tv_usec * 1000; |
|
+ return (result); |
|
+} |
|
+#endif |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE *hSession; |
|
+ char *lib_name = NULL; |
|
+ int error = 0; |
|
+ int c, errflg = 0; |
|
+ unsigned int count = 1000; |
|
+ unsigned int i; |
|
+ struct timespec starttime; |
|
+ struct timespec endtime; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:n:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'n': |
|
+ count = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\tsession [-m module] [-s slot] [-n count]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ /* Allocate sessions */ |
|
+ hSession = (CK_SESSION_HANDLE *) |
|
+ malloc(count * sizeof(CK_SESSION_HANDLE)); |
|
+ if (hSession == NULL) { |
|
+ perror("malloc"); |
|
+ exit(1); |
|
+ } |
|
+ for (i = 0; i < count; i++) |
|
+ hSession[i] = CK_INVALID_HANDLE; |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ rv = pkcs_C_Initialize(NULL_PTR); |
|
+ if (rv != CKR_OK) { |
|
+ if (rv == 0xfe) |
|
+ fprintf(stderr, |
|
+ "Can't load or link module \"%s\"\n", |
|
+ pk11_get_lib_name()); |
|
+ else |
|
+ fprintf(stderr, "C_Initialize: Error = 0x%.8lX\n", rv); |
|
+ free(hSession); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { |
|
+ perror("clock_gettime(start)"); |
|
+ goto exit_program; |
|
+ } |
|
+ |
|
+ /* loop */ |
|
+ for (i = 0; i < count; i++) { |
|
+ /* Open sessions */ |
|
+ rv = pkcs_C_OpenSession(slot, CKF_SERIAL_SESSION, |
|
+ NULL_PTR, NULL_PTR, &hSession[i]); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_OpenSession[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ if (i == 0) |
|
+ goto exit_program; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { |
|
+ perror("clock_gettime(end)"); |
|
+ goto exit_program; |
|
+ } |
|
+ |
|
+ endtime.tv_sec -= starttime.tv_sec; |
|
+ endtime.tv_nsec -= starttime.tv_nsec; |
|
+ while (endtime.tv_nsec < 0) { |
|
+ endtime.tv_sec -= 1; |
|
+ endtime.tv_nsec += 1000000000; |
|
+ } |
|
+ printf("%u sessions in %ld.%09lds\n", i, |
|
+ endtime.tv_sec, endtime.tv_nsec); |
|
+ if (i > 0) |
|
+ printf("%g sessions/s\n", |
|
+ i / ((double) endtime.tv_sec + |
|
+ (double) endtime.tv_nsec / 1000000000.)); |
|
+ |
|
+ for (i = 0; i < count; i++) { |
|
+ /* Close sessions */ |
|
+ if (hSession[i] == CK_INVALID_HANDLE) |
|
+ continue; |
|
+ rv = pkcs_C_CloseSession(hSession[i]); |
|
+ if ((rv != CKR_OK) && !errflg) { |
|
+ fprintf(stderr, |
|
+ "C_CloseSession[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ errflg = 1; |
|
+ } |
|
+ } |
|
+ |
|
+ exit_program: |
|
+ free(hSession); |
|
+ |
|
+ rv = pkcs_C_Finalize(NULL_PTR); |
|
+ if (rv != CKR_OK) |
|
+ fprintf(stderr, "C_Finalize: Error = 0x%.8lX\n", rv); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/pkcs11/benchmarks/sha1.c b/bin/tests/pkcs11/benchmarks/sha1.c |
|
new file mode 100644 |
|
index 0000000..756aadb |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/benchmarks/sha1.c |
|
@@ -0,0 +1,214 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* sha1 [-m module] [-s $slot] [-n count] */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <time.h> |
|
+#include <unistd.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+#ifndef HAVE_CLOCK_GETTIME |
|
+#ifndef CLOCK_REALTIME |
|
+#define CLOCK_REALTIME 0 |
|
+#endif |
|
+ |
|
+int |
|
+clock_gettime(int32_t id, struct timespec *tp) |
|
+{ |
|
+ struct timeval tv; |
|
+ int result; |
|
+ |
|
+ result = gettimeofday(&tv, NULL); |
|
+ if (result) |
|
+ return (result); |
|
+ tp->tv_sec = tv.tv_sec; |
|
+ tp->tv_nsec = (long) tv.tv_usec * 1000; |
|
+ return (result); |
|
+} |
|
+#endif |
|
+ |
|
+CK_BYTE buf[1024]; |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; |
|
+ CK_MECHANISM mech = { CKM_SHA_1, NULL, 0 }; |
|
+ CK_ULONG len = sizeof(buf); |
|
+ pk11_context_t pctx; |
|
+ pk11_optype_t op_type = OP_DIGEST; |
|
+ char *lib_name = NULL; |
|
+ int error = 0; |
|
+ int c, errflg = 0; |
|
+ unsigned int count = 1000; |
|
+ unsigned int i; |
|
+ struct timespec starttime; |
|
+ struct timespec endtime; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:n:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ op_type = OP_ANY; |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'n': |
|
+ count = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\tssha1 [-m module] [-s slot] [-n count]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ pk11_result_register(); |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, slot); |
|
+ if ((result != ISC_R_SUCCESS) && |
|
+ (result != PK11_R_NORANDOMSERVICE) && |
|
+ (result != PK11_R_NOAESSERVICE)) { |
|
+ fprintf(stderr, "Error initializing PKCS#11: %s\n", |
|
+ isc_result_totext(result)); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ hSession = pctx.session; |
|
+ |
|
+ /* Randomize the buffer */ |
|
+ rv = pkcs_C_GenerateRandom(hSession, buf, len); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, "C_GenerateRandom: Error = 0x%.8lX\n", rv); |
|
+ goto exit_session; |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { |
|
+ perror("clock_gettime(start)"); |
|
+ goto exit_session; |
|
+ } |
|
+ |
|
+ /* Initialize Digest */ |
|
+ rv = pkcs_C_DigestInit(hSession, &mech); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, "C_DigestInit: Error = 0x%.8lX\n", rv); |
|
+ goto exit_session; |
|
+ } |
|
+ |
|
+ |
|
+ for (i = 0; i < count; i++) { |
|
+ /* Digest buffer */ |
|
+ rv = pkcs_C_DigestUpdate(hSession, buf, len); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_DigestUpdate[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ /* Finalize Digest (unconditionally) */ |
|
+ len = 20U; |
|
+ rv = pkcs_C_DigestFinal(hSession, buf, &len); |
|
+ if ((rv != CKR_OK) && !error) |
|
+ fprintf(stderr, "C_DigestFinal: Error = 0x%.8lX\n", rv); |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { |
|
+ perror("clock_gettime(end)"); |
|
+ goto exit_session; |
|
+ } |
|
+ |
|
+ endtime.tv_sec -= starttime.tv_sec; |
|
+ endtime.tv_nsec -= starttime.tv_nsec; |
|
+ while (endtime.tv_nsec < 0) { |
|
+ endtime.tv_sec -= 1; |
|
+ endtime.tv_nsec += 1000000000; |
|
+ } |
|
+ printf("%uK digested bytes in %ld.%09lds\n", i, |
|
+ endtime.tv_sec, endtime.tv_nsec); |
|
+ if (i > 0) |
|
+ printf("%g digested bytes/s\n", |
|
+ 1024 * i / ((double) endtime.tv_sec + |
|
+ (double) endtime.tv_nsec / 1000000000.)); |
|
+ |
|
+ exit_session: |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/pkcs11/benchmarks/sign.c b/bin/tests/pkcs11/benchmarks/sign.c |
|
new file mode 100644 |
|
index 0000000..8425ba9 |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/benchmarks/sign.c |
|
@@ -0,0 +1,368 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* signrsa [-m module] [-s $slot] [-p pin] [-t] [-n count] */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <time.h> |
|
+#include <unistd.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
+#define getpassphrase(x) getpass(x) |
|
+#endif |
|
+ |
|
+#ifndef HAVE_CLOCK_GETTIME |
|
+#ifndef CLOCK_REALTIME |
|
+#define CLOCK_REALTIME 0 |
|
+#endif |
|
+ |
|
+int |
|
+clock_gettime(int32_t id, struct timespec *tp) |
|
+{ |
|
+ struct timeval tv; |
|
+ int result; |
|
+ |
|
+ result = gettimeofday(&tv, NULL); |
|
+ if (result) |
|
+ return (result); |
|
+ tp->tv_sec = tv.tv_sec; |
|
+ tp->tv_nsec = (long) tv.tv_usec * 1000; |
|
+ return (result); |
|
+} |
|
+#endif |
|
+ |
|
+CK_BYTE modulus[] = { |
|
+ 0x00, 0xb7, 0x9c, 0x1f, 0x05, 0xa3, 0xc2, 0x99, |
|
+ 0x44, 0x82, 0x20, 0x78, 0x43, 0x7f, 0x5f, 0x3b, |
|
+ 0x10, 0xd7, 0x9e, 0x61, 0x42, 0xd2, 0x7a, 0x90, |
|
+ 0x50, 0x8a, 0x99, 0x33, 0xe7, 0xca, 0xc8, 0x5f, |
|
+ 0x16, 0x1c, 0x56, 0xf8, 0xc1, 0x06, 0x2f, 0x96, |
|
+ 0xe7, 0x54, 0xf2, 0x85, 0x89, 0x41, 0x36, 0xf5, |
|
+ 0x4c, 0xa4, 0x0d, 0x62, 0xd3, 0x42, 0x51, 0x6b, |
|
+ 0x9f, 0xdc, 0x36, 0xcb, 0xad, 0x56, 0xf4, 0xbd, |
|
+ 0x2a, 0x60, 0x33, 0xb1, 0x7a, 0x99, 0xad, 0x08, |
|
+ 0x9f, 0x95, 0xe8, 0xe5, 0x14, 0xd9, 0x68, 0x79, |
|
+ 0xca, 0x4e, 0x72, 0xeb, 0xfb, 0x2c, 0xf1, 0x45, |
|
+ 0xd3, 0x33, 0x65, 0xe7, 0xc5, 0x11, 0xdd, 0xe7, |
|
+ 0x09, 0x83, 0x13, 0xd5, 0x17, 0x1b, 0xf4, 0xbd, |
|
+ 0x49, 0xdd, 0x8a, 0x3c, 0x3c, 0xf7, 0xa1, 0x5d, |
|
+ 0x7b, 0xb4, 0xd3, 0x80, 0x25, 0xf4, 0x05, 0x8f, |
|
+ 0xbc, 0x2c, 0x2a, 0x47, 0xff, 0xd1, 0xc8, 0x34, |
|
+ 0xbf |
|
+}; |
|
+CK_BYTE pubexp[] = { 0x01, 0x00, 0x01 }; |
|
+CK_BYTE privexp[] = { |
|
+ 0x00, 0xae, 0x02, 0xf1, 0x47, 0xa8, 0x07, 0x02, |
|
+ 0xb8, 0xf1, 0xd6, 0x92, 0x03, 0xee, 0x50, 0x33, |
|
+ 0xab, 0x67, 0x9e, 0x3b, 0xb1, 0x57, 0xc7, 0x3e, |
|
+ 0xc4, 0x86, 0x46, 0x61, 0xf1, 0xf8, 0xb6, 0x63, |
|
+ 0x9f, 0x91, 0xe6, 0x3f, 0x44, 0xb8, 0x77, 0x1b, |
|
+ 0xbe, 0x4c, 0x3c, 0xb8, 0x9f, 0xf7, 0x45, 0x7d, |
|
+ 0xbf, 0x4f, 0xef, 0x3b, 0xcc, 0xda, 0x1a, 0x4e, |
|
+ 0x34, 0xa8, 0x40, 0xea, 0x51, 0x72, 0x8a, 0xea, |
|
+ 0x47, 0x06, 0x04, 0xd0, 0x62, 0x31, 0xa0, 0x6c, |
|
+ 0x09, 0x60, 0xf9, 0xc7, 0x95, 0x88, 0x4a, 0xd7, |
|
+ 0x19, 0xce, 0x89, 0x08, 0x87, 0x14, 0xef, 0xcc, |
|
+ 0x0a, 0xef, 0x72, 0xb9, 0x21, 0xf5, 0xf0, 0xcd, |
|
+ 0x6d, 0xe5, 0xfa, 0x15, 0x7f, 0xae, 0x33, 0x9f, |
|
+ 0x26, 0xac, 0x2e, 0x52, 0x02, 0x07, 0xfb, 0x1d, |
|
+ 0x4b, 0xec, 0x9a, 0x6b, 0x3b, 0x26, 0x1f, 0x52, |
|
+ 0xfc, 0x47, 0xf8, 0x66, 0x33, 0xfa, 0x50, 0x6c, |
|
+ 0x41 |
|
+}; |
|
+CK_BYTE prime1[] = { |
|
+ 0x00, 0xe8, 0x98, 0xeb, 0xa1, 0xf0, 0xce, 0xde, |
|
+ 0xc2, 0x74, 0x01, 0x18, 0x2b, 0xd3, 0x8f, 0x58, |
|
+ 0xcd, 0xe9, 0x8e, 0x97, 0xbe, 0xfe, 0xe8, 0x6f, |
|
+ 0xd6, 0x0c, 0x0a, 0x47, 0xf8, 0x56, 0x84, 0x36, |
|
+ 0x15, 0xe6, 0x75, 0x1c, 0x69, 0x48, 0x8b, 0xf5, |
|
+ 0x0f, 0x84, 0xd2, 0x60, 0x8b, 0xa2, 0x2a, 0xa1, |
|
+ 0xeb, 0xed, 0xbe, 0x2d, 0xe9, 0x41, 0x0b, 0xed, |
|
+ 0x17, 0x7c, 0xd3, 0xa6, 0x35, 0x6e, 0xa6, 0xd8, |
|
+ 0x21 |
|
+}; |
|
+CK_BYTE prime2[] = { |
|
+ 0x00, 0xca, 0x15, 0x6a, 0x43, 0x5e, 0x83, 0xc9, |
|
+ 0x09, 0xeb, 0x14, 0x1e, 0x46, 0x46, 0x97, 0xfa, |
|
+ 0xfa, 0x3c, 0x61, 0x7e, 0xc1, 0xf8, 0x8c, 0x5e, |
|
+ 0xcb, 0xbf, 0xe4, 0xb9, 0x78, 0x7f, 0x4f, 0xab, |
|
+ 0x82, 0x15, 0x53, 0xaa, 0x04, 0xee, 0x11, 0x21, |
|
+ 0x2e, 0x23, 0x08, 0xa0, 0x14, 0x6d, 0x3a, 0x88, |
|
+ 0xe6, 0xf8, 0xbe, 0x61, 0x38, 0x99, 0xca, 0x36, |
|
+ 0x0d, 0x3e, 0x42, 0x0f, 0x63, 0x4d, 0x73, 0xf0, |
|
+ 0xdf |
|
+}; |
|
+CK_BYTE exp_1[] = { |
|
+ 0x66, 0x2d, 0xb7, 0x65, 0xbe, 0x99, 0xc2, 0x35, |
|
+ 0xfe, 0x2b, 0xf4, 0xe8, 0x5b, 0xd9, 0xdf, 0x13, |
|
+ 0x26, 0x04, 0xe4, 0x18, 0x9d, 0x76, 0x92, 0x9a, |
|
+ 0x9f, 0x53, 0x6c, 0xe6, 0x65, 0x6b, 0x53, 0x2f, |
|
+ 0x2f, 0xbc, 0x46, 0xac, 0xe1, 0x97, 0xca, 0x21, |
|
+ 0xf5, 0x21, 0x4e, 0x14, 0x49, 0x3b, 0x1d, 0x42, |
|
+ 0xbd, 0x80, 0x0c, 0x3f, 0x29, 0xba, 0x09, 0x7f, |
|
+ 0x85, 0xf0, 0x9c, 0x55, 0x60, 0xb4, 0x9e, 0xc1 |
|
+}; |
|
+CK_BYTE exp_2[] = { |
|
+ 0x00, 0x87, 0x22, 0x74, 0xf1, 0xe2, 0x15, 0x3c, |
|
+ 0x6d, 0xde, 0x7e, 0x90, 0x94, 0x2c, 0x06, 0xdb, |
|
+ 0xb5, 0x54, 0x85, 0x59, 0xcf, 0x7a, 0x56, 0xdb, |
|
+ 0xd9, 0x62, 0x54, 0x20, 0x56, 0xdc, 0xc3, 0xb9, |
|
+ 0x0b, 0xff, 0x18, 0xf8, 0x7b, 0xdd, 0x7b, 0x24, |
|
+ 0xf6, 0x06, 0x45, 0x71, 0x4e, 0xd7, 0x90, 0x2a, |
|
+ 0x16, 0x52, 0x46, 0x75, 0x1a, 0xf5, 0x74, 0x8c, |
|
+ 0x5a, 0xa4, 0xc4, 0x66, 0x27, 0xe0, 0x96, 0x64, |
|
+ 0x7f |
|
+}; |
|
+CK_BYTE coeff[] = { |
|
+ 0x00, 0xd0, 0x1f, 0xb3, 0x47, 0x40, 0x93, 0x8b, |
|
+ 0x99, 0xd7, 0xb5, 0xc6, 0x09, 0x82, 0x65, 0x94, |
|
+ 0x9d, 0x56, 0x0a, 0x05, 0x55, 0x7d, 0x93, 0x04, |
|
+ 0xa4, 0x26, 0xee, 0x42, 0x86, 0xa3, 0xf1, 0xd5, |
|
+ 0x7a, 0x42, 0x84, 0x3c, 0x21, 0x96, 0x9a, 0xd9, |
|
+ 0x36, 0xd4, 0x62, 0x01, 0xb0, 0x8b, 0x77, 0xe5, |
|
+ 0xcc, 0x1b, 0xd2, 0x12, 0xd2, 0x9c, 0x89, 0x67, |
|
+ 0x0c, 0x00, 0x09, 0x56, 0x8c, 0x33, 0x57, 0xf9, |
|
+ 0x8c |
|
+}; |
|
+ |
|
+CK_BYTE buf[1024]; |
|
+CK_BYTE sig[128]; |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; |
|
+ CK_ULONG len; |
|
+ CK_ULONG slen; |
|
+ CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS kClass = CKO_PRIVATE_KEY; |
|
+ CK_KEY_TYPE kType = CKK_RSA; |
|
+ CK_ATTRIBUTE kTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &kClass, (CK_ULONG) sizeof(kClass) }, |
|
+ { CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_MODULUS, modulus, (CK_ULONG) sizeof(modulus) }, |
|
+ { CKA_PUBLIC_EXPONENT, pubexp, (CK_ULONG) sizeof(pubexp) }, |
|
+ { CKA_PRIVATE_EXPONENT, privexp, (CK_ULONG) sizeof(privexp) }, |
|
+ { CKA_PRIME_1, prime1, (CK_ULONG) sizeof(prime1) }, |
|
+ { CKA_PRIME_2, prime2, (CK_ULONG) sizeof(prime2) }, |
|
+ { CKA_EXPONENT_1, exp_1, (CK_ULONG) sizeof(exp_1) }, |
|
+ { CKA_EXPONENT_2, exp_2, (CK_ULONG) sizeof(exp_2) }, |
|
+ { CKA_COEFFICIENT, coeff, (CK_ULONG) sizeof(coeff) } |
|
+ }; |
|
+ CK_MECHANISM mech = { CKM_SHA1_RSA_PKCS, NULL, 0 }; |
|
+ pk11_context_t pctx; |
|
+ pk11_optype_t op_type = OP_RSA; |
|
+ char *lib_name = NULL; |
|
+ char *pin = NULL; |
|
+ int error = 0; |
|
+ int c, errflg = 0; |
|
+ int ontoken = 0; |
|
+ unsigned int count = 1000; |
|
+ unsigned int i; |
|
+ struct timespec starttime; |
|
+ struct timespec endtime; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tn:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ op_type = OP_ANY; |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'p': |
|
+ pin = isc_commandline_argument; |
|
+ break; |
|
+ case 't': |
|
+ ontoken = 1; |
|
+ break; |
|
+ case 'n': |
|
+ count = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\tsign [-m module] [-s slot] [-p pin] " |
|
+ "[-t] [-n count]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ pk11_result_register(); |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ if (pin == NULL) |
|
+ pin = getpassphrase("Enter Pin: "); |
|
+ |
|
+ result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_TRUE, |
|
+ ISC_TRUE, (const char *) pin, slot); |
|
+ if ((result != ISC_R_SUCCESS) && |
|
+ (result != PK11_R_NORANDOMSERVICE) && |
|
+ (result != PK11_R_NODIGESTSERVICE) && |
|
+ (result != PK11_R_NOAESSERVICE)) { |
|
+ fprintf(stderr, "Error initializing PKCS#11: %s\n", |
|
+ isc_result_totext(result)); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ if (pin != NULL) |
|
+ memset(pin, 0, strlen((char *)pin)); |
|
+ |
|
+ hSession = pctx.session; |
|
+ |
|
+ /* Create the private RSA key */ |
|
+ if (ontoken) |
|
+ kTemplate[2].pValue = &truevalue; |
|
+ |
|
+ rv = pkcs_C_CreateObject(hSession, kTemplate, 13, &hKey); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, "C_CreateObject: Error = 0x%.8lX\n", rv); |
|
+ goto exit_key; |
|
+ } |
|
+ |
|
+ /* Randomize the buffer */ |
|
+ len = (CK_ULONG) sizeof(buf); |
|
+ rv = pkcs_C_GenerateRandom(hSession, buf, len); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, "C_GenerateRandom: Error = 0x%.8lX\n", rv); |
|
+ goto exit_key; |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { |
|
+ perror("clock_gettime(start)"); |
|
+ goto exit_key; |
|
+ } |
|
+ |
|
+ for (i = 0; i < count; i++) { |
|
+ /* Initialize Sign */ |
|
+ rv = pkcs_C_SignInit(hSession, &mech, hKey); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_SignInit[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ break; |
|
+ } |
|
+ |
|
+ /* Perform Sign */ |
|
+ slen = (CK_ULONG) sizeof(sig); |
|
+ rv = pkcs_C_Sign(hSession, buf, len, sig, &slen); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_Sign[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { |
|
+ perror("clock_gettime(end)"); |
|
+ goto exit_key; |
|
+ } |
|
+ |
|
+ endtime.tv_sec -= starttime.tv_sec; |
|
+ endtime.tv_nsec -= starttime.tv_nsec; |
|
+ while (endtime.tv_nsec < 0) { |
|
+ endtime.tv_sec -= 1; |
|
+ endtime.tv_nsec += 1000000000; |
|
+ } |
|
+ printf("%u RSA signs in %ld.%09lds\n", i, |
|
+ endtime.tv_sec, endtime.tv_nsec); |
|
+ if (i > 0) |
|
+ printf("%g RSA signs/s\n", |
|
+ 1024 * i / ((double) endtime.tv_sec + |
|
+ (double) endtime.tv_nsec / 1000000000.)); |
|
+ |
|
+ exit_key: |
|
+ if (hKey != CK_INVALID_HANDLE) { |
|
+ rv = pkcs_C_DestroyObject(hSession, hKey); |
|
+ if (rv != CKR_OK) |
|
+ fprintf(stderr, |
|
+ "C_DestroyObject: Error = 0x%.8lX\n", |
|
+ rv); |
|
+ } |
|
+ |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/pkcs11/benchmarks/verify.c b/bin/tests/pkcs11/benchmarks/verify.c |
|
new file mode 100644 |
|
index 0000000..0a8f2c2 |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/benchmarks/verify.c |
|
@@ -0,0 +1,292 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* verify [-m module] [-s $slot] [-p pin] [-t] [-n count] */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <time.h> |
|
+#include <unistd.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
+#define getpassphrase(x) getpass(x) |
|
+#endif |
|
+ |
|
+#ifndef HAVE_CLOCK_GETTIME |
|
+#ifndef CLOCK_REALTIME |
|
+#define CLOCK_REALTIME 0 |
|
+#endif |
|
+ |
|
+int |
|
+clock_gettime(int32_t id, struct timespec *tp) |
|
+{ |
|
+ struct timeval tv; |
|
+ int result; |
|
+ |
|
+ result = gettimeofday(&tv, NULL); |
|
+ if (result) |
|
+ return (result); |
|
+ tp->tv_sec = tv.tv_sec; |
|
+ tp->tv_nsec = (long) tv.tv_usec * 1000; |
|
+ return (result); |
|
+} |
|
+#endif |
|
+ |
|
+CK_BYTE modulus[] = { |
|
+ 0x00, 0xb7, 0x9c, 0x1f, 0x05, 0xa3, 0xc2, 0x99, |
|
+ 0x44, 0x82, 0x20, 0x78, 0x43, 0x7f, 0x5f, 0x3b, |
|
+ 0x10, 0xd7, 0x9e, 0x61, 0x42, 0xd2, 0x7a, 0x90, |
|
+ 0x50, 0x8a, 0x99, 0x33, 0xe7, 0xca, 0xc8, 0x5f, |
|
+ 0x16, 0x1c, 0x56, 0xf8, 0xc1, 0x06, 0x2f, 0x96, |
|
+ 0xe7, 0x54, 0xf2, 0x85, 0x89, 0x41, 0x36, 0xf5, |
|
+ 0x4c, 0xa4, 0x0d, 0x62, 0xd3, 0x42, 0x51, 0x6b, |
|
+ 0x9f, 0xdc, 0x36, 0xcb, 0xad, 0x56, 0xf4, 0xbd, |
|
+ 0x2a, 0x60, 0x33, 0xb1, 0x7a, 0x99, 0xad, 0x08, |
|
+ 0x9f, 0x95, 0xe8, 0xe5, 0x14, 0xd9, 0x68, 0x79, |
|
+ 0xca, 0x4e, 0x72, 0xeb, 0xfb, 0x2c, 0xf1, 0x45, |
|
+ 0xd3, 0x33, 0x65, 0xe7, 0xc5, 0x11, 0xdd, 0xe7, |
|
+ 0x09, 0x83, 0x13, 0xd5, 0x17, 0x1b, 0xf4, 0xbd, |
|
+ 0x49, 0xdd, 0x8a, 0x3c, 0x3c, 0xf7, 0xa1, 0x5d, |
|
+ 0x7b, 0xb4, 0xd3, 0x80, 0x25, 0xf4, 0x05, 0x8f, |
|
+ 0xbc, 0x2c, 0x2a, 0x47, 0xff, 0xd1, 0xc8, 0x34, |
|
+ 0xbf |
|
+}; |
|
+CK_BYTE exponent[] = { 0x01, 0x00, 0x01 }; |
|
+ |
|
+CK_BYTE buf[1024]; |
|
+CK_BYTE sig[128]; |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; |
|
+ CK_ULONG len; |
|
+ CK_ULONG slen; |
|
+ CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS kClass = CKO_PUBLIC_KEY; |
|
+ CK_KEY_TYPE kType = CKK_RSA; |
|
+ CK_ATTRIBUTE kTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &kClass, (CK_ULONG) sizeof(kClass) }, |
|
+ { CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_MODULUS, modulus, (CK_ULONG) sizeof(modulus) }, |
|
+ { CKA_PUBLIC_EXPONENT, exponent, (CK_ULONG) sizeof(exponent) } |
|
+ }; |
|
+ CK_MECHANISM mech = { CKM_SHA1_RSA_PKCS, NULL, 0 }; |
|
+ pk11_context_t pctx; |
|
+ pk11_optype_t op_type = OP_RSA; |
|
+ char *lib_name = NULL; |
|
+ char *pin = NULL; |
|
+ int error = 0; |
|
+ int c, errflg = 0; |
|
+ int ontoken = 0; |
|
+ unsigned int count = 1000; |
|
+ unsigned int i; |
|
+ struct timespec starttime; |
|
+ struct timespec endtime; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tn:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ op_type = OP_ANY; |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'p': |
|
+ pin = isc_commandline_argument; |
|
+ break; |
|
+ case 't': |
|
+ ontoken = 1; |
|
+ break; |
|
+ case 'n': |
|
+ count = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\tverify [-m module] [-s slot] [-p pin] " |
|
+ "[-t] [-n count]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ pk11_result_register(); |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ if (pin == NULL) |
|
+ pin = getpassphrase("Enter Pin: "); |
|
+ |
|
+ result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_TRUE, |
|
+ ISC_TRUE, (const char *) pin, slot); |
|
+ if ((result != ISC_R_SUCCESS) && |
|
+ (result != PK11_R_NORANDOMSERVICE) && |
|
+ (result != PK11_R_NODIGESTSERVICE) && |
|
+ (result != PK11_R_NOAESSERVICE)) { |
|
+ fprintf(stderr, "Error initializing PKCS#11: %s\n", |
|
+ isc_result_totext(result)); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ if (pin != NULL) |
|
+ memset(pin, 0, strlen((char *)pin)); |
|
+ |
|
+ hSession = pctx.session; |
|
+ |
|
+ /* Create the private RSA key */ |
|
+ if (ontoken) |
|
+ kTemplate[2].pValue = &truevalue; |
|
+ |
|
+ rv = pkcs_C_CreateObject(hSession, kTemplate, 7, &hKey); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, "C_CreateObject: Error = 0x%.8lX\n", rv); |
|
+ error = 1; |
|
+ goto exit_key; |
|
+ } |
|
+ |
|
+ /* Randomize the buffer */ |
|
+ len = (CK_ULONG) sizeof(buf); |
|
+ rv = pkcs_C_GenerateRandom(hSession, buf, len); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, "C_GenerateRandom: Error = 0x%.8lX\n", rv); |
|
+ goto exit_key; |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) { |
|
+ perror("clock_gettime(start)"); |
|
+ goto exit_key; |
|
+ } |
|
+ |
|
+ for (i = 0; i < count; i++) { |
|
+ /* Initialize Verify */ |
|
+ rv = pkcs_C_VerifyInit(hSession, &mech, hKey); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_VerifyInit[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ break; |
|
+ } |
|
+ |
|
+ /* Perform Verify */ |
|
+ slen = (CK_ULONG) sizeof(sig); |
|
+ rv = pkcs_C_Verify(hSession, buf, len, sig, slen); |
|
+ if ((rv != CKR_OK) && (rv != CKR_SIGNATURE_INVALID)) { |
|
+ fprintf(stderr, |
|
+ "C_Verify[%u]: Error = 0x%.8lX\n", |
|
+ i, rv); |
|
+ error = 1; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) { |
|
+ perror("clock_gettime(end)"); |
|
+ goto exit_key; |
|
+ } |
|
+ |
|
+ endtime.tv_sec -= starttime.tv_sec; |
|
+ endtime.tv_nsec -= starttime.tv_nsec; |
|
+ while (endtime.tv_nsec < 0) { |
|
+ endtime.tv_sec -= 1; |
|
+ endtime.tv_nsec += 1000000000; |
|
+ } |
|
+ printf("%u RSA verify in %ld.%09lds\n", i, |
|
+ endtime.tv_sec, endtime.tv_nsec); |
|
+ if (i > 0) |
|
+ printf("%g RSA verify/s\n", |
|
+ 1024 * i / ((double) endtime.tv_sec + |
|
+ (double) endtime.tv_nsec / 1000000000.)); |
|
+ |
|
+ exit_key: |
|
+ if (hKey != CK_INVALID_HANDLE) { |
|
+ rv = pkcs_C_DestroyObject(hSession, hKey); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_DestroyObject: Error = 0x%.8lX\n", |
|
+ rv); |
|
+ errflg = 1; |
|
+ } |
|
+ } |
|
+ |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/pkcs11/pkcs11-hmacmd5.c b/bin/tests/pkcs11/pkcs11-hmacmd5.c |
|
new file mode 100644 |
|
index 0000000..00a1df1 |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/pkcs11-hmacmd5.c |
|
@@ -0,0 +1,332 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* |
|
+ * pkcs11-hmacmd5 |
|
+ * |
|
+ * Prints the MD5 HMAC of the standard input, using the PKCS#11 device. |
|
+ * |
|
+ * Usage: |
|
+ * pkcs11-hmacmd5 [-m module] [-s $slot] [-n] [-p $pin] |
|
+ * -m: PKCS#11 provider module. This must be the full |
|
+ * path to a shared library object implementing the |
|
+ * PKCS#11 API for a device. |
|
+ * -s: Slot |
|
+ * -p: PIN |
|
+ * -n: don't log in to the PKCS#11 device |
|
+ * -k: key name for the HMAC |
|
+ */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <fcntl.h> |
|
+#include <errno.h> |
|
+#include <string.h> |
|
+#include <sys/types.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
+#define getpassphrase(x) getpass(x) |
|
+#endif |
|
+ |
|
+/* Define static key template values */ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+#define BLOCKSIZE 32768 |
|
+ |
|
+char buffer[BLOCKSIZE + 72]; |
|
+char digest[16]; |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE hSession; |
|
+ CK_MECHANISM mech = { CKM_MD5_HMAC, NULL, 0 }; |
|
+ CK_ULONG len; |
|
+ CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_MD5_HMAC; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_VALUE, NULL, 0 } |
|
+ }; |
|
+ pk11_context_t pctx; |
|
+ pk11_optype_t op_type = OP_DIGEST; |
|
+ char *lib_name = NULL; |
|
+ char *pin = NULL; |
|
+ int error = 0; |
|
+ isc_boolean_t logon = ISC_TRUE; |
|
+ int c, errflg = 0; |
|
+ char *key = NULL; |
|
+ size_t sum = 0; |
|
+ unsigned int i; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:np:k:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ op_type = OP_ANY; |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'n': |
|
+ logon = ISC_FALSE; |
|
+ break; |
|
+ case 'p': |
|
+ pin = isc_commandline_argument; |
|
+ break; |
|
+ case 'k': |
|
+ key = isc_commandline_argument; |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg || (key == NULL)) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\tpkcs11-hmacmd5 [-m module] [-s slot] " |
|
+ "[-n|-p pin] -k key\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ /* Decode the key */ |
|
+ for (i = 0; i < BLOCKSIZE / 2; i++) { |
|
+ switch (c = *key++) { |
|
+ case 0: |
|
+ goto key_done; |
|
+ case '0': |
|
+ case '1': |
|
+ case '2': |
|
+ case '3': |
|
+ case '4': |
|
+ case '5': |
|
+ case '6': |
|
+ case '7': |
|
+ case '8': |
|
+ case '9': |
|
+ if ((i & 1) == 0) |
|
+ buffer[i >> 1] = (c - '0') << 4; |
|
+ else |
|
+ buffer[i >> 1] |= c - '0'; |
|
+ break; |
|
+ case 'A': |
|
+ case 'B': |
|
+ case 'C': |
|
+ case 'D': |
|
+ case 'E': |
|
+ case 'F': |
|
+ if ((i & 1) == 0) |
|
+ buffer[i >> 1] = (c - 'A' + 10) << 4; |
|
+ else |
|
+ buffer[i >> 1] |= c - 'A' + 10; |
|
+ break; |
|
+ case 'a': |
|
+ case 'b': |
|
+ case 'c': |
|
+ case 'd': |
|
+ case 'e': |
|
+ case 'f': |
|
+ if ((i & 1) == 0) |
|
+ buffer[i >> 1] = (c - 'a' + 10) << 4; |
|
+ else |
|
+ buffer[i >> 1] |= c - 'a' + 10; |
|
+ break; |
|
+ default: |
|
+ fprintf(stderr, "Not hexdigit '%c' in key\n", c); |
|
+ exit(1); |
|
+ } |
|
+ } |
|
+ key_done: |
|
+ if ((i & 1) != 0) { |
|
+ fprintf(stderr, "Even number of hexdigits in key\n"); |
|
+ exit(1); |
|
+ } |
|
+ len = i >> 1; |
|
+ keyTemplate[5].pValue = buffer; |
|
+ keyTemplate[5].ulValueLen = (CK_ULONG) len; |
|
+ |
|
+ pk11_result_register(); |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ if (logon && pin == NULL) |
|
+ pin = getpassphrase("Enter Pin: "); |
|
+ |
|
+ result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_FALSE, logon, |
|
+ (const char *) pin, slot); |
|
+ if ((result != ISC_R_SUCCESS) && |
|
+ (result != PK11_R_NORANDOMSERVICE) && |
|
+ (result != PK11_R_NOAESSERVICE)) { |
|
+ fprintf(stderr, "Error initializing PKCS#11: %s\n", |
|
+ isc_result_totext(result)); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ if (pin != NULL) |
|
+ memset(pin, 0, strlen((char *)pin)); |
|
+ |
|
+ hSession = pctx.session; |
|
+ |
|
+ rv = pkcs_C_CreateObject(hSession, keyTemplate, (CK_ULONG) 6, &hKey); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, "C_CreateObject: Error = 0x%.8lX\n", rv); |
|
+ error = 1; |
|
+ goto exit_session; |
|
+ } |
|
+ if (hKey == CK_INVALID_HANDLE) { |
|
+ fprintf(stderr, "C_CreateObject failed\n"); |
|
+ error = 1; |
|
+ goto exit_session; |
|
+ } |
|
+ |
|
+ rv = pkcs_C_SignInit(hSession, &mech, hKey); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, "C_SignInit: Error = 0x%.8lX\n", rv); |
|
+ error = 1; |
|
+ goto exit_sign; |
|
+ } |
|
+ |
|
+ for (;;) { |
|
+ size_t n; |
|
+ |
|
+ for (;;) { |
|
+ n = fread(buffer + sum, 1, BLOCKSIZE - sum, stdin); |
|
+ sum += n; |
|
+ if (sum == BLOCKSIZE) |
|
+ break; |
|
+ if (n == 0) { |
|
+ if (ferror(stdin)) { |
|
+ fprintf(stderr, "fread failed\n"); |
|
+ error = 1; |
|
+ goto exit_sign; |
|
+ } |
|
+ goto partial_block; |
|
+ } |
|
+ if (feof(stdin)) |
|
+ goto partial_block; |
|
+ } |
|
+ |
|
+ rv = pkcs_C_SignUpdate(hSession, (CK_BYTE_PTR) buffer, |
|
+ (CK_ULONG) BLOCKSIZE); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_SignUpdate: Error = 0x%.8lX\n", |
|
+ rv); |
|
+ error = 1; |
|
+ goto exit_sign; |
|
+ } |
|
+ } |
|
+ |
|
+partial_block: |
|
+ if (sum > 0) { |
|
+ rv = pkcs_C_SignUpdate(hSession, (CK_BYTE_PTR) buffer, |
|
+ (CK_ULONG) sum); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_SignUpdate: Error = 0x%.8lX\n", |
|
+ rv); |
|
+ error = 1; |
|
+ goto exit_sign; |
|
+ } |
|
+ } |
|
+ |
|
+ len = 16; |
|
+ rv = pkcs_C_SignFinal(hSession, (CK_BYTE_PTR) digest, &len); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, "C_SignFinal: Error = 0x%.8lX\n", rv); |
|
+ error = 1; |
|
+ goto exit_sign; |
|
+ } |
|
+ if (len != 16) { |
|
+ fprintf(stderr, "C_SignFinal: bad length = %lu\n", len); |
|
+ error = 1; |
|
+ } |
|
+ |
|
+ for (i = 0; i < 16; i++) |
|
+ printf("%02x", digest[i] & 0xff); |
|
+ printf("\n"); |
|
+ |
|
+ exit_sign: |
|
+ rv = pkcs_C_DestroyObject(hSession, hKey); |
|
+ if ((error == 0) && (rv != CKR_OK)) { |
|
+ fprintf(stderr, "C_DestroyObject: Error = 0x%.8lX\n", rv); |
|
+ error = 1; |
|
+ } |
|
+ |
|
+ exit_session: |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/pkcs11/pkcs11-md5sum.c b/bin/tests/pkcs11/pkcs11-md5sum.c |
|
new file mode 100644 |
|
index 0000000..fd50648 |
|
--- /dev/null |
|
+++ b/bin/tests/pkcs11/pkcs11-md5sum.c |
|
@@ -0,0 +1,235 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* |
|
+ * pkcs11-md5sum |
|
+ * |
|
+ * Prints the MD5 checksum of the standard input, using the PKCS#11 device. |
|
+ * |
|
+ * Usage: |
|
+ * pkcs11-md5sum [-m module] [-s $slot] [-n] [-p $pin] |
|
+ * -m: PKCS#11 provider module. This must be the full |
|
+ * path to a shared library object implementing the |
|
+ * PKCS#11 API for a device. |
|
+ * -s: Slot |
|
+ * -p: PIN |
|
+ * -n: don't log in to the PKCS#11 device |
|
+ */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <fcntl.h> |
|
+#include <errno.h> |
|
+#include <string.h> |
|
+#include <sys/types.h> |
|
+ |
|
+#include <isc/commandline.h> |
|
+#include <isc/result.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) |
|
+#define getpassphrase(x) getpass(x) |
|
+#endif |
|
+ |
|
+#define BLOCKSIZE 32768 |
|
+ |
|
+char buffer[BLOCKSIZE + 72]; |
|
+char digest[16]; |
|
+ |
|
+int |
|
+main(int argc, char *argv[]) { |
|
+ isc_result_t result; |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot = 0; |
|
+ CK_SESSION_HANDLE hSession; |
|
+ CK_MECHANISM mech = { CKM_MD5, NULL, 0 }; |
|
+ CK_ULONG len; |
|
+ pk11_context_t pctx; |
|
+ pk11_optype_t op_type = OP_DIGEST; |
|
+ char *lib_name = NULL; |
|
+ char *pin = NULL; |
|
+ int error = 0; |
|
+ isc_boolean_t logon = ISC_TRUE; |
|
+ int c, errflg = 0; |
|
+ size_t sum = 0; |
|
+ unsigned int i; |
|
+ |
|
+ while ((c = isc_commandline_parse(argc, argv, ":m:s:np:")) != -1) { |
|
+ switch (c) { |
|
+ case 'm': |
|
+ lib_name = isc_commandline_argument; |
|
+ break; |
|
+ case 's': |
|
+ op_type = OP_ANY; |
|
+ slot = atoi(isc_commandline_argument); |
|
+ break; |
|
+ case 'n': |
|
+ logon = ISC_FALSE; |
|
+ break; |
|
+ case 'p': |
|
+ pin = isc_commandline_argument; |
|
+ break; |
|
+ case ':': |
|
+ fprintf(stderr, |
|
+ "Option -%c requires an operand\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ break; |
|
+ case '?': |
|
+ default: |
|
+ fprintf(stderr, "Unrecognised option: -%c\n", |
|
+ isc_commandline_option); |
|
+ errflg++; |
|
+ } |
|
+ } |
|
+ |
|
+ if (errflg) { |
|
+ fprintf(stderr, "Usage:\n"); |
|
+ fprintf(stderr, |
|
+ "\tpkcs11-md5sum [-m module] [-s slot] [-n|-p pin]\n"); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ pk11_result_register(); |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ if (lib_name != NULL) |
|
+ pk11_set_lib_name(lib_name); |
|
+ |
|
+ if (logon && pin == NULL) |
|
+ pin = getpassphrase("Enter Pin: "); |
|
+ |
|
+ result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_FALSE, logon, |
|
+ (const char *) pin, slot); |
|
+ if ((result != ISC_R_SUCCESS) && |
|
+ (result != PK11_R_NORANDOMSERVICE) && |
|
+ (result != PK11_R_NOAESSERVICE)) { |
|
+ fprintf(stderr, "Error initializing PKCS#11: %s\n", |
|
+ isc_result_totext(result)); |
|
+ exit(1); |
|
+ } |
|
+ |
|
+ if (pin != NULL) |
|
+ memset(pin, 0, strlen((char *)pin)); |
|
+ |
|
+ hSession = pctx.session; |
|
+ |
|
+ rv = pkcs_C_DigestInit(hSession, &mech); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, "C_DigestInit: Error = 0x%.8lX\n", rv); |
|
+ error = 1; |
|
+ goto exit_session; |
|
+ } |
|
+ |
|
+ for (;;) { |
|
+ size_t n; |
|
+ |
|
+ for (;;) { |
|
+ n = fread(buffer + sum, 1, BLOCKSIZE - sum, stdin); |
|
+ sum += n; |
|
+ if (sum == BLOCKSIZE) |
|
+ break; |
|
+ if (n == 0) { |
|
+ if (ferror(stdin)) { |
|
+ fprintf(stderr, "fread failed\n"); |
|
+ error = 1; |
|
+ goto exit_session; |
|
+ } |
|
+ goto partial_block; |
|
+ } |
|
+ if (feof(stdin)) |
|
+ goto partial_block; |
|
+ } |
|
+ |
|
+ rv = pkcs_C_DigestUpdate(hSession, (CK_BYTE_PTR) buffer, |
|
+ (CK_ULONG) BLOCKSIZE); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_DigestUpdate: Error = 0x%.8lX\n", |
|
+ rv); |
|
+ error = 1; |
|
+ goto exit_session; |
|
+ } |
|
+ } |
|
+ |
|
+partial_block: |
|
+ if (sum > 0) { |
|
+ rv = pkcs_C_DigestUpdate(hSession, (CK_BYTE_PTR) buffer, |
|
+ (CK_ULONG) sum); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, |
|
+ "C_DigestUpdate: Error = 0x%.8lX\n", |
|
+ rv); |
|
+ error = 1; |
|
+ goto exit_session; |
|
+ } |
|
+ } |
|
+ |
|
+ len = 16; |
|
+ rv = pkcs_C_DigestFinal(hSession, (CK_BYTE_PTR) digest, &len); |
|
+ if (rv != CKR_OK) { |
|
+ fprintf(stderr, "C_DigestFinal: Error = 0x%.8lX\n", rv); |
|
+ error = 1; |
|
+ goto exit_session; |
|
+ } |
|
+ if (len != 16) { |
|
+ fprintf(stderr, "C_DigestFinal: bad length = %lu\n", len); |
|
+ error = 1; |
|
+ } |
|
+ |
|
+ for (i = 0; i < 16; i++) |
|
+ printf("%02x", digest[i] & 0xff); |
|
+ printf("\n"); |
|
+ |
|
+ exit_session: |
|
+ pk11_return_session(&pctx); |
|
+ (void) pk11_finalize(); |
|
+ |
|
+ exit(error); |
|
+} |
|
diff --git a/bin/tests/system/autosign/prereq.sh b/bin/tests/system/autosign/prereq.sh |
|
index 34cd4a1..53807a2 100644 |
|
--- a/bin/tests/system/autosign/prereq.sh |
|
+++ b/bin/tests/system/autosign/prereq.sh |
|
@@ -25,6 +25,7 @@ if $KEYGEN -q -a RSAMD5 -b 512 -n zone -r random.data foo > /dev/null 2>&1 |
|
then |
|
rm -f Kfoo* |
|
else |
|
- echo "I:This test requires that --with-openssl was used." >&2 |
|
+ echo "I:This test requires cryptography" >&2 |
|
+ echo "I:--with-openssl, or --with-pkcs11 and --enable-native-pkcs11" >&2 |
|
exit 1 |
|
fi |
|
diff --git a/bin/tests/system/cleanpkcs11.sh b/bin/tests/system/cleanpkcs11.sh |
|
index e1cbc6f..ba541ed 100644 |
|
--- a/bin/tests/system/cleanpkcs11.sh |
|
+++ b/bin/tests/system/cleanpkcs11.sh |
|
@@ -16,6 +16,10 @@ |
|
|
|
# $Id: cleanpkcs11.sh,v 1.3 2010/06/08 23:50:24 tbox Exp $ |
|
|
|
+SYSTEMTESTTOP=. |
|
+. $SYSTEMTESTTOP/conf.sh |
|
+ |
|
+ |
|
if [ ! -x ../../pkcs11/pkcs11-destroy ]; then exit 1; fi |
|
|
|
-../../pkcs11/pkcs11-destroy -s ${SLOT:-0} -p 1234 |
|
+$PK11DEL -w0 > /dev/null 2>&1 |
|
diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in |
|
index d6e902f..c40e8f1 100644 |
|
--- a/bin/tests/system/conf.sh.in |
|
+++ b/bin/tests/system/conf.sh.in |
|
@@ -47,9 +47,9 @@ CHECKDS=$TOP/bin/python/dnssec-checkds |
|
COVERAGE=$TOP/bin/python/dnssec-coverage |
|
CHECKZONE=$TOP/bin/check/named-checkzone |
|
CHECKCONF=$TOP/bin/check/named-checkconf |
|
-PK11GEN="$TOP/bin/pkcs11/pkcs11-keygen -s ${SLOT:-0} -p 1234" |
|
-PK11LIST="$TOP/bin/pkcs11/pkcs11-list -s ${SLOT:-0} -p 1234" |
|
-PK11DEL="$TOP/bin/pkcs11/pkcs11-destroy -s ${SLOT:-0} -p 1234" |
|
+PK11GEN="$TOP/bin/pkcs11/pkcs11-keygen -q -s ${SLOT:-0} -p ${HSMPIN:-1234}" |
|
+PK11LIST="$TOP/bin/pkcs11/pkcs11-list -s ${SLOT:-0} -p ${HSMPIN:-1234}" |
|
+PK11DEL="$TOP/bin/pkcs11/pkcs11-destroy -s ${SLOT:-0} -p ${HSMPIN:-1234} -w 0" |
|
JOURNALPRINT=$TOP/bin/tools/named-journalprint |
|
VERIFY=$TOP/bin/dnssec/dnssec-verify |
|
ARPANAME=$TOP/bin/tools/arpaname |
|
@@ -63,7 +63,7 @@ SUBDIRS="acl additional allow_query addzone autosign builtin |
|
database dlv dlvauto dlz dlzexternal dname dns64 dnssec ecdsa |
|
formerr forward glue gost ixfr inline limits logfileconfig |
|
lwresd masterfile masterformat metadata notify nsupdate pending |
|
- pkcs11 redirect resolver rndc rpz rrl rrsetorder rsabigexponent |
|
+ @PKCS11_TEST@ redirect resolver rndc rpz rrl rrsetorder rsabigexponent |
|
smartsign sortlist spf staticstub stub tkey tsig tsiggss unknown |
|
upforwd verify views wildcard xfer xferquota zero zonechecks" |
|
|
|
diff --git a/bin/tests/system/dnssec/prereq.sh b/bin/tests/system/dnssec/prereq.sh |
|
index cb7c0c7..113e372 100644 |
|
--- a/bin/tests/system/dnssec/prereq.sh |
|
+++ b/bin/tests/system/dnssec/prereq.sh |
|
@@ -23,6 +23,7 @@ if $KEYGEN -q -a RSAMD5 -b 512 -n zone -r random.data foo > /dev/null 2>&1 |
|
then |
|
rm -f Kfoo* |
|
else |
|
- echo "I:This test requires that --with-openssl was used." >&2 |
|
+ echo "I:This test requires cryptography" >&2 |
|
+ echo "I:--with-openssl, or --with-pkcs11 and --enable-native-pkcs11" >&2 |
|
exit 1 |
|
fi |
|
diff --git a/bin/tests/system/ecdsa/prereq.sh.in b/bin/tests/system/ecdsa/prereq.sh.in |
|
index 434b53c..4214a30 100644 |
|
--- a/bin/tests/system/ecdsa/prereq.sh.in |
|
+++ b/bin/tests/system/ecdsa/prereq.sh.in |
|
@@ -16,9 +16,16 @@ |
|
|
|
# $Id$ |
|
|
|
-OPENSSL_ECDSA="@OPENSSL_ECDSA@" |
|
-if test -z "$OPENSSL_ECDSA" |
|
-then |
|
- echo "I:This test requires a openssl version with ecdsa support." >&2 |
|
+SYSTEMTESTTOP=.. |
|
+. $SYSTEMTESTTOP/conf.sh |
|
+../../../tools/genrandom 400 random.data |
|
+ |
|
+fail=0 |
|
+$KEYGEN -q -a ecdsap256sha256 test > /dev/null 2>&1 || fail=1 |
|
+rm -f Ktest* random.data |
|
+ |
|
+if [ $fail != 0 ] |
|
+ then |
|
+ echo "I:This test requires support for ECDSA cryptography." >&2 |
|
exit 255 |
|
fi |
|
diff --git a/bin/tests/system/gost/prereq.sh.in b/bin/tests/system/gost/prereq.sh.in |
|
index 98ec507..0e4079e 100644 |
|
--- a/bin/tests/system/gost/prereq.sh.in |
|
+++ b/bin/tests/system/gost/prereq.sh.in |
|
@@ -16,9 +16,16 @@ |
|
|
|
# $Id: prereq.sh.in,v 1.4 2010/12/27 13:38:43 marka Exp $ |
|
|
|
-OPENSSL_GOST="@OPENSSL_GOST@" |
|
-if test -z "$OPENSSL_GOST" |
|
-then |
|
- echo "I:This test requires a openssl version with gost support." >&2 |
|
+SYSTEMTESTTOP=.. |
|
+. $SYSTEMTESTTOP/conf.sh |
|
+../../../tools/genrandom 400 random.data |
|
+ |
|
+fail=0 |
|
+$KEYGEN -q -a eccgost test > /dev/null 2>&1 || fail=1 |
|
+rm -f Ktest* random.data |
|
+ |
|
+if [ $fail != 0 ] |
|
+ then |
|
+ echo "I:This test requires support for GOST cryptography." >&2 |
|
exit 255 |
|
fi |
|
diff --git a/bin/tests/system/inline/clean.sh b/bin/tests/system/inline/clean.sh |
|
index dae21e5..b6dda0b 100644 |
|
--- a/bin/tests/system/inline/clean.sh |
|
+++ b/bin/tests/system/inline/clean.sh |
|
@@ -74,7 +74,7 @@ rm -f ns5/bits.bk.signed |
|
rm -f ns5/bits.bk.signed.jnl |
|
rm -f */*.jbk |
|
rm -f random.data |
|
-rm -f dig.out.ns*.test* |
|
+rm -f dig.out.ns* |
|
rm -f signing.out* |
|
rm -f freeze.test* |
|
rm -f thaw.test* |
|
diff --git a/bin/tests/system/metadata/prereq.sh b/bin/tests/system/metadata/prereq.sh |
|
index b7ce1ea..006bcf5 100644 |
|
--- a/bin/tests/system/metadata/prereq.sh |
|
+++ b/bin/tests/system/metadata/prereq.sh |
|
@@ -22,6 +22,7 @@ if $KEYGEN -q -r random.data foo > /dev/null 2>&1 |
|
then |
|
rm -f Kfoo* |
|
else |
|
- echo "I:This test requires that --with-openssl was used." >&2 |
|
+ echo "I:This test requires cryptography" >&2 |
|
+ echo "I:--with-openssl, or --with-pkcs11 and --enable-native-pkcs11" >&2 |
|
exit 1 |
|
fi |
|
diff --git a/bin/tests/system/pending/prereq.sh b/bin/tests/system/pending/prereq.sh |
|
index 0b6998e..f0848d7 100644 |
|
--- a/bin/tests/system/pending/prereq.sh |
|
+++ b/bin/tests/system/pending/prereq.sh |
|
@@ -16,12 +16,25 @@ |
|
|
|
# $Id: prereq.sh,v 1.3 2009/11/18 23:48:06 tbox Exp $ |
|
|
|
+SYSTEMTESTTOP=.. |
|
+. $SYSTEMTESTTOP/conf.sh |
|
../../../tools/genrandom 400 random.data |
|
|
|
-if $KEYGEN -q -a RSAMD5 -b 512 -n zone -r random.data foo > /dev/null 2>&1 |
|
-then |
|
- rm -f Kfoo* |
|
+rsafail=0 eccfail=0 |
|
+ |
|
+$KEYGEN -q -r random.data foo > /dev/null 2>&1 || rsafail=1 |
|
+rm -f Kfoo* |
|
+ |
|
+$KEYGEN -q -a ECDSAP256SHA256 -r random.data foo > /dev/null 2>&1 || eccfail=1 |
|
+rm -f Kfoo* |
|
+ |
|
+if [ $rsafail = 0 -a $eccfail = 0 ]; then |
|
+ echo both > supported |
|
+elif [ $rsafail = 1 -a $eccfail = 1 ]; then |
|
+ echo "I:This test requires PKCS#11 support for either RSA or ECDSA cryptography." >&2 |
|
+ exit 255 |
|
+elif [ $rsafail = 0 ]; then |
|
+ echo rsaonly > supported |
|
else |
|
- echo "I:This test requires that --with-openssl was used." >&2 |
|
- exit 1 |
|
+ echo ecconly > supported |
|
fi |
|
diff --git a/bin/tests/system/pkcs11/clean.sh b/bin/tests/system/pkcs11/clean.sh |
|
index d7a557b..29d0149 100644 |
|
--- a/bin/tests/system/pkcs11/clean.sh |
|
+++ b/bin/tests/system/pkcs11/clean.sh |
|
@@ -17,5 +17,6 @@ |
|
# $Id: clean.sh,v 1.3 2010/06/08 23:50:24 tbox Exp $ |
|
|
|
rm -f K* ns1/K* keyset-* dsset-* ns1/*.db ns1/*.signed ns1/*.jnl |
|
-rm -f dig.out random.data |
|
-rm -f ns1/key ns1/named.memstats |
|
+rm -f dig.out random.data pin |
|
+rm -f ns1/*.key ns1/named.memstats |
|
+rm -f supported |
|
diff --git a/bin/tests/system/pkcs11/ns1/named.conf b/bin/tests/system/pkcs11/ns1/named.conf |
|
index 09a850f..48b8adf 100644 |
|
--- a/bin/tests/system/pkcs11/ns1/named.conf |
|
+++ b/bin/tests/system/pkcs11/ns1/named.conf |
|
@@ -39,8 +39,14 @@ controls { |
|
inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; }; |
|
}; |
|
|
|
-zone "example." { |
|
+zone "rsa.example." { |
|
+ type master; |
|
+ file "rsa.example.db.signed"; |
|
+ allow-update { any; }; |
|
+}; |
|
+ |
|
+zone "ecc.example." { |
|
type master; |
|
- file "example.db.signed"; |
|
+ file "ecc.example.db.signed"; |
|
allow-update { any; }; |
|
}; |
|
diff --git a/bin/tests/system/pkcs11/setup.sh b/bin/tests/system/pkcs11/setup.sh |
|
index c044d75..a17a83d 100644 |
|
--- a/bin/tests/system/pkcs11/setup.sh |
|
+++ b/bin/tests/system/pkcs11/setup.sh |
|
@@ -21,21 +21,59 @@ SYSTEMTESTTOP=.. |
|
|
|
RANDFILE=random.data |
|
|
|
-zone=example |
|
infile=ns1/example.db.in |
|
-zonefile=ns1/example.db |
|
|
|
-$PK11GEN -b 1024 -l robie-zsk1 -i 01 |
|
-$PK11GEN -b 1024 -l robie-zsk2 -i 02 |
|
-$PK11GEN -b 2048 -l robie-ksk |
|
+/bin/echo -n ${HSMPIN:-1234}> pin |
|
+PWD=`pwd` |
|
|
|
-zsk1=`$KEYFRLAB -a RSASHA1 -l robie-zsk1 example` |
|
-zsk2=`$KEYFRLAB -a RSASHA1 -l robie-zsk2 example` |
|
-ksk=`$KEYFRLAB -a RSASHA1 -f ksk -l robie-ksk example` |
|
+supported=`cat supported` |
|
|
|
-cat $infile $zsk1.key $ksk.key > $zonefile |
|
-$SIGNER -a -P -g -r $RANDFILE -o $zone $zonefile > /dev/null 2> signer.err || cat signer.err |
|
-rm -f signer.err |
|
+zone=rsa.example |
|
+zonefile=ns1/rsa.example.db |
|
+if [ "$supported" != "ecconly" ]; then |
|
+ $PK11GEN -a RSA -b 1024 -l robie-rsa-zsk1 -i 01 |
|
+ $PK11GEN -a RSA -b 1024 -l robie-rsa-zsk2 -i 02 |
|
+ $PK11GEN -a RSA -b 2048 -l robie-rsa-ksk |
|
+ |
|
+ rsazsk1=`$KEYFRLAB -a RSASHA1 \ |
|
+ -l "object=robie-rsa-zsk1;pin-source=$PWD/pin" rsa.example` |
|
+ rsazsk2=`$KEYFRLAB -a RSASHA1 \ |
|
+ -l "object=robie-rsa-zsk2;pin-source=$PWD/pin" rsa.example` |
|
+ rsaksk=`$KEYFRLAB -a RSASHA1 -f ksk \ |
|
+ -l "object=robie-rsa-ksk;pin-source=$PWD/pin" rsa.example` |
|
+ |
|
+ cat $infile $rsazsk1.key $rsaksk.key > $zonefile |
|
+ $SIGNER -a -P -g -r $RANDFILE -o $zone $zonefile \ |
|
+ > /dev/null 2> signer.err || cat signer.err |
|
+ cp $rsazsk2.key ns1/rsa.key |
|
+ mv Krsa* ns1 |
|
+else |
|
+ # RSA not available and will not be tested; make a placeholder |
|
+ cp $infile ${zonefile}.signed |
|
+fi |
|
+ |
|
+zone=ecc.example |
|
+zonefile=ns1/ecc.example.db |
|
+if [ "$supported" != "rsaonly" ]; then |
|
+ $PK11GEN -a ECC -b 256 -l robie-ecc-zsk1 -i 03 |
|
+ $PK11GEN -a ECC -b 256 -l robie-ecc-zsk2 -i 04 |
|
+ $PK11GEN -a ECC -b 384 -l robie-ecc-ksk |
|
|
|
-cp $zsk2.key ns1/key |
|
-mv Kexample* ns1 |
|
+ ecczsk1=`$KEYFRLAB -a ECDSAP256SHA256 \ |
|
+ -l "object=robie-ecc-zsk1;pin-source=$PWD/pin" ecc.example` |
|
+ ecczsk2=`$KEYFRLAB -a ECDSAP256SHA256 \ |
|
+ -l "object=robie-ecc-zsk2;pin-source=$PWD/pin" ecc.example` |
|
+ eccksk=`$KEYFRLAB -a ECDSAP384SHA384 -f ksk \ |
|
+ -l "object=robie-ecc-ksk;pin-source=$PWD/pin" ecc.example` |
|
+ |
|
+ cat $infile $ecczsk1.key $eccksk.key > $zonefile |
|
+ $SIGNER -a -P -g -r $RANDFILE -o $zone $zonefile \ |
|
+ > /dev/null 2> signer.err || cat signer.err |
|
+ cp $ecczsk2.key ns1/ecc.key |
|
+ mv Kecc* ns1 |
|
+else |
|
+ # ECC not available and will not be tested; make a placeholder |
|
+ cp $infile ${zonefile}.signed |
|
+fi |
|
+ |
|
+rm -f signer.err |
|
diff --git a/bin/tests/system/pkcs11/tests.sh b/bin/tests/system/pkcs11/tests.sh |
|
index 4694afc..01f1523 100644 |
|
--- a/bin/tests/system/pkcs11/tests.sh |
|
+++ b/bin/tests/system/pkcs11/tests.sh |
|
@@ -26,47 +26,59 @@ DIGOPTS="+tcp +noadd +nosea +nostat +nocmd +dnssec -p 5300" |
|
status=0 |
|
ret=0 |
|
|
|
-zonefile=ns1/example.db |
|
+supported=`cat supported` |
|
+case $supported in |
|
+ rsaonly) algs="rsa" ;; |
|
+ ecconly) algs="ecc" ;; |
|
+ both) algs="rsa ecc" ;; |
|
+esac |
|
|
|
-echo "I:testing PKCS#11 key generation" |
|
+for alg in $algs; do |
|
+ zonefile=ns1/$alg.example.db |
|
+ echo "I:testing PKCS#11 key generation ($alg)" |
|
+ count=`$PK11LIST | grep robie-$alg-ksk | wc -l` |
|
+ if [ $count != 2 ]; then echo "I:failed"; status=1; fi |
|
|
|
-count=`$PK11LIST | grep robie-ksk | wc -l` |
|
-if [ $count != 2 ]; then echo "I:failed"; status=1; fi |
|
+ echo "I:testing offline signing with PKCS#11 keys ($alg)" |
|
|
|
-echo "I:testing offline signing with PKCS#11 keys" |
|
+ count=`grep RRSIG $zonefile.signed | wc -l` |
|
+ if [ $count != 12 ]; then echo "I:failed"; status=1; fi |
|
|
|
-count=`grep RRSIG $zonefile.signed | wc -l` |
|
-if [ $count != 12 ]; then echo "I:failed"; status=1; fi |
|
+ echo "I:testing inline signing with PKCS#11 keys ($alg)" |
|
|
|
-echo "I:testing inline signing with PKCS#11 keys" |
|
+ $NSUPDATE > /dev/null <<END || status=1 |
|
|
|
-$NSUPDATE > /dev/null <<END || status=1 |
|
server 10.53.0.1 5300 |
|
ttl 300 |
|
-zone example. |
|
-update add `grep -v ';' ns1/key` |
|
+zone $alg.example. |
|
+update add `grep -v ';' ns1/${alg}.key` |
|
send |
|
END |
|
|
|
-echo "I:waiting 20 seconds for key changes to take effect" |
|
-sleep 20 |
|
- |
|
-$DIG $DIGOPTS ns.example. @10.53.0.1 a > dig.out || ret=1 |
|
-if [ $ret != 0 ]; then echo "I:failed"; fi |
|
-status=`expr $status + $ret` |
|
-count=`grep RRSIG dig.out | wc -l` |
|
-if [ $count != 4 ]; then echo "I:failed"; status=1; fi |
|
- |
|
-echo "I:testing PKCS#11 key destroy" |
|
- |
|
-ret=0 |
|
-$PK11DEL -l robie-zsk1 || ret=1 |
|
-$PK11DEL -i 02 || ret=1 |
|
-if [ $ret != 0 ]; then echo "I:failed"; fi |
|
-status=`expr $status + $ret` |
|
-count=`$PK11LIST | grep robie-zsk | wc -l` |
|
-if [ $count != 0 ]; then echo "I:failed"; fi |
|
-status=`expr $status + $count` |
|
+ echo "I:waiting 20 seconds for key changes to take effect" |
|
+ sleep 20 |
|
+ |
|
+ $DIG $DIGOPTS ns.$alg.example. @10.53.0.1 a > dig.out || ret=1 |
|
+ if [ $ret != 0 ]; then echo "I:failed"; fi |
|
+ status=`expr $status + $ret` |
|
+ count=`grep RRSIG dig.out | wc -l` |
|
+ if [ $count != 4 ]; then echo "I:failed"; status=1; fi |
|
+ |
|
+ echo "I:testing PKCS#11 key destroy ($alg)" |
|
+ ret=0 |
|
+ $PK11DEL -l robie-$alg-ksk -w0 > /dev/null 2>&1 || ret=1 |
|
+ $PK11DEL -l robie-$alg-zsk1 -w0 > /dev/null 2>&1 || ret=1 |
|
+ case $alg in |
|
+ rsa) id=02 ;; |
|
+ ecc) id=04 ;; |
|
+ esac |
|
+ $PK11DEL -i $id -w0 > /dev/null 2>&1 || ret=1 |
|
+ if [ $ret != 0 ]; then echo "I:failed"; fi |
|
+ status=`expr $status + $ret` |
|
+ count=`$PK11LIST | grep robie-$alg | wc -l` |
|
+ if [ $count != 0 ]; then echo "I:failed"; fi |
|
+ status=`expr $status + $count` |
|
+done |
|
|
|
echo "I:exit status: $status" |
|
exit $status |
|
diff --git a/bin/tests/system/pkcs11ssl/clean.sh b/bin/tests/system/pkcs11ssl/clean.sh |
|
new file mode 100644 |
|
index 0000000..14ec725 |
|
--- /dev/null |
|
+++ b/bin/tests/system/pkcs11ssl/clean.sh |
|
@@ -0,0 +1,20 @@ |
|
+#!/bin/sh |
|
+# |
|
+# Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+# |
|
+# Permission to use, copy, modify, and/or distribute this software for any |
|
+# purpose with or without fee is hereby granted, provided that the above |
|
+# copyright notice and this permission notice appear in all copies. |
|
+# |
|
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+# PERFORMANCE OF THIS SOFTWARE. |
|
+ |
|
+rm -f K* ns1/K* keyset-* dsset-* ns1/*.db ns1/*.signed ns1/*.jnl |
|
+rm -f dig.out random.data pin |
|
+rm -f ns1/*.key ns1/named.memstats |
|
+rm -f supported |
|
diff --git a/bin/tests/system/pkcs11ssl/ns1/example.db.in b/bin/tests/system/pkcs11ssl/ns1/example.db.in |
|
new file mode 100644 |
|
index 0000000..7166fa8 |
|
--- /dev/null |
|
+++ b/bin/tests/system/pkcs11ssl/ns1/example.db.in |
|
@@ -0,0 +1,29 @@ |
|
+; Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") |
|
+; |
|
+; Permission to use, copy, modify, and/or distribute this software for any |
|
+; purpose with or without fee is hereby granted, provided that the above |
|
+; copyright notice and this permission notice appear in all copies. |
|
+; |
|
+; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+; PERFORMANCE OF THIS SOFTWARE. |
|
+ |
|
+; $Id: example.db.in,v 1.3 2010/06/08 23:50:24 tbox Exp $ |
|
+ |
|
+$TTL 300 ; 5 minutes |
|
+@ IN SOA ns root ( |
|
+ 2000082401 ; serial |
|
+ 1800 ; refresh (30 minutes) |
|
+ 1800 ; retry (30 minutes) |
|
+ 1814400 ; expire (3 weeks) |
|
+ 3600 ; minimum (1 hour) |
|
+ ) |
|
+ NS ns |
|
+ns A 10.53.0.1 |
|
+ |
|
+txt TXT "recursed" |
|
+ |
|
diff --git a/bin/tests/system/pkcs11ssl/ns1/named.conf b/bin/tests/system/pkcs11ssl/ns1/named.conf |
|
new file mode 100644 |
|
index 0000000..90b8117 |
|
--- /dev/null |
|
+++ b/bin/tests/system/pkcs11ssl/ns1/named.conf |
|
@@ -0,0 +1,52 @@ |
|
+/* |
|
+ * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* $Id: named.conf,v 1.3 2010/06/08 23:50:24 tbox Exp $ */ |
|
+ |
|
+controls { /* empty */ }; |
|
+ |
|
+options { |
|
+ query-source address 10.53.0.1; |
|
+ notify-source 10.53.0.1; |
|
+ transfer-source 10.53.0.1; |
|
+ port 5300; |
|
+ pid-file "named.pid"; |
|
+ listen-on { 10.53.0.1; }; |
|
+ listen-on-v6 { none; }; |
|
+ recursion no; |
|
+ notify no; |
|
+}; |
|
+ |
|
+key rndc_key { |
|
+ secret "1234abcd8765"; |
|
+ algorithm hmac-md5; |
|
+}; |
|
+ |
|
+controls { |
|
+ inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; }; |
|
+}; |
|
+ |
|
+zone "rsa.example." { |
|
+ type master; |
|
+ file "rsa.example.db.signed"; |
|
+ allow-update { any; }; |
|
+}; |
|
+ |
|
+zone "ecc.example." { |
|
+ type master; |
|
+ file "ecc.example.db.signed"; |
|
+ allow-update { any; }; |
|
+}; |
|
diff --git a/bin/tests/system/pkcs11ssl/prereq.sh b/bin/tests/system/pkcs11ssl/prereq.sh |
|
new file mode 100644 |
|
index 0000000..b5133f4 |
|
--- /dev/null |
|
+++ b/bin/tests/system/pkcs11ssl/prereq.sh |
|
@@ -0,0 +1,34 @@ |
|
+#!/bin/sh |
|
+# |
|
+# Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+# |
|
+# Permission to use, copy, modify, and/or distribute this software for any |
|
+# purpose with or without fee is hereby granted, provided that the above |
|
+# copyright notice and this permission notice appear in all copies. |
|
+# |
|
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+# PERFORMANCE OF THIS SOFTWARE. |
|
+ |
|
+# $Id: prereq.sh,v 1.3 2010/06/08 23:50:24 tbox Exp $ |
|
+ |
|
+SYSTEMTESTTOP=.. |
|
+. $SYSTEMTESTTOP/conf.sh |
|
+../../../tools/genrandom 400 random.data |
|
+ |
|
+echo rsaonly > supported |
|
+exit 0 |
|
+ |
|
+rsafail=0 eccfail=0 |
|
+ |
|
+$KEYGEN -q -r random.data foo > /dev/null 2>&1 || rsafail=1 |
|
+rm -f Kfoo* |
|
+ |
|
+if [ $rsafail = 1 ]; then |
|
+ echo "I:This test requires OpenSSL built with PKCS#11 support." >&2 |
|
+ exit 255 |
|
+fi |
|
diff --git a/bin/tests/system/pkcs11ssl/setup.sh b/bin/tests/system/pkcs11ssl/setup.sh |
|
new file mode 100644 |
|
index 0000000..c13b275 |
|
--- /dev/null |
|
+++ b/bin/tests/system/pkcs11ssl/setup.sh |
|
@@ -0,0 +1,46 @@ |
|
+#!/bin/sh |
|
+# |
|
+# Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") |
|
+# |
|
+# Permission to use, copy, modify, and/or distribute this software for any |
|
+# purpose with or without fee is hereby granted, provided that the above |
|
+# copyright notice and this permission notice appear in all copies. |
|
+# |
|
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+# PERFORMANCE OF THIS SOFTWARE. |
|
+ |
|
+SYSTEMTESTTOP=.. |
|
+. $SYSTEMTESTTOP/conf.sh |
|
+ |
|
+RANDFILE=random.data |
|
+infile=ns1/example.db.in |
|
+ |
|
+/bin/echo -n ${HSMPIN:-1234}> pin |
|
+PWD=`pwd` |
|
+ |
|
+zone=rsa.example |
|
+zonefile=ns1/rsa.example.db |
|
+ |
|
+$PK11GEN -a RSA -b 1024 -l robie-rsa-zsk1 -i 01 |
|
+$PK11GEN -a RSA -b 1024 -l robie-rsa-zsk2 -i 02 |
|
+$PK11GEN -a RSA -b 2048 -l robie-rsa-ksk |
|
+ |
|
+rsazsk1=`$KEYFRLAB -a RSASHA1 \ |
|
+ -l "robie-rsa-zsk1" rsa.example` |
|
+rsazsk2=`$KEYFRLAB -a RSASHA1 \ |
|
+ -l "robie-rsa-zsk2" rsa.example` |
|
+rsaksk=`$KEYFRLAB -a RSASHA1 -f ksk \ |
|
+ -l "robie-rsa-ksk" rsa.example` |
|
+ |
|
+cat $infile $rsazsk1.key $rsaksk.key > $zonefile |
|
+$SIGNER -a -P -g -r $RANDFILE -o $zone $zonefile \ |
|
+ > /dev/null 2> signer.err || cat signer.err |
|
+cp $rsazsk2.key ns1/rsa.key |
|
+mv Krsa* ns1 |
|
+ |
|
+rm -f signer.err |
|
diff --git a/bin/tests/system/pkcs11ssl/tests.sh b/bin/tests/system/pkcs11ssl/tests.sh |
|
new file mode 100644 |
|
index 0000000..7785d5a |
|
--- /dev/null |
|
+++ b/bin/tests/system/pkcs11ssl/tests.sh |
|
@@ -0,0 +1,71 @@ |
|
+#!/bin/sh |
|
+# |
|
+# Copyright (C) 2010, 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+# |
|
+# Permission to use, copy, modify, and/or distribute this software for any |
|
+# purpose with or without fee is hereby granted, provided that the above |
|
+# copyright notice and this permission notice appear in all copies. |
|
+# |
|
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+# PERFORMANCE OF THIS SOFTWARE. |
|
+ |
|
+# $Id: tests.sh,v 1.3 2010/06/08 23:50:24 tbox Exp $ |
|
+ |
|
+SYSTEMTESTTOP=.. |
|
+. $SYSTEMTESTTOP/conf.sh |
|
+ |
|
+RANDFILE=random.data |
|
+ |
|
+DIGOPTS="+tcp +noadd +nosea +nostat +nocmd +dnssec -p 5300" |
|
+ |
|
+status=0 |
|
+ret=0 |
|
+ |
|
+alg=rsa |
|
+zonefile=ns1/rsa.example.db |
|
+echo "I:testing PKCS#11 key generation (rsa)" |
|
+count=`$PK11LIST | grep robie-rsa-ksk | wc -l` |
|
+if [ $count != 2 ]; then echo "I:failed"; status=1; fi |
|
+ |
|
+echo "I:testing offline signing with PKCS#11 keys (rsa)" |
|
+ |
|
+count=`grep RRSIG $zonefile.signed | wc -l` |
|
+if [ $count != 12 ]; then echo "I:failed"; status=1; fi |
|
+ |
|
+echo "I:testing inline signing with PKCS#11 keys (rsa)" |
|
+ |
|
+$NSUPDATE > /dev/null <<END || status=1 |
|
+server 10.53.0.1 5300 |
|
+ttl 300 |
|
+zone rsa.example. |
|
+update add `grep -v ';' ns1/${alg}.key` |
|
+send |
|
+END |
|
+ |
|
+echo "I:waiting 20 seconds for key changes to take effect" |
|
+sleep 20 |
|
+ |
|
+$DIG $DIGOPTS ns.rsa.example. @10.53.0.1 a > dig.out || ret=1 |
|
+if [ $ret != 0 ]; then echo "I:failed"; fi |
|
+status=`expr $status + $ret` |
|
+count=`grep RRSIG dig.out | wc -l` |
|
+if [ $count != 4 ]; then echo "I:failed"; status=1; fi |
|
+ |
|
+echo "I:testing PKCS#11 key destroy (rsa)" |
|
+ret=0 |
|
+$PK11DEL -l robie-rsa-ksk -w0 > /dev/null 2>&1 || ret=1 |
|
+$PK11DEL -l robie-rsa-zsk1 -w0 > /dev/null 2>&1 || ret=1 |
|
+$PK11DEL -i $id -w0 > /dev/null 2>&1 || ret=1 |
|
+if [ $ret != 0 ]; then echo "I:failed"; fi |
|
+status=`expr $status + $ret` |
|
+count=`$PK11LIST | grep robie-rsa | wc -l` |
|
+if [ $count != 0 ]; then echo "I:failed"; fi |
|
+status=`expr $status + $count` |
|
+ |
|
+echo "I:exit status: $status" |
|
+exit $status |
|
diff --git a/bin/tests/system/pkcs11ssl/usepkcs11 b/bin/tests/system/pkcs11ssl/usepkcs11 |
|
new file mode 100644 |
|
index 0000000..ef46412 |
|
--- /dev/null |
|
+++ b/bin/tests/system/pkcs11ssl/usepkcs11 |
|
@@ -0,0 +1 @@ |
|
+This test relies on PKCS#11! |
|
diff --git a/bin/tests/system/rsabigexponent/Makefile.in b/bin/tests/system/rsabigexponent/Makefile.in |
|
index d32eb15..ce8958b 100644 |
|
--- a/bin/tests/system/rsabigexponent/Makefile.in |
|
+++ b/bin/tests/system/rsabigexponent/Makefile.in |
|
@@ -24,7 +24,7 @@ top_srcdir = @top_srcdir@ |
|
|
|
CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} @DST_OPENSSL_INC@ |
|
|
|
-CDEFINES = @USE_OPENSSL@ |
|
+CDEFINES = @CRYPTO@ |
|
CWARNINGS = |
|
|
|
DNSLIBS = ../../../../lib/dns/libdns.@A@ @DNS_CRYPTO_LIBS@ |
|
diff --git a/bin/tests/system/rsabigexponent/bigkey.c b/bin/tests/system/rsabigexponent/bigkey.c |
|
index aa2e8ec..436254c 100644 |
|
--- a/bin/tests/system/rsabigexponent/bigkey.c |
|
+++ b/bin/tests/system/rsabigexponent/bigkey.c |
|
@@ -16,7 +16,7 @@ |
|
|
|
/* $Id$ */ |
|
|
|
-#ifdef OPENSSL |
|
+#if defined(OPENSSL) || defined(PKCS11CRYPTO) |
|
#include <config.h> |
|
|
|
#include <stdio.h> |
|
@@ -44,8 +44,16 @@ |
|
#include <dst/dst.h> |
|
#include <dst/result.h> |
|
|
|
+#ifdef OPENSSL |
|
#include <openssl/opensslv.h> |
|
#if OPENSSL_VERSION_NUMBER <= 0x00908000L |
|
+#define USE_FIX_KEY_FILES |
|
+#endif |
|
+#else |
|
+#define USE_FIX_KEY_FILES |
|
+#endif |
|
+ |
|
+#ifdef USE_FIX_KEY_FILES |
|
|
|
/* |
|
* Use a fixed key file pair if OpenSSL doesn't support > 32 bit exponents. |
|
@@ -235,16 +243,16 @@ main(int argc, char **argv) { |
|
} |
|
#endif |
|
|
|
-#else /* OPENSSL */ |
|
+#else /* OPENSSL || PKCS11CRYPTO */ |
|
|
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
|
|
int |
|
-main(int argc, char **argv) { |
|
- fprintf(stderr, "Compiled without OpenSSL\n"); |
|
+main() { |
|
+ fprintf(stderr, "Compiled without Crypto\n"); |
|
exit(1); |
|
} |
|
|
|
-#endif /* OPENSSL */ |
|
+#endif /* OPENSSL || PKCS11CRYPTO */ |
|
/*! \file */ |
|
diff --git a/bin/tests/system/rsabigexponent/prereq.sh b/bin/tests/system/rsabigexponent/prereq.sh |
|
index 8edbf1d..6259fb6 100644 |
|
--- a/bin/tests/system/rsabigexponent/prereq.sh |
|
+++ b/bin/tests/system/rsabigexponent/prereq.sh |
|
@@ -22,6 +22,7 @@ if ./bigkey > /dev/null 2>&1 |
|
then |
|
rm -f Kexample.* |
|
else |
|
- echo "I:This test requires that --with-openssl was used." >&2 |
|
+ echo "I:This test requires cryptography" >&2 |
|
+ echo "I:--with-openssl, or --with-pkcs11 and --enable-native-pkcs11" >&2 |
|
exit 1 |
|
fi |
|
diff --git a/bin/tests/system/smartsign/prereq.sh b/bin/tests/system/smartsign/prereq.sh |
|
index e47b769..9ed2fa8 100644 |
|
--- a/bin/tests/system/smartsign/prereq.sh |
|
+++ b/bin/tests/system/smartsign/prereq.sh |
|
@@ -22,6 +22,7 @@ if $KEYGEN -q -r random.data foo > /dev/null 2>&1 |
|
then |
|
rm -f Kfoo* |
|
else |
|
- echo "I:This test requires that --with-openssl was used." >&2 |
|
+ echo "I:This test requires cryptography" >&2 |
|
+ echo "I:--with-openssl, or --with-pkcs11 and --enable-native-pkcs11" >&2 |
|
exit 1 |
|
fi |
|
diff --git a/bin/tests/system/tkey/keycreate.c b/bin/tests/system/tkey/keycreate.c |
|
index ff2c2ee..af17582 100644 |
|
--- a/bin/tests/system/tkey/keycreate.c |
|
+++ b/bin/tests/system/tkey/keycreate.c |
|
@@ -228,6 +228,7 @@ main(int argc, char *argv[]) { |
|
dns_result_register(); |
|
|
|
mctx = NULL; |
|
+ isc_mem_debugging = ISC_MEM_DEBUGRECORD; |
|
RUNCHECK(isc_mem_create(0, 0, &mctx)); |
|
|
|
ectx = NULL; |
|
diff --git a/bin/tests/system/tkey/prereq.sh b/bin/tests/system/tkey/prereq.sh |
|
index fca4a27..66295fe 100644 |
|
--- a/bin/tests/system/tkey/prereq.sh |
|
+++ b/bin/tests/system/tkey/prereq.sh |
|
@@ -23,6 +23,7 @@ if $KEYGEN -a RSAMD5 -b 512 -n zone -r random.data foo > /dev/null 2>&1 |
|
then |
|
rm -f foo* |
|
else |
|
- echo "I:This test requires that --with-openssl was used." >&2 |
|
+ echo "I:This test requires cryptography" >&2 |
|
+ echo "I:--with-openssl, or --with-pkcs11 and --enable-native-pkcs11" >&2 |
|
exit 1 |
|
fi |
|
diff --git a/config.h.in b/config.h.in |
|
index 4139e1d..f2eb59a 100644 |
|
--- a/config.h.in |
|
+++ b/config.h.in |
|
@@ -132,14 +132,11 @@ int sigwait(const unsigned int *set, int *sig); |
|
/** define if you have strerror in the C library. */ |
|
#undef HAVE_STRERROR |
|
|
|
-/** Define if you are running under Compaq TruCluster. */ |
|
-#undef HAVE_TRUCLUSTER |
|
- |
|
/* Define if OpenSSL includes DSA support */ |
|
#undef HAVE_OPENSSL_DSA |
|
|
|
-/* Define if OpenSSL includes ECDSA support */ |
|
-#undef HAVE_OPENSSL_ECDSA |
|
+/* Define if you have getpassphrase in the C library. */ |
|
+#undef HAVE_GETPASSPHRASE |
|
|
|
/* Define to the length type used by the socket API (socklen_t, size_t, int). */ |
|
#undef ISC_SOCKADDR_LEN_T |
|
@@ -187,6 +184,9 @@ int sigwait(const unsigned int *set, int *sig); |
|
/* Define to 1 if you have the `chroot' function. */ |
|
#undef HAVE_CHROOT |
|
|
|
+/* Define if clock_gettime is available. */ |
|
+#undef HAVE_CLOCK_GETTIME |
|
+ |
|
/* Define to 1 if you have the <devpoll.h> header file. */ |
|
#undef HAVE_DEVPOLL_H |
|
|
|
@@ -292,6 +292,12 @@ int sigwait(const unsigned int *set, int *sig); |
|
/* Define if your OpenSSL version supports GOST. */ |
|
#undef HAVE_OPENSSL_GOST |
|
|
|
+/* Define if your PKCS11 provider supports ECDSA. */ |
|
+#undef HAVE_PKCS11_ECDSA |
|
+ |
|
+/* Define if your PKCS11 provider supports GOST. */ |
|
+#undef HAVE_PKCS11_GOST |
|
+ |
|
/* Define to 1 if you have the `readline' function. */ |
|
#undef HAVE_READLINE |
|
|
|
@@ -418,6 +424,9 @@ int sigwait(const unsigned int *set, int *sig); |
|
(O_NDELAY/O_NONBLOCK). */ |
|
#undef PORT_NONBLOCK |
|
|
|
+/* Define if GOST private keys are encoded in ASN.1. */ |
|
+#undef PREFER_GOSTASN1 |
|
+ |
|
/* The size of `void *', as computed by sizeof. */ |
|
/* #undef SIZEOF_VOID_P */ |
|
|
|
diff --git a/configure.in b/configure.in |
|
index 8a06905..24eafb7 100644 |
|
--- a/configure.in |
|
+++ b/configure.in |
|
@@ -640,25 +640,76 @@ AC_ARG_WITH(openssl, |
|
(Required for DNSSEC)], |
|
use_openssl="$withval", use_openssl="auto") |
|
|
|
+# |
|
+# was --enable-native-pkcs11 specified? |
|
+# (note it implies both --without-openssl and --with-pkcs11) |
|
+# |
|
+AC_ARG_ENABLE(native-pkcs11, |
|
+ [ --enable-native-pkcs11 use native PKCS11 for all crypto [[default=no]]], |
|
+ want_native_pkcs11="$enableval", want_native_pkcs11="no") |
|
+ |
|
+AC_ARG_WITH(pkcs11, |
|
+[ --with-pkcs11[=PATH] Build with PKCS11 support [yes|no|path] |
|
+ (PATH is for the PKCS11 provider)], |
|
+ use_pkcs11="$withval", use_pkcs11="auto") |
|
+ |
|
openssldirs="/usr /usr/local /usr/local/ssl /usr/pkg /usr/sfw" |
|
if test "$use_openssl" = "auto" |
|
then |
|
- for d in $openssldirs |
|
- do |
|
- if test -f $d/include/openssl/opensslv.h |
|
- then |
|
- use_openssl=$d |
|
- break |
|
- fi |
|
- done |
|
+ if test "$want_native_pkcs11" = "yes" |
|
+ then |
|
+ use_openssl="native_pkcs11" |
|
+ else |
|
+ for d in $openssldirs |
|
+ do |
|
+ if test -f $d/include/openssl/opensslv.h |
|
+ then |
|
+ use_openssl=$d |
|
+ break |
|
+ fi |
|
+ done |
|
+ fi |
|
fi |
|
OPENSSL_ECDSA="" |
|
OPENSSL_GOST="" |
|
+AC_ARG_WITH(gost, |
|
+[ --with-gost Crypto GOST [yes|no|raw|asn1].], |
|
+ with_gost="$withval", with_gost="auto") |
|
+AC_ARG_WITH(ecdsa, [ --with-ecdsa OpenSSL ECDSA], |
|
+ with_ecdsa="$withval", with_ecdsa="auto") |
|
+ |
|
+gosttype="raw" |
|
+case "$with_gost" in |
|
+ raw) |
|
+ with_gost="yes" |
|
+ ;; |
|
+ asn1) |
|
+ AC_DEFINE(PREFER_GOSTASN1, 1, |
|
+ [Define if GOST private keys are encoded in ASN.1.]) |
|
+ gosttype="asn1" |
|
+ with_gost="yes" |
|
+ ;; |
|
+ auto|yes|no) |
|
+ ;; |
|
+ *) |
|
+ AC_MSG_ERROR(unknown GOST private key encoding) |
|
+ ;; |
|
+esac |
|
+ |
|
case "$use_openssl" in |
|
+ native_pkcs11) |
|
+ AC_MSG_RESULT(disabled because of native PKCS11) |
|
+ DST_OPENSSL_INC="" |
|
+ CRYPTO="" |
|
+ OPENSSLGOSTLINKOBJS="" |
|
+ OPENSSLGOSTLINKSRS="" |
|
+ OPENSSLLINKOBJS="" |
|
+ OPENSSLLINKSRCS="" |
|
+ ;; |
|
no) |
|
AC_MSG_RESULT(no) |
|
DST_OPENSSL_INC="" |
|
- USE_OPENSSL="" |
|
+ CRYPTO="" |
|
OPENSSLGOSTLINKOBJS="" |
|
OPENSSLGOSTLINKSRS="" |
|
OPENSSLLINKOBJS="" |
|
@@ -666,7 +717,7 @@ case "$use_openssl" in |
|
;; |
|
auto) |
|
DST_OPENSSL_INC="" |
|
- USE_OPENSSL="" |
|
+ CRYPTO="" |
|
OPENSSLGOSTLINKOBJS="" |
|
OPENSSLGOSTLINKSRS="" |
|
OPENSSLLINKOBJS="" |
|
@@ -676,6 +727,11 @@ case "$use_openssl" in |
|
If you don't want OpenSSL, use --without-openssl]) |
|
;; |
|
*) |
|
+ if test "$want_native_pkcs11" = "yes" |
|
+ then |
|
+ AC_MSG_RESULT() |
|
+ AC_MSG_ERROR([OpenSSL and native PKCS11 cannot be used together.]) |
|
+ fi |
|
if test "$use_openssl" = "yes" |
|
then |
|
# User did not specify a path - guess it |
|
@@ -697,7 +753,7 @@ If you don't want OpenSSL, use --without-openssl]) |
|
then |
|
AC_MSG_ERROR(["$use_openssl/include/openssl/opensslv.h" not found]) |
|
fi |
|
- USE_OPENSSL='-DOPENSSL' |
|
+ CRYPTO='-DOPENSSL' |
|
if test "$use_openssl" = "/usr" |
|
then |
|
DST_OPENSSL_INC="" |
|
@@ -733,6 +789,7 @@ If you don't want OpenSSL, use --without-openssl]) |
|
fi |
|
AC_MSG_RESULT(using OpenSSL from $use_openssl/lib and $use_openssl/include) |
|
|
|
+ saved_cc="$CC" |
|
saved_cflags="$CFLAGS" |
|
saved_libs="$LIBS" |
|
CFLAGS="$CFLAGS $DST_OPENSSL_INC" |
|
@@ -839,8 +896,7 @@ int main() { |
|
[AC_MSG_RESULT(no) |
|
have_ecdsa="no"], |
|
[AC_MSG_RESULT(using --with-ecdsa)]) |
|
- AC_ARG_WITH(ecdsa, [ --with-ecdsa OpenSSL ECDSA], |
|
- with_ecdsa="$withval", with_ecdsa="auto") |
|
+ |
|
case "$with_ecdsa" in |
|
yes) |
|
case "$have_ecdsa" in |
|
@@ -869,6 +925,15 @@ int main() { |
|
|
|
AC_MSG_CHECKING(for OpenSSL GOST support) |
|
have_gost="" |
|
+ case "$use_pkcs11" in |
|
+ auto|no) |
|
+ ;; |
|
+ *) |
|
+ if $use_threads; then |
|
+ CC="$CC -pthread" |
|
+ fi |
|
+ ;; |
|
+ esac |
|
AC_TRY_RUN([ |
|
#include <openssl/conf.h> |
|
#include <openssl/engine.h> |
|
@@ -896,8 +961,7 @@ int main() { |
|
[AC_MSG_RESULT(no) |
|
have_gost="no"], |
|
[AC_MSG_RESULT(using --with-gost)]) |
|
- AC_ARG_WITH(gost, [ --with-gost OpenSSL GOST], |
|
- with_gost="$withval", with_gost="auto") |
|
+ |
|
case "$with_gost" in |
|
yes) |
|
case "$have_gost" in |
|
@@ -910,7 +974,7 @@ int main() { |
|
*) |
|
case "$have_gost" in |
|
yes|no) ;; |
|
- *) AC_MSG_ERROR([need --with-gost=[[yes or no]]]) ;; |
|
+ *) AC_MSG_ERROR([need --with-gost=[[yes, no, raw or asn1]]]) ;; |
|
esac |
|
;; |
|
esac |
|
@@ -938,7 +1002,6 @@ esac |
|
# it as needed) if it is found. |
|
# |
|
|
|
-AC_SUBST(USE_OPENSSL) |
|
AC_SUBST(DST_OPENSSL_INC) |
|
AC_SUBST(OPENSSLGOSTLINKOBJS) |
|
AC_SUBST(OPENSSLGOSTLINKSRCS) |
|
@@ -958,7 +1021,7 @@ AC_ARG_ENABLE(openssl-hash, |
|
want_openssl_hash="$enableval", want_openssl_hash="no") |
|
case $want_openssl_hash in |
|
yes) |
|
- if test "$USE_OPENSSL" = "" |
|
+ if test "$CRYPTO" = "" |
|
then |
|
AC_MSG_ERROR([No OpenSSL for hash functions]) |
|
fi |
|
@@ -973,6 +1036,41 @@ esac |
|
AC_SUBST(ISC_PLATFORM_OPENSSLHASH) |
|
AC_SUBST(ISC_OPENSSL_INC) |
|
|
|
+AC_ARG_WITH(libtool, |
|
+ [ --with-libtool use GNU libtool], |
|
+ use_libtool="$withval", use_libtool="no") |
|
+ |
|
+case $use_libtool in |
|
+ yes) |
|
+ AM_PROG_LIBTOOL |
|
+ O=lo |
|
+ A=la |
|
+ LIBTOOL_MKDEP_SED='s;\.o;\.lo;' |
|
+ LIBTOOL_MODE_COMPILE='--mode=compile --tag=CC' |
|
+ LIBTOOL_MODE_INSTALL='--mode=install --tag=CC' |
|
+ LIBTOOL_MODE_LINK='--mode=link --tag=CC' |
|
+ case "$host" in |
|
+ *) LIBTOOL_ALLOW_UNDEFINED= ;; |
|
+ esac |
|
+ case "$host" in |
|
+ *-ibm-aix*) LIBTOOL_IN_MAIN="-Wl,-bI:T_testlist.imp" ;; |
|
+ *) LIBTOOL_IN_MAIN= ;; |
|
+ esac; |
|
+ ;; |
|
+ *) |
|
+ O=o |
|
+ A=a |
|
+ LIBTOOL= |
|
+ AC_SUBST(LIBTOOL) |
|
+ LIBTOOL_MKDEP_SED= |
|
+ LIBTOOL_MODE_COMPILE= |
|
+ LIBTOOL_MODE_INSTALL= |
|
+ LIBTOOL_MODE_LINK= |
|
+ LIBTOOL_ALLOW_UNDEFINED= |
|
+ LIBTOOL_IN_MAIN= |
|
+ ;; |
|
+esac |
|
+ |
|
# |
|
# PKCS11 (aka crypto hardware) support |
|
# |
|
@@ -980,25 +1078,102 @@ AC_SUBST(ISC_OPENSSL_INC) |
|
# |
|
|
|
AC_MSG_CHECKING(for PKCS11 support) |
|
-AC_ARG_WITH(pkcs11, |
|
-[ --with-pkcs11[=PATH] Build with PKCS11 support [yes|no|path] |
|
- (PATH is for the PKCS11 provider)], |
|
- use_pkcs11="$withval", use_pkcs11="no") |
|
+ |
|
+if test "$use_pkcs11" = "auto" |
|
+then |
|
+ if test "$want_native_pkcs11" = "yes" |
|
+ then |
|
+ use_pkcs11="yes" |
|
+ else |
|
+ use_pkcs11="no" |
|
+ fi |
|
+fi |
|
|
|
case "$use_pkcs11" in |
|
no|'') |
|
- AC_MSG_RESULT(disabled) |
|
- USE_PKCS11='' |
|
- PKCS11_TOOLS='' |
|
+ AC_MSG_RESULT(no) |
|
+ USE_PKCS11="" |
|
+ PKCS11_TEST="" |
|
+ PKCS11_TOOLS="" |
|
+ ISC_PK11_C="" |
|
+ ISC_PK11_O="" |
|
+ ISC_PK11_API_C="" |
|
+ ISC_PK11_API_O="" |
|
+ ISC_PK11_RESULT_C="" |
|
+ ISC_PK11_RESULT_O="" |
|
+ ISC_ISCPK11_API_C="" |
|
+ ISC_ISCPK11_API_O="" |
|
;; |
|
yes|*) |
|
- AC_MSG_RESULT(using OpenSSL with PKCS11 support) |
|
+ AC_MSG_RESULT(yes) |
|
+ if ! $use_threads; then |
|
+ AC_MSG_ERROR([PKCS11 requires thread support]) |
|
+ fi |
|
+ if test "$CRYPTO" != "" |
|
+ then |
|
+ AC_MSG_CHECKING(for OpenSSL with PKCS11 support) |
|
+ saved_cc="$CC" |
|
+ saved_cflags="$CFLAGS" |
|
+ saved_libs="$LIBS" |
|
+ CC="$CC -pthread" |
|
+ CFLAGS="$CFLAGS $DST_OPENSSL_INC" |
|
+ LIBS="$LIBS $DNS_OPENSSL_LIBS" |
|
+ AC_TRY_RUN([ |
|
+#include <openssl/conf.h> |
|
+#include <openssl/engine.h> |
|
+int main() { |
|
+ ENGINE *e; |
|
+ |
|
+ OPENSSL_config(NULL); |
|
+ e = ENGINE_by_id("pkcs11"); |
|
+ if (e == NULL) |
|
+ return (1); |
|
+ if (ENGINE_init(e) <= 0) |
|
+ return (1); |
|
+ return (0); |
|
+} |
|
+], |
|
+ [AC_MSG_RESULT(yes) |
|
+ PKCS11_TEST=pkcs11ssl |
|
+ PKCS11_ENGINE='-DPKCS11_ENGINE="\"pkcs11\""'], |
|
+ [AC_MSG_RESULT(no) |
|
+ PKCS11_TEST='' |
|
+ PKCS11_ENGINE='-DPKCS11_ENGINE=NULL'], |
|
+ [AC_MSG_RESULT(cross compile, defaulting to no) |
|
+ PKCS11_TEST='' |
|
+ PKCS11_ENGINE='-DPKCS11_ENGINE=NULL']) |
|
+ CC="$saved_cc" |
|
+ CFLAGS="$saved_cflags" |
|
+ LIBS="$saved_libs" |
|
+ else |
|
+ PKCS11_TEST='' |
|
+ PKCS11_ENGINE='-DPKCS11_ENGINE=NULL' |
|
+ |
|
+ fi |
|
USE_PKCS11='-DUSE_PKCS11' |
|
PKCS11_TOOLS=pkcs11 |
|
- ;; |
|
+ AC_CHECK_FUNC(getpassphrase, AC_DEFINE(HAVE_GETPASSPHRASE),) |
|
+ ISC_PK11_C="pk11.c" |
|
+ ISC_PK11_O="pk11.$O" |
|
+ ISC_PK11_API_C="pk11_api.c" |
|
+ ISC_PK11_API_O="pk11_api.$O" |
|
+ ISC_PK11_RESULT_C="pk11_result.c" |
|
+ ISC_PK11_RESULT_O="pk11_result.$O" |
|
+ ISC_ISCPK11_API_C="unix/pk11_api.c" |
|
+ ISC_ISCPK11_API_O="unix/pk11_api.$O" |
|
+ ;; |
|
esac |
|
AC_SUBST(USE_PKCS11) |
|
AC_SUBST(PKCS11_TOOLS) |
|
+AC_SUBST(PKCS11_ENGINE) |
|
+AC_SUBST(ISC_PK11_C) |
|
+AC_SUBST(ISC_PK11_O) |
|
+AC_SUBST(ISC_PK11_API_C) |
|
+AC_SUBST(ISC_PK11_API_O) |
|
+AC_SUBST(ISC_PK11_RESULT_C) |
|
+AC_SUBST(ISC_PK11_RESULT_O) |
|
+AC_SUBST(ISC_ISCPK11_API_C) |
|
+AC_SUBST(ISC_ISCPK11_API_O) |
|
|
|
AC_MSG_CHECKING(for PKCS11 tools) |
|
case "$use_pkcs11" in |
|
@@ -1006,13 +1181,77 @@ case "$use_pkcs11" in |
|
AC_MSG_RESULT(disabled) |
|
PKCS11_PROVIDER="undefined" |
|
;; |
|
- *) |
|
- AC_MSG_RESULT(PKCS11 provider is "$use_pkcs11") |
|
+ yes|'') |
|
+ PKCS11_PROVIDER="undefined" |
|
+ AC_MSG_RESULT(enabled) |
|
+ ;; |
|
+ *) |
|
PKCS11_PROVIDER="$use_pkcs11" |
|
+ AC_MSG_RESULT([enabled, PKCS11 provider is $PKCS11_PROVIDER]) |
|
;; |
|
esac |
|
AC_SUBST(PKCS11_PROVIDER) |
|
|
|
+ |
|
+PKCS11_ECDSA="" |
|
+PKCS11_GOST="" |
|
+AC_MSG_CHECKING(for native PKCS11) |
|
+ |
|
+case "$want_native_pkcs11" in |
|
+ yes) |
|
+ AC_MSG_RESULT(using native PKCS11 crypto) |
|
+ CRYPTO="-DPKCS11CRYPTO" |
|
+ PKCS11LINKOBJS='${PKCS11LINKOBJS}' |
|
+ PKCS11LINKSRCS='${PKCS11LINKSRCS}' |
|
+ PKCS11_TEST=pkcs11 |
|
+ AC_MSG_CHECKING(for PKCS11 ECDSA) |
|
+ case "$with_ecdsa" in |
|
+ no) |
|
+ AC_MSG_RESULT([disabled]) |
|
+ ;; |
|
+ *) |
|
+ AC_MSG_RESULT(enabled) |
|
+ PKCS11_ECDSA="yes" |
|
+ AC_DEFINE(HAVE_PKCS11_ECDSA, 1, |
|
+ [Define if your PKCS11 provider supports ECDSA.]) |
|
+ ;; |
|
+ esac |
|
+ AC_MSG_CHECKING(for PKCS11 GOST) |
|
+ case "$with_gost" in |
|
+ yes) |
|
+ AC_MSG_RESULT(enabled) |
|
+ PKCS11_GOST="yes" |
|
+ AC_DEFINE(HAVE_PKCS11_GOST, 1, |
|
+ [Define if your PKCS11 provider supports GOST.]) |
|
+ ;; |
|
+ *) |
|
+ AC_MSG_RESULT([disabled]) |
|
+ ;; |
|
+ esac |
|
+ ;; |
|
+ no|'') |
|
+ AC_MSG_RESULT(disabled) |
|
+ ;; |
|
+esac |
|
+ |
|
+AC_SUBST(PKCS11LINKOBJS) |
|
+AC_SUBST(PKCS11LINKSRCS) |
|
+AC_SUBST(CRYPTO) |
|
+AC_SUBST(PKCS11_ECDSA) |
|
+AC_SUBST(PKCS11_GOST) |
|
+AC_SUBST(PKCS11_TEST) |
|
+ |
|
+# for PKCS11 benchmarks |
|
+have_clock_gt=no |
|
+AC_CHECK_FUNC(clock_gettime,have_clock_gt=yes,) |
|
+if test "$have_clock_gt" = "no"; then |
|
+ AC_CHECK_LIB(rt,clock_gettime,have_clock_gt=ye,,) |
|
+ fi |
|
+if test "$have_clock_gt" = "yes"; then |
|
+ AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if clock_gettime is available.]) |
|
+fi |
|
+ |
|
+ |
|
AC_MSG_CHECKING(for GSSAPI library) |
|
AC_ARG_WITH(gssapi, |
|
[ --with-gssapi=PATH Specify path for system-supplied GSSAPI [[default=yes]]], |
|
@@ -1245,6 +1484,21 @@ case "$use_randomdev" in |
|
esac |
|
|
|
# |
|
+# Only check dsa signature generation on these platforms when performing |
|
+# system tests. |
|
+# |
|
+CHECK_DSA=0 |
|
+if grep "#define PATH_RANDOMDEV " confdefs.h > /dev/null |
|
+then |
|
+ case "$host" in |
|
+ *darwin*|*freebsd*) |
|
+ CHECK_DSA=1 |
|
+ ;; |
|
+ esac |
|
+fi |
|
+AC_SUBST(CHECK_DSA) |
|
+ |
|
+# |
|
# Do we have arc4random() ? |
|
# |
|
AC_CHECK_FUNC(arc4random, AC_DEFINE(HAVE_ARC4RANDOM)) |
|
@@ -1633,41 +1887,6 @@ esac |
|
AC_SUBST(PURIFY) |
|
|
|
|
|
-AC_ARG_WITH(libtool, |
|
- [ --with-libtool use GNU libtool], |
|
- use_libtool="$withval", use_libtool="no") |
|
- |
|
-case $use_libtool in |
|
- yes) |
|
- AM_PROG_LIBTOOL |
|
- O=lo |
|
- A=la |
|
- LIBTOOL_MKDEP_SED='s;\.o;\.lo;' |
|
- LIBTOOL_MODE_COMPILE='--mode=compile --tag=CC' |
|
- LIBTOOL_MODE_INSTALL='--mode=install --tag=CC' |
|
- LIBTOOL_MODE_LINK='--mode=link --tag=CC' |
|
- case "$host" in |
|
- *) LIBTOOL_ALLOW_UNDEFINED= ;; |
|
- esac |
|
- case "$host" in |
|
- *-ibm-aix*) LIBTOOL_IN_MAIN="-Wl,-bI:T_testlist.imp" ;; |
|
- *) LIBTOOL_IN_MAIN= ;; |
|
- esac; |
|
- ;; |
|
- *) |
|
- O=o |
|
- A=a |
|
- LIBTOOL= |
|
- AC_SUBST(LIBTOOL) |
|
- LIBTOOL_MKDEP_SED= |
|
- LIBTOOL_MODE_COMPILE= |
|
- LIBTOOL_MODE_INSTALL= |
|
- LIBTOOL_MODE_LINK= |
|
- LIBTOOL_ALLOW_UNDEFINED= |
|
- LIBTOOL_IN_MAIN= |
|
- ;; |
|
-esac |
|
- |
|
# |
|
# enable/disable dumping stack backtrace. Also check if the system supports |
|
# glibc-compatible backtrace() function. |
|
@@ -3419,6 +3638,9 @@ BIND9_CONFIGARGS="`echo $BIND9_CONFIGARGS | sed 's/^ //'`" |
|
BIND9_CONFIGARGS="CONFIGARGS=${BIND9_CONFIGARGS}" |
|
AC_SUBST(BIND9_CONFIGARGS) |
|
|
|
+AC_SUBST_FILE(LIBISCPK11_API) |
|
+LIBISCPK11_API="$srcdir/lib/iscpk11/api" |
|
+ |
|
AC_SUBST_FILE(LIBISC_API) |
|
LIBISC_API="$srcdir/lib/isc/api" |
|
|
|
@@ -3728,6 +3950,8 @@ AC_CONFIG_FILES([ |
|
bin/tests/mem/Makefile |
|
bin/tests/names/Makefile |
|
bin/tests/net/Makefile |
|
+ bin/tests/pkcs11/Makefile |
|
+ bin/tests/pkcs11/benchmarks/Makefile |
|
bin/tests/rbt/Makefile |
|
bin/tests/resolver/Makefile |
|
bin/tests/sockaddr/Makefile |
|
@@ -3811,11 +4035,14 @@ AC_CONFIG_FILES([ |
|
lib/isc/include/Makefile |
|
lib/isc/include/isc/Makefile |
|
lib/isc/include/isc/platform.h |
|
+ lib/isc/include/pk11/Makefile |
|
+ lib/isc/include/pkcs11/Makefile |
|
lib/isc/tests/Makefile |
|
lib/isc/nls/Makefile |
|
lib/isc/unix/Makefile |
|
lib/isc/unix/include/Makefile |
|
lib/isc/unix/include/isc/Makefile |
|
+ lib/isc/unix/include/pkcs11/Makefile |
|
lib/isccc/Makefile |
|
lib/isccc/include/Makefile |
|
lib/isccc/include/isccc/Makefile |
|
@@ -3885,12 +4112,8 @@ test "$use_pkcs11" = "no" || echo " PKCS#11/Cryptoki support (--with-pkcs11)" |
|
if test "$enable_full_report" = "yes"; then |
|
test "$enable_ipv6" = "no" -o "$found_ipv6" = "no" || \ |
|
echo " IPv6 support (--enable-ipv6)" |
|
- test "X$USE_OPENSSL" = "X" || \ |
|
+ test "X$CRYPTO" = "X" -o "$want_native_pkcs11" = "yes" || \ |
|
echo " OpenSSL cryptography/DNSSEC (--with-openssl)" |
|
- test "$OPENSSL_GOST" != "yes" || \ |
|
- echo " GOST algorithm support (--with-gost)" |
|
- test "$OPENSSL_ECDSA" != "yes" || \ |
|
- echo " ECDSA algorithm support (--with-ecdsa)" |
|
test "X$PYTHON" = "X" || echo " Python tools (--with-python)" |
|
test "X$libxml2_libs" = "X" || echo " XML statistics (--with-libxml2)" |
|
fi |
|
@@ -3923,24 +4146,28 @@ test "$enable_filter" = "yes" || \ |
|
test "$use_gssapi" = "no" && echo " GSS-API (--with-gssapi)" |
|
test "$want_backtrace" = "yes" || \ |
|
echo " Print backtrace on crash (--enable-backtrace)" |
|
-test "$use_pkcs11" = "no" && echo " PKCS#11/Cryptoki support (--with-pkcs11)" |
|
|
|
-test "$enable_ipv6" = "no" -o "$found_ipv6" = "no" && \ |
|
- echo " IPv6 support (--enable-ipv6)" |
|
-test "X$USE_OPENSSL" = "X" && \ |
|
- echo " OpenSSL cryptography/DNSSEC (--with-openssl)" |
|
-test "X$USE_OPENSSL" != "X" -a "$OPENSSL_GOST" != "yes" && \ |
|
+test "X$CRYPTO" = "X" -o "$want_native_pkcs11" = "yes" && \ |
|
+ echo " OpenSSL cryptography/DNSSEC (--with-openssl)" |
|
+test "$want_native_pkcs11" != "yes" && \ |
|
+ echo " Native PKCS#11 cryptography/DNSSEC (--enable-native-pkcs11)" |
|
+test "X$CRYPTO" = "X" -o "$OPENSSL_GOST" = "yes" -o "$PKCS11_GOST" = "yes" || \ |
|
echo " GOST algorithm support (--with-gost)" |
|
-test "X$USE_OPENSSL" != "X" -a "$OPENSSL_ECDSA" != "yes" && \ |
|
+test "X$CRYPTO" = "X" -o "$OPENSSL_ECDSA" = "yes" -o "$PKCS11_ECDSA" = "yes" || \ |
|
echo " ECDSA algorithm support (--with-ecdsa)" |
|
+test "$use_pkcs11" = "no" && echo " PKCS#11/Cryptoki support (--with-pkcs11)" |
|
+test "$enable_ipv6" = "no" -o "$found_ipv6" = "no" && \ |
|
+ echo " IPv6 support (--enable-ipv6)" |
|
test "X$PYTHON" = "X" && echo " Python tools (--with-python)" |
|
test "X$libxml2_libs" = "X" && echo " XML statistics (--with-libxml2)" |
|
|
|
echo "========================================================================" |
|
|
|
-if test "X$USE_OPENSSL" = "X"; then |
|
+if test "X$CRYPTO" = "X"; then |
|
cat << \EOF |
|
-BIND is being built without OpenSSL. This means it will not have DNSSEC support. |
|
+BIND 9 is being built without cryptography support. This means it will |
|
+not have DNSSEC support. Use --with-openssl, or --with-pkcs11 and |
|
+--enable-native-pkcs11 to enable cryptography. |
|
EOF |
|
fi |
|
|
|
diff --git a/doc/arm/pkcs11.xml b/doc/arm/pkcs11.xml |
|
index b4e22bb..5388a29 100644 |
|
--- a/doc/arm/pkcs11.xml |
|
+++ b/doc/arm/pkcs11.xml |
|
@@ -20,162 +20,259 @@ |
|
<!-- $Id: pkcs11.xml,v 1.7 2012/01/16 22:50:12 each Exp $ --> |
|
|
|
<sect1 id="pkcs11"> |
|
- <title>PKCS #11 (Cryptoki) support</title> |
|
- <para>PKCS #11 (Public Key Cryptography Standard #11) defines a |
|
- platform- independent API for the control of hardware security |
|
- modules (HSMs) and other cryptographic support devices.</para> |
|
- <para>BIND 9 is known to work with two HSMs: The Sun SCA 6000 |
|
- cryptographic acceleration board, tested under Solaris x86, and |
|
- the AEP Keyper network-attached key storage device, tested with |
|
- Debian Linux, Solaris x86 and Windows Server 2003.</para> |
|
+ <title>PKCS#11 (Cryptoki) support</title> |
|
+ <para> |
|
+ PKCS#11 (Public Key Cryptography Standard #11) defines a |
|
+ platform-independent API for the control of hardware security |
|
+ modules (HSMs) and other cryptographic support devices. |
|
+ </para> |
|
+ <para> |
|
+ BIND 9 is known to work with three HSMs: The AEP Keyper, which has |
|
+ been tested with Debian Linux, Solaris x86 and Windows Server 2003; |
|
+ the Thales nShield, tested with Debian Linux; and the Sun SCA 6000 |
|
+ cryptographic acceleration board, tested with Solaris x86. In |
|
+ addition, BIND can be used with SoftHSM, a software-based HSM |
|
+ simulator produced by the OpenDNSSEC project. |
|
+ </para> |
|
+ <para> |
|
+ PKCS#11 makes use of a "provider library": a dynamically loadable |
|
+ library which provides a low-level PKCS#11 interface to drive the HSM |
|
+ hardware. The PKCS#11 provider library comes from the HSM vendor, and |
|
+ it is specific to the HSM to be controlled. |
|
+ </para> |
|
+ <para> |
|
+ There are two available mechanisms for PKCS#11 support in BIND 9: |
|
+ OpenSSL-based PKCS#11 and native PKCS#11. When using the first |
|
+ mechanism, BIND uses a modified version of OpenSSL, which loads |
|
+ the provider library and operates the HSM indirectly; any |
|
+ cryptographic operations not supported by the HSM can be carried |
|
+ out by OpenSSL instead. The second mechanism enables BIND to bypass |
|
+ OpenSSL completely; BIND loads the provider library itself, and uses |
|
+ the PKCS#11 API to drive the HSM directly. |
|
+ </para> |
|
<sect2> |
|
<title>Prerequisites</title> |
|
- <para>See the HSM vendor documentation for information about |
|
- installing, initializing, testing and troubleshooting the |
|
- HSM.</para> |
|
- <para>BIND 9 uses OpenSSL for cryptography, but stock OpenSSL |
|
- does not yet fully support PKCS #11. However, a PKCS #11 engine |
|
- for OpenSSL is available from the OpenSolaris project. It has |
|
- been modified by ISC to work with with BIND 9, and to provide |
|
- new features such as PIN management and key by |
|
- reference.</para> |
|
- <para>The patched OpenSSL depends on a "PKCS #11 provider". |
|
- This is a shared library object, providing a low-level PKCS #11 |
|
- interface to the HSM hardware. It is dynamically loaded by |
|
- OpenSSL at runtime. The PKCS #11 provider comes from the HSM |
|
- vendor, and is specific to the HSM to be controlled.</para> |
|
- <para>There are two "flavors" of PKCS #11 support provided by |
|
- the patched OpenSSL, one of which must be chosen at |
|
- configuration time. The correct choice depends on the HSM |
|
- hardware:</para> |
|
+ <para> |
|
+ See the documentation provided by your HSM vendor for |
|
+ information about installing, initializing, testing and |
|
+ troubleshooting the HSM. |
|
+ </para> |
|
+ </sect2> |
|
+ <sect2> |
|
+ <title>Native PKCS#11</title> |
|
+ <para> |
|
+ Native PKCS#11 mode will only work with an HSM capable of carrying |
|
+ out <emphasis>every</emphasis> cryptographic operation BIND 9 may |
|
+ need. The HSM's provider library must have a complete implementation |
|
+ of the PKCS#11 API, so that all these functions are accessible. As of |
|
+ this writing, only the Thales nShield HSM and the latest development |
|
+ version of SoftHSM can be used in this fashion. For other HSM's, |
|
+ including the AEP Keyper, Sun SCA 6000 and older versions of SoftHSM, |
|
+ use OpenSSL-based PKCS#11. (Note: As more HSMs become capable of |
|
+ supporting native PKCS#11, it is expected that OpenSSL-based |
|
+ PKCS#11 will eventually be deprecated.) |
|
+ </para> |
|
+ <para> |
|
+ To build BIND with native PKCS#11, configure as follows: |
|
+ </para> |
|
+ <screen> |
|
+$ <userinput>cd bind9</userinput> |
|
+$ <userinput>./configure --enable-native-pkcs11 \ |
|
+ --with-pkcs11=<replaceable>provider-library-path</replaceable></userinput> |
|
+ </screen> |
|
+ <para> |
|
+ This will cause all BIND tools, including <command>named</command> |
|
+ and the <command>dnssec-*</command> and <command>pkcs11-*</command> |
|
+ tools, to use the PKCS#11 provider library specified in |
|
+ <replaceable>provider-library-path</replaceable> for cryptography. |
|
+ (The provider library path can be overridden using the |
|
+ <option>-E</option> in <command>named</command> and the |
|
+ <command>dnssec-*</command> tools, or the <option>-m</option> in |
|
+ the <command>pkcs11-*</command> tools.) |
|
+ </para> |
|
+ </sect2> |
|
+ <sect2> |
|
+ <title>OpenSSL-based PKCS#11</title> |
|
+ <para> |
|
+ OpenSSL-based PKCS#11 mode uses a modified version of the |
|
+ OpenSSL library; stock OpenSSL does not fully support PKCS#11. |
|
+ ISC provides a patch to OpenSSL to correct this. This patch is |
|
+ based on work originally done by the OpenSolaris project; it has been |
|
+ modified by ISC to provide new features such as PIN management and |
|
+ key-by-reference. |
|
+ </para> |
|
+ <para> |
|
+ There are two "flavors" of PKCS#11 support provided by |
|
+ the patched OpenSSL, one of which must be chosen at |
|
+ configuration time. The correct choice depends on the HSM |
|
+ hardware: |
|
+ </para> |
|
<itemizedlist> |
|
<listitem> |
|
- <para>Use 'crypto-accelerator' with HSMs that have hardware |
|
- cryptographic acceleration features, such as the SCA 6000 |
|
- board. This causes OpenSSL to run all supported |
|
- cryptographic operations in the HSM.</para> |
|
+ <para> |
|
+ Use 'crypto-accelerator' with HSMs that have hardware |
|
+ cryptographic acceleration features, such as the SCA 6000 |
|
+ board. This causes OpenSSL to run all supported |
|
+ cryptographic operations in the HSM. |
|
+ </para> |
|
</listitem> |
|
<listitem> |
|
- <para>Use 'sign-only' with HSMs that are designed to |
|
- function primarily as secure key storage devices, but lack |
|
- hardware acceleration. These devices are highly secure, but |
|
- are not necessarily any faster at cryptography than the |
|
- system CPU — often, they are slower. It is therefore |
|
- most efficient to use them only for those cryptographic |
|
- functions that require access to the secured private key, |
|
- such as zone signing, and to use the system CPU for all |
|
- other computationally-intensive operations. The AEP Keyper |
|
- is an example of such a device.</para> |
|
+ <para> |
|
+ Use 'sign-only' with HSMs that are designed to |
|
+ function primarily as secure key storage devices, but lack |
|
+ hardware acceleration. These devices are highly secure, but |
|
+ are not necessarily any faster at cryptography than the |
|
+ system CPU — often, they are slower. It is therefore |
|
+ most efficient to use them only for those cryptographic |
|
+ functions that require access to the secured private key, |
|
+ such as zone signing, and to use the system CPU for all |
|
+ other computationally-intensive operations. The AEP Keyper |
|
+ is an example of such a device. |
|
+ </para> |
|
</listitem> |
|
</itemizedlist> |
|
- <para>The modified OpenSSL code is included in the BIND 9 release, |
|
- in the form of a context diff against the latest verions of |
|
- OpenSSL. OpenSSL 0.9.8, 1.0.0 and 1.0.1 are supported; there are |
|
- separate diffs for each version. In the examples to follow, |
|
- we use OpenSSL 0.9.8, but the same methods work with OpenSSL 1.0.0 |
|
- and 1.0.1. |
|
+ <para> |
|
+ The modified OpenSSL code is included in the BIND 9 release, |
|
+ in the form of a context diff against the latest verions of |
|
+ OpenSSL. OpenSSL 0.9.8, 1.0.0, and 1.0.1 are supported; there are |
|
+ separate diffs for each version. In the examples to follow, |
|
+ we use OpenSSL 0.9.8, but the same methods work with OpenSSL |
|
+ 1.0.0 and 1.0.1. |
|
</para> |
|
<note> |
|
- The latest OpenSSL versions at the time of the BIND release |
|
- are 0.9.8y, 1.0.0k and 1.0.1e. |
|
- ISC will provide an updated patch as new versions of OpenSSL |
|
+ The latest OpenSSL versions as of this writing (January 2014) |
|
+ are 0.9.8y, 1.0.0l, and 1.0.1f. |
|
+ ISC will provide updated patches as new versions of OpenSSL |
|
are released. The version number in the following examples |
|
- is expected to change.</note> |
|
+ is expected to change. |
|
+ </note> |
|
<para> |
|
- Before building BIND 9 with PKCS #11 support, it will be |
|
- necessary to build OpenSSL with this patch in place and inform |
|
- it of the path to the HSM-specific PKCS #11 provider |
|
- library.</para> |
|
- <para>Obtain OpenSSL 0.9.8s:</para> |
|
- <screen> |
|
-$ <userinput>wget <ulink>http://www.openssl.org/source/openssl-0.9.8s.tar.gz</ulink></userinput> |
|
-</screen> |
|
- <para>Extract the tarball:</para> |
|
- <screen> |
|
-$ <userinput>tar zxf openssl-0.9.8s.tar.gz</userinput> |
|
+ Before building BIND 9 with PKCS#11 support, it will be |
|
+ necessary to build OpenSSL with the patch in place, and configure |
|
+ it with the path to your HSM's PKCS#11 provider library. |
|
+ </para> |
|
+ </sect3> |
|
+ <title>Patching OpenSSL</title> |
|
+ <screen> |
|
+$ <userinput>wget <ulink>http://www.openssl.org/source/openssl-0.9.8y.tar.gz</ulink></userinput> |
|
+ </screen> |
|
+ <para>Extract the tarball:</para> |
|
+ <screen> |
|
+$ <userinput>tar zxf openssl-0.9.8y.tar.gz</userinput> |
|
</screen> |
|
- <para>Apply the patch from the BIND 9 release:</para> |
|
- <screen> |
|
-$ <userinput>patch -p1 -d openssl-0.9.8s \ |
|
- < bind9/bin/pkcs11/openssl-0.9.8s-patch</userinput> |
|
+ <para>Apply the patch from the BIND 9 release:</para> |
|
+ <screen> |
|
+$ <userinput>patch -p1 -d openssl-0.9.8y \ |
|
+ < bind9/bin/pkcs11/openssl-0.9.8y-patch</userinput> |
|
</screen> |
|
- <note>(Note that the patch file may not be compatible with the |
|
- "patch" utility on all operating systems. You may need to |
|
- install GNU patch.)</note> |
|
- <para>When building OpenSSL, place it in a non-standard |
|
- location so that it does not interfere with OpenSSL libraries |
|
- elsewhere on the system. In the following examples, we choose |
|
- to install into "/opt/pkcs11/usr". We will use this location |
|
- when we configure BIND 9.</para> |
|
+ <note> |
|
+ Note that the patch file may not be compatible with the |
|
+ "patch" utility on all operating systems. You may need to |
|
+ install GNU patch. |
|
+ </note> |
|
+ <para> |
|
+ When building OpenSSL, place it in a non-standard |
|
+ location so that it does not interfere with OpenSSL libraries |
|
+ elsewhere on the system. In the following examples, we choose |
|
+ to install into "/opt/pkcs11/usr". We will use this location |
|
+ when we configure BIND 9. |
|
+ </para> |
|
+ <para> |
|
+ Later, when building BIND 9, the location of the custom-built |
|
+ OpenSSL library will need to be specified via configure. |
|
+ </para> |
|
+ </sect3> |
|
<sect3> |
|
<!-- Example 1 --> |
|
<title>Building OpenSSL for the AEP Keyper on Linux</title> |
|
- <para>The AEP Keyper is a highly secure key storage device, |
|
- but does not provide hardware cryptographic acceleration. It |
|
- can carry out cryptographic operations, but it is probably |
|
- slower than your system's CPU. Therefore, we choose the |
|
- 'sign-only' flavor when building OpenSSL.</para> |
|
- <para>The Keyper-specific PKCS #11 provider library is |
|
- delivered with the Keyper software. In this example, we place |
|
- it /opt/pkcs11/usr/lib:</para> |
|
+ <para> |
|
+ The AEP Keyper is a highly secure key storage device, |
|
+ but does not provide hardware cryptographic acceleration. It |
|
+ can carry out cryptographic operations, but it is probably |
|
+ slower than your system's CPU. Therefore, we choose the |
|
+ 'sign-only' flavor when building OpenSSL. |
|
+ </para> |
|
+ <para> |
|
+ The Keyper-specific PKCS#11 provider library is |
|
+ delivered with the Keyper software. In this example, we place |
|
+ it /opt/pkcs11/usr/lib: |
|
+ </para> |
|
<screen> |
|
$ <userinput>cp pkcs11.GCC4.0.2.so.4.05 /opt/pkcs11/usr/lib/libpkcs11.so</userinput> |
|
</screen> |
|
- <para>This library is only available for Linux as a 32-bit |
|
- binary. If we are compiling on a 64-bit Linux system, it is |
|
- necessary to force a 32-bit build, by specifying -m32 in the |
|
- build options.</para> |
|
- <para>Finally, the Keyper library requires threads, so we |
|
- must specify -pthread.</para> |
|
+ <para> |
|
+ This library is only available for Linux as a 32-bit |
|
+ binary. If we are compiling on a 64-bit Linux system, it is |
|
+ necessary to force a 32-bit build, by specifying -m32 in the |
|
+ build options. |
|
+ </para> |
|
+ <para> |
|
+ Finally, the Keyper library requires threads, so we |
|
+ must specify -pthread. |
|
+ </para> |
|
<screen> |
|
-$ <userinput>cd openssl-0.9.8s</userinput> |
|
+$ <userinput>cd openssl-0.9.8y</userinput> |
|
$ <userinput>./Configure linux-generic32 -m32 -pthread \ |
|
--pk11-libname=/opt/pkcs11/usr/lib/libpkcs11.so \ |
|
--pk11-flavor=sign-only \ |
|
--prefix=/opt/pkcs11/usr</userinput> |
|
</screen> |
|
- <para>After configuring, run "<command>make</command>" |
|
- and "<command>make test</command>". If "<command>make |
|
- test</command>" fails with "pthread_atfork() not found", you forgot to |
|
- add the -pthread above.</para> |
|
+ <para> |
|
+ After configuring, run "<command>make</command>" |
|
+ and "<command>make test</command>". If "<command>make |
|
+ test</command>" fails with "pthread_atfork() not found", you forgot to |
|
+ add the -pthread above. |
|
+ </para> |
|
</sect3> |
|
<sect3> |
|
<!-- Example 2 --> |
|
<title>Building OpenSSL for the SCA 6000 on Solaris</title> |
|
- <para>The SCA-6000 PKCS #11 provider is installed as a system |
|
- library, libpkcs11. It is a true crypto accelerator, up to 4 |
|
- times faster than any CPU, so the flavor shall be |
|
- 'crypto-accelerator'.</para> |
|
- <para>In this example, we are building on Solaris x86 on an |
|
- AMD64 system.</para> |
|
+ <para> |
|
+ The SCA-6000 PKCS#11 provider is installed as a system |
|
+ library, libpkcs11. It is a true crypto accelerator, up to 4 |
|
+ times faster than any CPU, so the flavor shall be |
|
+ 'crypto-accelerator'. |
|
+ </para> |
|
+ <para> |
|
+ In this example, we are building on Solaris x86 on an |
|
+ AMD64 system. |
|
+ </para> |
|
<screen> |
|
-$ <userinput>cd openssl-0.9.8s</userinput> |
|
+$ <userinput>cd openssl-0.9.8y</userinput> |
|
$ <userinput>./Configure solaris64-x86_64-cc \ |
|
--pk11-libname=/usr/lib/64/libpkcs11.so \ |
|
--pk11-flavor=crypto-accelerator \ |
|
--prefix=/opt/pkcs11/usr</userinput> |
|
</screen> |
|
- <para>(For a 32-bit build, use "solaris-x86-cc" and |
|
- /usr/lib/libpkcs11.so.)</para> |
|
- <para>After configuring, run |
|
- <command>make</command> and |
|
- <command>make test</command>.</para> |
|
+ <para> |
|
+ (For a 32-bit build, use "solaris-x86-cc" and /usr/lib/libpkcs11.so.) |
|
+ </para> |
|
+ <para> |
|
+ After configuring, run |
|
+ <command>make</command> and |
|
+ <command>make test</command>. |
|
+ </para> |
|
</sect3> |
|
<sect3> |
|
<!-- Example 3 --> |
|
<title>Building OpenSSL for SoftHSM</title> |
|
- <para>SoftHSM is a software library provided by the OpenDNSSEC |
|
- project (http://www.opendnssec.org) which provides a PKCS#11 |
|
- interface to a virtual HSM, implemented in the form of encrypted |
|
- data on the local filesystem. It uses the Botan library for |
|
- encryption and SQLite3 for data storage. Though less secure |
|
- than a true HSM, it can provide more secure key storage than |
|
- traditional key files, and can allow you to experiment with |
|
- PKCS#11 when an HSM is not available.</para> |
|
- <para>The SoftHSM cryptographic store must be installed and |
|
- initialized before using it with OpenSSL, and the SOFTHSM_CONF |
|
- environment variable must always point to the SoftHSM configuration |
|
- file:</para> |
|
+ <para> |
|
+ SoftHSM is a software library provided by the OpenDNSSEC |
|
+ project (http://www.opendnssec.org) which provides a PKCS#11 |
|
+ interface to a virtual HSM, implemented in the form of encrypted |
|
+ data on the local filesystem. SoftHSM can be configured to use |
|
+ either OpenSSL or the Botan library for encryption, and SQLite3 |
|
+ for data storage. Though less secure than a true HSM, it can |
|
+ provide more secure key storage than traditional key files, |
|
+ and can allow you to experiment with PKCS#11 when an HSM is |
|
+ not available. |
|
+ </para> |
|
+ <para> |
|
+ The SoftHSM cryptographic store must be installed and |
|
+ initialized before using it with OpenSSL, and the SOFTHSM_CONF |
|
+ environment variable must always point to the SoftHSM configuration |
|
+ file: |
|
+ </para> |
|
<screen> |
|
$ <userinput> cd softhsm-1.3.0 </userinput> |
|
$ <userinput> configure --prefix=/opt/pkcs11/usr </userinput> |
|
@@ -185,25 +282,31 @@ $ <userinput> export SOFTHSM_CONF=/opt/pkcs11/softhsm.conf </userinput> |
|
$ <userinput> echo "0:/opt/pkcs11/softhsm.db" > $SOFTHSM_CONF </userinput> |
|
$ <userinput> /opt/pkcs11/usr/bin/softhsm --init-token 0 --slot 0 --label softhsm </userinput> |
|
</screen> |
|
- <para>SoftHSM can perform all cryptographic operations, but |
|
- since it only uses your system CPU, there is no need to use it |
|
- for anything but signing. Therefore, we choose the 'sign-only' |
|
- flavor when building OpenSSL.</para> |
|
+ <para> |
|
+ SoftHSM can perform all cryptographic operations, but |
|
+ since it only uses your system CPU, there is no advantage to using |
|
+ it for anything but signing. Therefore, we choose the 'sign-only' |
|
+ flavor when building OpenSSL. |
|
+ </para> |
|
<screen> |
|
-$ <userinput>cd openssl-0.9.8s</userinput> |
|
+$ <userinput>cd openssl-0.9.8y</userinput> |
|
$ <userinput>./Configure linux-x86_64 -pthread \ |
|
- --pk11-libname=/opt/pkcs11/usr/lib/libpkcs11.so \ |
|
+ --pk11-libname=/opt/pkcs11/usr/lib/libsofthsm.so \ |
|
--pk11-flavor=sign-only \ |
|
--prefix=/opt/pkcs11/usr</userinput> |
|
</screen> |
|
- <para>After configuring, run "<command>make</command>" |
|
- and "<command>make test</command>".</para> |
|
+ <para> |
|
+ After configuring, run "<command>make</command>" |
|
+ and "<command>make test</command>". |
|
+ </para> |
|
</sect3> |
|
- <para>Once you have built OpenSSL, run |
|
- "<command>apps/openssl engine pkcs11</command>" to confirm |
|
- that PKCS #11 support was compiled in correctly. The output |
|
- should be one of the following lines, depending on the flavor |
|
- selected:</para> |
|
+ <para> |
|
+ Once you have built OpenSSL, run |
|
+ "<command>apps/openssl engine pkcs11</command>" to confirm |
|
+ that PKCS#11 support was compiled in correctly. The output |
|
+ should be one of the following lines, depending on the flavor |
|
+ selected: |
|
+ </para> |
|
<screen> |
|
(pkcs11) PKCS #11 engine support (sign only) |
|
</screen> |
|
@@ -211,29 +314,31 @@ $ <userinput>./Configure linux-x86_64 -pthread \ |
|
<screen> |
|
(pkcs11) PKCS #11 engine support (crypto accelerator) |
|
</screen> |
|
- <para>Next, run |
|
- "<command>apps/openssl engine pkcs11 -t</command>". This will |
|
- attempt to initialize the PKCS #11 engine. If it is able to |
|
- do so successfully, it will report |
|
- <quote><literal>[ available ]</literal></quote>.</para> |
|
- <para>If the output is correct, run |
|
- "<command>make install</command>" which will install the |
|
- modified OpenSSL suite to |
|
- <filename>/opt/pkcs11/usr</filename>.</para> |
|
- </sect2> |
|
- <sect2> |
|
- <title>Building BIND 9 with PKCS#11</title> |
|
- <para>When building BIND 9, the location of the custom-built |
|
- OpenSSL library must be specified via configure.</para> |
|
+ <para> |
|
+ Next, run |
|
+ "<command>apps/openssl engine pkcs11 -t</command>". This will |
|
+ attempt to initialize the PKCS#11 engine. If it is able to |
|
+ do so successfully, it will report |
|
+ <quote><literal>[ available ]</literal></quote>. |
|
+ </para> |
|
+ <para> |
|
+ If the output is correct, run |
|
+ "<command>make install</command>" which will install the |
|
+ modified OpenSSL suite to <filename>/opt/pkcs11/usr</filename>. |
|
+ </para> |
|
<sect3> |
|
<!-- Example 4 --> |
|
<title>Configuring BIND 9 for Linux with the AEP Keyper</title> |
|
- <para>To link with the PKCS #11 provider, threads must be |
|
- enabled in the BIND 9 build.</para> |
|
- <para>The PKCS #11 library for the AEP Keyper is currently |
|
- only available as a 32-bit binary. If we are building on a |
|
- 64-bit host, we must force a 32-bit build by adding "-m32" to |
|
- the CC options on the "configure" command line.</para> |
|
+ <para> |
|
+ To link with the PKCS#11 provider, threads must be |
|
+ enabled in the BIND 9 build. |
|
+ </para> |
|
+ <para> |
|
+ The PKCS#11 library for the AEP Keyper is currently |
|
+ only available as a 32-bit binary. If we are building on a |
|
+ 64-bit host, we must force a 32-bit build by adding "-m32" to |
|
+ the CC options on the "configure" command line. |
|
+ </para> |
|
<screen> |
|
$ <userinput>cd ../bind9</userinput> |
|
$ <userinput>./configure CC="gcc -m32" --enable-threads \ |
|
@@ -244,8 +349,10 @@ $ <userinput>./configure CC="gcc -m32" --enable-threads \ |
|
<sect3> |
|
<!-- Example 5 --> |
|
<title>Configuring BIND 9 for Solaris with the SCA 6000</title> |
|
- <para>To link with the PKCS #11 provider, threads must be |
|
- enabled in the BIND 9 build.</para> |
|
+ <para> |
|
+ To link with the PKCS#11 provider, threads must be |
|
+ enabled in the BIND 9 build. |
|
+ </para> |
|
<screen> |
|
$ <userinput>cd ../bind9</userinput> |
|
$ <userinput>./configure CC="cc -xarch=amd64" --enable-threads \ |
|
@@ -253,11 +360,13 @@ $ <userinput>./configure CC="cc -xarch=amd64" --enable-threads \ |
|
--with-pkcs11=/usr/lib/64/libpkcs11.so</userinput> |
|
</screen> |
|
<para>(For a 32-bit build, omit CC="cc -xarch=amd64".)</para> |
|
- <para>If configure complains about OpenSSL not working, you |
|
- may have a 32/64-bit architecture mismatch. Or, you may have |
|
- incorrectly specified the path to OpenSSL (it should be the |
|
- same as the --prefix argument to the OpenSSL |
|
- Configure).</para> |
|
+ <para> |
|
+ If configure complains about OpenSSL not working, you |
|
+ may have a 32/64-bit architecture mismatch. Or, you may have |
|
+ incorrectly specified the path to OpenSSL (it should be the |
|
+ same as the --prefix argument to the OpenSSL |
|
+ Configure). |
|
+ </para> |
|
</sect3> |
|
<sect3> |
|
<!-- Example 6 --> |
|
@@ -266,63 +375,85 @@ $ <userinput>./configure CC="cc -xarch=amd64" --enable-threads \ |
|
$ <userinput>cd ../bind9</userinput> |
|
$ <userinput>./configure --enable-threads \ |
|
--with-openssl=/opt/pkcs11/usr \ |
|
- --with-pkcs11=/opt/pkcs11/usr/lib/libpkcs11.so</userinput> |
|
+ --with-pkcs11=/opt/pkcs11/usr/lib/libsofthsm.so</userinput> |
|
</screen> |
|
</sect3> |
|
- <para>After configuring, run |
|
- "<command>make</command>", |
|
- "<command>make test</command>" and |
|
- "<command>make install</command>".</para> |
|
- <para>(Note: If "make test" fails in the "pkcs11" system test, you may |
|
- have forgotten to set the SOFTHSM_CONF environment variable.)</para> |
|
+ <para> |
|
+ After configuring, run |
|
+ "<command>make</command>", |
|
+ "<command>make test</command>" and |
|
+ "<command>make install</command>". |
|
+ </para> |
|
+ <para> |
|
+ (Note: If "make test" fails in the "pkcs11" system test, you may |
|
+ have forgotten to set the SOFTHSM_CONF environment variable.) |
|
+ </para> |
|
</sect2> |
|
<sect2> |
|
- <title>PKCS #11 Tools</title> |
|
- <para>BIND 9 includes a minimal set of tools to operate the |
|
- HSM, including |
|
- <command>pkcs11-keygen</command> to generate a new key pair |
|
- within the HSM, |
|
- <command>pkcs11-list</command> to list objects currently |
|
- available, and |
|
- <command>pkcs11-destroy</command> to remove objects.</para> |
|
- <para>In UNIX/Linux builds, these tools are built only if BIND |
|
- 9 is configured with the --with-pkcs11 option. (NOTE: If |
|
- --with-pkcs11 is set to "yes", rather than to the path of the |
|
- PKCS #11 provider, then the tools will be built but the |
|
- provider will be left undefined. Use the -m option or the |
|
- PKCS11_PROVIDER environment variable to specify the path to the |
|
- provider.)</para> |
|
+ <title>PKCS#11 Tools</title> |
|
+ <para> |
|
+ BIND 9 includes a minimal set of tools to operate the |
|
+ HSM, including |
|
+ <command>pkcs11-keygen</command> to generate a new key pair |
|
+ within the HSM, |
|
+ <command>pkcs11-list</command> to list objects currently |
|
+ available, |
|
+ <command>pkcs11-destroy</command> to remove objects, and |
|
+ <command>pkcs11-tokens</command> to list available tokens. |
|
+ </para> |
|
+ <para> |
|
+ In UNIX/Linux builds, these tools are built only if BIND |
|
+ 9 is configured with the --with-pkcs11 option. (Note: If |
|
+ --with-pkcs11 is set to "yes", rather than to the path of the |
|
+ PKCS#11 provider, then the tools will be built but the |
|
+ provider will be left undefined. Use the -m option or the |
|
+ PKCS11_PROVIDER environment variable to specify the path to the |
|
+ provider.) |
|
+ </para> |
|
</sect2> |
|
<sect2> |
|
<title>Using the HSM</title> |
|
- <para>First, we must set up the runtime environment so the |
|
- OpenSSL and PKCS #11 libraries can be loaded:</para> |
|
+ <para> |
|
+ For OpenSSL-based PKCS#11, we must first set up the runtime |
|
+ environment so the OpenSSL and PKCS#11 libraries can be loaded: |
|
+ </para> |
|
<screen> |
|
$ <userinput>export LD_LIBRARY_PATH=/opt/pkcs11/usr/lib:${LD_LIBRARY_PATH}</userinput> |
|
</screen> |
|
- <para>When operating an AEP Keyper, it is also necessary to |
|
- specify the location of the "machine" file, which stores |
|
- information about the Keyper for use by PKCS #11 provider |
|
- library. If the machine file is in |
|
- <filename>/opt/Keyper/PKCS11Provider/machine</filename>, |
|
- use:</para> |
|
+ <para> |
|
+ This causes <command>named</command> and other binaries to load |
|
+ the OpenSSL library from <filename>/opt/pkcs11/usr/lib</filename> |
|
+ rather than from the default location. This step is not necessary |
|
+ when using native PKCS#11. |
|
+ </para> |
|
+ <para> |
|
+ Some HSMs require other environment variables to be set. |
|
+ For example, when operating an AEP Keyper, it is necessary to |
|
+ specify the location of the "machine" file, which stores |
|
+ information about the Keyper for use by the provider |
|
+ library. If the machine file is in |
|
+ <filename>/opt/Keyper/PKCS11Provider/machine</filename>, |
|
+ use: |
|
+ </para> |
|
<screen> |
|
$ <userinput>export KEYPER_LIBRARY_PATH=/opt/Keyper/PKCS11Provider</userinput> |
|
</screen> |
|
- <!-- TODO: why not defined at compile time? --> |
|
- <para>These environment variables must be set whenever running |
|
- any tool that uses the HSM, including |
|
- <command>pkcs11-keygen</command>, |
|
- <command>pkcs11-list</command>, |
|
- <command>pkcs11-destroy</command>, |
|
- <command>dnssec-keyfromlabel</command>, |
|
- <command>dnssec-signzone</command>, |
|
- <command>dnssec-keygen</command>(which will use the HSM for |
|
- random number generation), and |
|
- <command>named</command>.</para> |
|
- <para>We can now create and use keys in the HSM. In this case, |
|
- we will create a 2048 bit key and give it the label |
|
- "sample-ksk":</para> |
|
+ <para> |
|
+ Such environment variables must be set whenever running |
|
+ any tool that uses the HSM, including |
|
+ <command>pkcs11-keygen</command>, |
|
+ <command>pkcs11-list</command>, |
|
+ <command>pkcs11-destroy</command>, |
|
+ <command>dnssec-keyfromlabel</command>, |
|
+ <command>dnssec-signzone</command>, |
|
+ <command>dnssec-keygen</command>, and |
|
+ <command>named</command>. |
|
+ </para> |
|
+ <para> |
|
+ We can now create and use keys in the HSM. In this case, |
|
+ we will create a 2048 bit key and give it the label |
|
+ "sample-ksk": |
|
+ </para> |
|
<screen> |
|
$ <userinput>pkcs11-keygen -b 2048 -l sample-ksk</userinput> |
|
</screen> |
|
@@ -333,44 +464,56 @@ Enter PIN: |
|
object[0]: handle 2147483658 class 3 label[8] 'sample-ksk' id[0] |
|
object[1]: handle 2147483657 class 2 label[8] 'sample-ksk' id[0] |
|
</screen> |
|
- <para>Before using this key to sign a zone, we must create a |
|
- pair of BIND 9 key files. The "dnssec-keyfromlabel" utility |
|
- does this. In this case, we will be using the HSM key |
|
- "sample-ksk" as the key-signing key for "example.net":</para> |
|
+ <para> |
|
+ Before using this key to sign a zone, we must create a |
|
+ pair of BIND 9 key files. The "dnssec-keyfromlabel" utility |
|
+ does this. In this case, we will be using the HSM key |
|
+ "sample-ksk" as the key-signing key for "example.net": |
|
+ </para> |
|
<screen> |
|
$ <userinput>dnssec-keyfromlabel -l sample-ksk -f KSK example.net</userinput> |
|
</screen> |
|
- <para>The resulting K*.key and K*.private files can now be used |
|
- to sign the zone. Unlike normal K* files, which contain both |
|
- public and private key data, these files will contain only the |
|
- public key data, plus an identifier for the private key which |
|
- remains stored within the HSM. The HSM handles signing with the |
|
- private key.</para> |
|
- <para>If you wish to generate a second key in the HSM for use |
|
- as a zone-signing key, follow the same procedure above, using a |
|
- different keylabel, a smaller key size, and omitting "-f KSK" |
|
- from the dnssec-keyfromlabel arguments:</para> |
|
+ <para> |
|
+ The resulting K*.key and K*.private files can now be used |
|
+ to sign the zone. Unlike normal K* files, which contain both |
|
+ public and private key data, these files will contain only the |
|
+ public key data, plus an identifier for the private key which |
|
+ remains stored within the HSM. Signing with the private key takes |
|
+ place inside the HSM. |
|
+ </para> |
|
+ <para> |
|
+ If you wish to generate a second key in the HSM for use |
|
+ as a zone-signing key, follow the same procedure above, using a |
|
+ different keylabel, a smaller key size, and omitting "-f KSK" |
|
+ from the dnssec-keyfromlabel arguments: |
|
+ </para> |
|
<screen> |
|
$ <userinput>pkcs11-keygen -b 1024 -l sample-zsk</userinput> |
|
$ <userinput>dnssec-keyfromlabel -l sample-zsk example.net</userinput> |
|
</screen> |
|
- <para>Alternatively, you may prefer to generate a conventional |
|
- on-disk key, using dnssec-keygen:</para> |
|
+ <para> |
|
+ Alternatively, you may prefer to generate a conventional |
|
+ on-disk key, using dnssec-keygen: |
|
+ </para> |
|
<screen> |
|
$ <userinput>dnssec-keygen example.net</userinput> |
|
</screen> |
|
- <para>This provides less security than an HSM key, but since |
|
- HSMs can be slow or cumbersome to use for security reasons, it |
|
- may be more efficient to reserve HSM keys for use in the less |
|
- frequent key-signing operation. The zone-signing key can be |
|
- rolled more frequently, if you wish, to compensate for a |
|
- reduction in key security.</para> |
|
- <para>Now you can sign the zone. (Note: If not using the -S |
|
- option to |
|
- <command>dnssec-signzone</command>, it will be necessary to add |
|
- the contents of both |
|
- <filename>K*.key</filename> files to the zone master file before |
|
- signing it.)</para> |
|
+ <para> |
|
+ This provides less security than an HSM key, but since |
|
+ HSMs can be slow or cumbersome to use for security reasons, it |
|
+ may be more efficient to reserve HSM keys for use in the less |
|
+ frequent key-signing operation. The zone-signing key can be |
|
+ rolled more frequently, if you wish, to compensate for a |
|
+ reduction in key security. (Note: When using native PKCS#11, |
|
+ there is no speed advantage to using on-disk keys, as cryptographic |
|
+ operations will be done by the HSM regardless.) |
|
+ </para> |
|
+ <para> |
|
+ Now you can sign the zone. (Note: If not using the -S |
|
+ option to <command>dnssec-signzone</command>, it will be |
|
+ necessary to add the contents of both <filename>K*.key</filename> |
|
+ files to the zone master file before signing it.) |
|
+ </para> |
|
<screen> |
|
$ <userinput>dnssec-signzone -S example.net</userinput> |
|
Enter PIN: |
|
@@ -383,36 +526,50 @@ example.net.signed |
|
</sect2> |
|
<sect2> |
|
<title>Specifying the engine on the command line</title> |
|
- <para>The OpenSSL engine can be specified in |
|
- <command>named</command> and all of the BIND |
|
- <command>dnssec-*</command> tools by using the "-E |
|
- <engine>" command line option. If BIND 9 is built with |
|
- the --with-pkcs11 option, this option defaults to "pkcs11". |
|
- Specifying the engine will generally not be necessary unless |
|
- for some reason you wish to use a different OpenSSL |
|
- engine.</para> |
|
- <para>If you wish to disable use of the "pkcs11" engine — |
|
- for troubleshooting purposes, or because the HSM is unavailable |
|
- — set the engine to the empty string. For example:</para> |
|
+ <para> |
|
+ When using OpenSSL-based PKCS#11, the "engine" to be used by |
|
+ OpenSSL can be specified in <command>named</command> and all of |
|
+ the BIND <command>dnssec-*</command> tools by using the "-E |
|
+ <engine>" command line option. If BIND 9 is built with |
|
+ the --with-pkcs11 option, this option defaults to "pkcs11". |
|
+ Specifying the engine will generally not be necessary unless |
|
+ for some reason you wish to use a different OpenSSL |
|
+ engine. |
|
+ </para> |
|
+ <para> |
|
+ If you wish to disable use of the "pkcs11" engine — |
|
+ for troubleshooting purposes, or because the HSM is unavailable |
|
+ — set the engine to the empty string. For example: |
|
+ </para> |
|
<screen> |
|
$ <userinput>dnssec-signzone -E '' -S example.net</userinput> |
|
</screen> |
|
- <para>This causes |
|
- <command>dnssec-signzone</command> to run as if it were compiled |
|
- without the --with-pkcs11 option.</para> |
|
+ <para> |
|
+ This causes |
|
+ <command>dnssec-signzone</command> to run as if it were compiled |
|
+ without the --with-pkcs11 option. |
|
+ </para> |
|
+ <para> |
|
+ When built with native PKCS#11 mode, the "engine" option has a |
|
+ different meaning: it specifies the path to the PKCS#11 provider |
|
+ library. This may be useful when testing a new provider library. |
|
+ </para> |
|
</sect2> |
|
<sect2> |
|
<title>Running named with automatic zone re-signing</title> |
|
- <para>If you want |
|
- <command>named</command> to dynamically re-sign zones using HSM |
|
- keys, and/or to to sign new records inserted via nsupdate, then |
|
- named must have access to the HSM PIN. This can be accomplished |
|
- by placing the PIN into the openssl.cnf file (in the above |
|
- examples, |
|
- <filename>/opt/pkcs11/usr/ssl/openssl.cnf</filename>).</para> |
|
- <para>The location of the openssl.cnf file can be overridden by |
|
- setting the OPENSSL_CONF environment variable before running |
|
- named.</para> |
|
+ <para> |
|
+ If you want <command>named</command> to dynamically re-sign zones |
|
+ using HSM keys, and/or to to sign new records inserted via nsupdate, |
|
+ then named must have access to the HSM PIN. In OpenSSL-based PKCS#11, |
|
+ this is accomplished by placing the PIN into the openssl.cnf file |
|
+ (in the above examples, |
|
+ <filename>/opt/pkcs11/usr/ssl/openssl.cnf</filename>). |
|
+ </para> |
|
+ <para> |
|
+ The location of the openssl.cnf file can be overridden by |
|
+ setting the OPENSSL_CONF environment variable before running |
|
+ named. |
|
+ </para> |
|
<para>Sample openssl.cnf:</para> |
|
<programlisting> |
|
openssl_conf = openssl_def |
|
@@ -423,22 +580,25 @@ $ <userinput>dnssec-signzone -E '' -S example.net</userinput> |
|
[ pkcs11_section ] |
|
PIN = <replaceable><PLACE PIN HERE></replaceable> |
|
</programlisting> |
|
- <para>This will also allow the dnssec-* tools to access the HSM |
|
- without PIN entry. (The pkcs11-* tools access the HSM directly, |
|
- not via OpenSSL, so a PIN will still be required to use |
|
- them.)</para> |
|
-<!-- |
|
-If the PIN is not known, I believe the first time named needs the |
|
-PIN to open a key, it'll ask you to type in the PIN, which will be |
|
-a problem because it probably won't be running on a terminal |
|
---> |
|
+ <para> |
|
+ This will also allow the dnssec-* tools to access the HSM |
|
+ without PIN entry. (The pkcs11-* tools access the HSM directly, |
|
+ not via OpenSSL, so a PIN will still be required to use |
|
+ them.) |
|
+ </para> |
|
+ <para> |
|
+ In native PKCS#11 mode, the PIN can be provided in a file specified |
|
+ as an attribute of the key's label. For example, if a key had the label |
|
+ <userinput>pkcs11:object=local-zsk;pin-source=/etc/hsmpin"</userinput>, |
|
+ then the PIN would be read from the file |
|
+ <filename>/etc/hsmpin</filename>. |
|
+ </para> |
|
<warning> |
|
- <para>Placing the HSM's PIN in a text file in |
|
- this manner may reduce the security advantage of using an |
|
- HSM. Be sure this is what you want to do before configuring |
|
- OpenSSL in this way.</para> |
|
+ <para> |
|
+ Placing the HSM's PIN in a text file in this manner may reduce the |
|
+ security advantage of using an HSM. Be sure this is what you want to |
|
+ do before configuring OpenSSL in this way. |
|
+ </para> |
|
</warning> |
|
</sect2> |
|
- <!-- TODO: what is alternative then for named dynamic re-signing? --> |
|
- <!-- TODO: what happens if PIN is not known? named will log about it? --> |
|
</sect1> |
|
diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in |
|
index 0c5e93b..41fac95 100644 |
|
--- a/lib/dns/Makefile.in |
|
+++ b/lib/dns/Makefile.in |
|
@@ -27,10 +27,10 @@ top_srcdir = @top_srcdir@ |
|
|
|
USE_ISC_SPNEGO = @USE_ISC_SPNEGO@ |
|
|
|
-CINCLUDES = -I. -Iinclude ${DNS_INCLUDES} \ |
|
- ${ISC_INCLUDES} @DST_OPENSSL_INC@ @DST_GSSAPI_INC@ |
|
+CINCLUDES = -I. -I${top_srcdir}/lib/dns -Iinclude ${DNS_INCLUDES} ${ISC_INCLUDES} \ |
|
+ @DST_OPENSSL_INC@ @DST_GSSAPI_INC@ |
|
|
|
-CDEFINES = -DUSE_MD5 @USE_OPENSSL@ @USE_GSSAPI@ ${USE_ISC_SPNEGO} |
|
+CDEFINES = -DUSE_MD5 @CRYPTO@ @USE_GSSAPI@ ${USE_ISC_SPNEGO} |
|
|
|
CWARNINGS = |
|
|
|
@@ -47,7 +47,10 @@ OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \ |
|
opensslecdsa_link.@O@ @OPENSSLGOSTLINKOBJS@ \ |
|
opensslrsa_link.@O@ |
|
|
|
-DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \ |
|
+PKCS11LINKOBJS = pkcs11dh_link.@O@ pkcs11dsa_link.@O@ pkcs11rsa_link.@O@ \ |
|
+ pkcs11ecdsa_link.@O@ pkcs11gost_link.@O@ pkcs11.@O@ |
|
+ |
|
+DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ @PKCS11LINKOBJS@ \ |
|
dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \ |
|
gssapi_link.@O@ gssapictx.@O@ hmac_link.@O@ key.@O@ |
|
|
|
@@ -79,7 +82,10 @@ OPENSSLGOSTLINKSRCS = opensslgost_link.c |
|
OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \ |
|
opensslecdsa_link.c @OPENSSLGOSTLINKSRCS@ opensslrsa_link.c |
|
|
|
-DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \ |
|
+PKCS11LINKSRCS = pkcs11dh_link.c pkcs11dsa_link.c pkcs11rsa_link.c \ |
|
+ pkcs11ecdsa_link.c pkcs11gost_link.c pkcs11.c |
|
+ |
|
+DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ @PKCS11LINKSRCS@ \ |
|
dst_api.c dst_lib.c dst_parse.c \ |
|
dst_result.c gssapi_link.c gssapictx.c \ |
|
hmac_link.c key.c |
|
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c |
|
index cf97404..00a0080 100644 |
|
--- a/lib/dns/dnssec.c |
|
+++ b/lib/dns/dnssec.c |
|
@@ -275,7 +275,8 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, |
|
if (ret != ISC_R_SUCCESS) |
|
goto cleanup_databuf; |
|
|
|
- ret = dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx); |
|
+ ret = dst_context_create3(key, mctx, |
|
+ DNS_LOGCATEGORY_DNSSEC, ISC_TRUE, &ctx); |
|
if (ret != ISC_R_SUCCESS) |
|
goto cleanup_databuf; |
|
|
|
@@ -470,7 +471,8 @@ dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key, |
|
} |
|
|
|
again: |
|
- ret = dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx); |
|
+ ret = dst_context_create4(key, mctx, DNS_LOGCATEGORY_DNSSEC, |
|
+ ISC_FALSE, maxbits, &ctx); |
|
if (ret != ISC_R_SUCCESS) |
|
goto cleanup_struct; |
|
|
|
@@ -872,7 +874,8 @@ dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key) { |
|
|
|
isc_buffer_init(&databuf, data, sizeof(data)); |
|
|
|
- RETERR(dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx)); |
|
+ RETERR(dst_context_create3(key, mctx, |
|
+ DNS_LOGCATEGORY_DNSSEC, ISC_TRUE, &ctx)); |
|
|
|
/* |
|
* Digest the fields of the SIG - we can cheat and use |
|
@@ -1022,7 +1025,8 @@ dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg, |
|
goto failure; |
|
} |
|
|
|
- RETERR(dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx)); |
|
+ RETERR(dst_context_create3(key, mctx, |
|
+ DNS_LOGCATEGORY_DNSSEC, ISC_FALSE, &ctx)); |
|
|
|
/* |
|
* Digest the SIG(0) record, except for the signature. |
|
diff --git a/lib/dns/ds.c b/lib/dns/ds.c |
|
index e72ecbb..b51476b 100644 |
|
--- a/lib/dns/ds.c |
|
+++ b/lib/dns/ds.c |
|
@@ -38,11 +38,8 @@ |
|
|
|
#include <dst/dst.h> |
|
|
|
-#ifdef HAVE_OPENSSL_GOST |
|
-#include <dst/result.h> |
|
-#include <openssl/evp.h> |
|
- |
|
-extern const EVP_MD * EVP_gost(void); |
|
+#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) |
|
+#include "dst_gost.h" |
|
#endif |
|
|
|
isc_result_t |
|
@@ -59,9 +56,8 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, |
|
isc_sha1_t sha1; |
|
isc_sha256_t sha256; |
|
isc_sha384_t sha384; |
|
-#ifdef HAVE_OPENSSL_GOST |
|
- EVP_MD_CTX ctx; |
|
- const EVP_MD *md; |
|
+#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) |
|
+ isc_gost_t gost; |
|
#endif |
|
|
|
REQUIRE(key != NULL); |
|
@@ -88,29 +84,23 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, |
|
isc_sha1_final(&sha1, digest); |
|
break; |
|
|
|
-#ifdef HAVE_OPENSSL_GOST |
|
-#define CHECK(x) \ |
|
- if ((x) != 1) { \ |
|
- EVP_MD_CTX_cleanup(&ctx); \ |
|
- return (DST_R_CRYPTOFAILURE); \ |
|
- } |
|
+#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) |
|
+#define RETERR(x) do { \ |
|
+ isc_result_t ret = (x); \ |
|
+ if (ret != ISC_R_SUCCESS) { \ |
|
+ isc_gost_invalidate(&gost); \ |
|
+ return (ret); \ |
|
+ } \ |
|
+} while (0) |
|
|
|
case DNS_DSDIGEST_GOST: |
|
- md = EVP_gost(); |
|
- if (md == NULL) |
|
- return (DST_R_CRYPTOFAILURE); |
|
- EVP_MD_CTX_init(&ctx); |
|
- CHECK(EVP_DigestInit(&ctx, md)); |
|
+ RETERR(isc_gost_init(&gost)); |
|
dns_name_toregion(name, &r); |
|
- CHECK(EVP_DigestUpdate(&ctx, |
|
- (const void *) r.base, |
|
- (size_t) r.length)); |
|
+ RETERR(isc_gost_update(&gost, r.base, r.length)); |
|
dns_rdata_toregion(key, &r); |
|
INSIST(r.length >= 4); |
|
- CHECK(EVP_DigestUpdate(&ctx, |
|
- (const void *) r.base, |
|
- (size_t) r.length)); |
|
- CHECK(EVP_DigestFinal(&ctx, digest, NULL)); |
|
+ RETERR(isc_gost_update(&gost, r.base, r.length)); |
|
+ RETERR(isc_gost_final(&gost, digest)); |
|
break; |
|
#endif |
|
|
|
@@ -147,7 +137,7 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, |
|
ds.length = ISC_SHA1_DIGESTLENGTH; |
|
break; |
|
|
|
-#ifdef HAVE_OPENSSL_GOST |
|
+#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) |
|
case DNS_DSDIGEST_GOST: |
|
ds.length = ISC_GOST_DIGESTLENGTH; |
|
break; |
|
diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c |
|
index 6416273..d96473f 100644 |
|
--- a/lib/dns/dst_api.c |
|
+++ b/lib/dns/dst_api.c |
|
@@ -75,9 +75,7 @@ |
|
#define DST_AS_STR(t) ((t).value.as_textregion.base) |
|
|
|
static dst_func_t *dst_t_func[DST_MAX_ALGS]; |
|
-#ifdef BIND9 |
|
static isc_entropy_t *dst_entropy_pool = NULL; |
|
-#endif |
|
static unsigned int dst_entropy_flags = 0; |
|
static isc_boolean_t dst_initialized = ISC_FALSE; |
|
|
|
@@ -169,7 +167,7 @@ dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, |
|
#endif |
|
REQUIRE(dst_initialized == ISC_FALSE); |
|
|
|
-#ifndef OPENSSL |
|
+#if !defined(OPENSSL) && !defined(PKCS11CRYPTO) |
|
UNUSED(engine); |
|
#endif |
|
|
|
@@ -234,7 +232,24 @@ dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, |
|
RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA256])); |
|
RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA384])); |
|
#endif |
|
-#endif /* OPENSSL */ |
|
+#elif PKCS11CRYPTO |
|
+ RETERR(dst__pkcs11_init(mctx, engine)); |
|
+ RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSAMD5])); |
|
+ RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA1])); |
|
+ RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1])); |
|
+ RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA256])); |
|
+ RETERR(dst__pkcs11rsa_init(&dst_t_func[DST_ALG_RSASHA512])); |
|
+ RETERR(dst__pkcs11dsa_init(&dst_t_func[DST_ALG_DSA])); |
|
+ RETERR(dst__pkcs11dsa_init(&dst_t_func[DST_ALG_NSEC3DSA])); |
|
+ RETERR(dst__pkcs11dh_init(&dst_t_func[DST_ALG_DH])); |
|
+#ifdef HAVE_PKCS11_ECDSA |
|
+ RETERR(dst__pkcs11ecdsa_init(&dst_t_func[DST_ALG_ECDSA256])); |
|
+ RETERR(dst__pkcs11ecdsa_init(&dst_t_func[DST_ALG_ECDSA384])); |
|
+#endif |
|
+#ifdef HAVE_PKCS11_GOST |
|
+ RETERR(dst__pkcs11gost_init(&dst_t_func[DST_ALG_ECCGOST])); |
|
+#endif |
|
+#endif /* if OPENSSL, elif PKCS11CRYPTO */ |
|
#ifdef GSSAPI |
|
RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI])); |
|
#endif |
|
@@ -259,7 +274,9 @@ dst_lib_destroy(void) { |
|
dst_t_func[i]->cleanup(); |
|
#ifdef OPENSSL |
|
dst__openssl_destroy(); |
|
-#endif |
|
+#elif PKCS11CRYPTO |
|
+ (void) dst__pkcs11_destroy(); |
|
+#endif /* if OPENSSL, elif PKCS11CRYPTO */ |
|
if (dst__memory_pool != NULL) |
|
isc_mem_detach(&dst__memory_pool); |
|
#ifdef BIND9 |
|
@@ -279,13 +296,31 @@ dst_algorithm_supported(unsigned int alg) { |
|
|
|
isc_result_t |
|
dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) { |
|
- return (dst_context_create2(key, mctx, |
|
- DNS_LOGCATEGORY_GENERAL, dctxp)); |
|
+ return (dst_context_create4(key, mctx, DNS_LOGCATEGORY_GENERAL, |
|
+ ISC_TRUE, 0, dctxp)); |
|
} |
|
|
|
isc_result_t |
|
dst_context_create2(dst_key_t *key, isc_mem_t *mctx, |
|
- isc_logcategory_t *category, dst_context_t **dctxp) { |
|
+ isc_logcategory_t *category, dst_context_t **dctxp) |
|
+{ |
|
+ return (dst_context_create4(key, mctx, category, ISC_TRUE, 0, dctxp)); |
|
+} |
|
+ |
|
+isc_result_t |
|
+dst_context_create3(dst_key_t *key, isc_mem_t *mctx, |
|
+ isc_logcategory_t *category, isc_boolean_t useforsigning, |
|
+ dst_context_t **dctxp) |
|
+{ |
|
+ return (dst_context_create4(key, mctx, category, |
|
+ useforsigning, 0, dctxp)); |
|
+} |
|
+ |
|
+isc_result_t |
|
+dst_context_create4(dst_key_t *key, isc_mem_t *mctx, |
|
+ isc_logcategory_t *category, isc_boolean_t useforsigning, |
|
+ int maxbits, dst_context_t **dctxp) |
|
+{ |
|
dst_context_t *dctx; |
|
isc_result_t result; |
|
|
|
@@ -294,7 +329,7 @@ dst_context_create2(dst_key_t *key, isc_mem_t *mctx, |
|
REQUIRE(mctx != NULL); |
|
REQUIRE(dctxp != NULL && *dctxp == NULL); |
|
|
|
- if (key->func->createctx == NULL) |
|
+ if (key->func->createctx == NULL && key->func->createctx2 == NULL) |
|
return (DST_R_UNSUPPORTEDALG); |
|
if (key->keydata.generic == NULL) |
|
return (DST_R_NULLKEY); |
|
@@ -305,7 +340,14 @@ dst_context_create2(dst_key_t *key, isc_mem_t *mctx, |
|
dctx->key = key; |
|
dctx->mctx = mctx; |
|
dctx->category = category; |
|
- result = key->func->createctx(key, dctx); |
|
+ if (useforsigning) |
|
+ dctx->use = DO_SIGN; |
|
+ else |
|
+ dctx->use = DO_VERIFY; |
|
+ if (key->func->createctx2 != NULL) |
|
+ result = key->func->createctx2(key, maxbits, dctx); |
|
+ else |
|
+ result = key->func->createctx(key, dctx); |
|
if (result != ISC_R_SUCCESS) { |
|
isc_mem_put(mctx, dctx, sizeof(dst_context_t)); |
|
return (result); |
|
@@ -1796,7 +1838,7 @@ algorithm_status(unsigned int alg) { |
|
|
|
if (dst_algorithm_supported(alg)) |
|
return (ISC_R_SUCCESS); |
|
-#ifndef OPENSSL |
|
+#if !defined(OPENSSL) && !defined(PKCS11CRYPTO) |
|
if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 || |
|
alg == DST_ALG_DSA || alg == DST_ALG_DH || |
|
alg == DST_ALG_HMACMD5 || alg == DST_ALG_NSEC3DSA || |
|
@@ -1842,11 +1884,18 @@ dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) { |
|
|
|
if (len == 0) |
|
return (ISC_R_SUCCESS); |
|
+ |
|
+#ifdef PKCS11CRYPTO |
|
+ UNUSED(pseudo); |
|
+ UNUSED(flags); |
|
+ return (pk11_rand_bytes(buf, len)); |
|
+#else /* PKCS11CRYPTO */ |
|
if (pseudo) |
|
flags &= ~ISC_ENTROPY_GOODONLY; |
|
else |
|
flags |= ISC_ENTROPY_BLOCKING; |
|
return (isc_entropy_getdata(dst_entropy_pool, buf, len, NULL, flags)); |
|
+#endif /* PKCS11CRYPTO */ |
|
#else |
|
UNUSED(buf); |
|
UNUSED(len); |
|
@@ -1858,7 +1907,7 @@ dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) { |
|
|
|
unsigned int |
|
dst__entropy_status(void) { |
|
-#ifdef BIND9 |
|
+#ifndef PKCS11CRYPTO |
|
#ifdef GSSAPI |
|
unsigned int flags = dst_entropy_flags; |
|
isc_result_t ret; |
|
diff --git a/lib/dns/dst_gost.h b/lib/dns/dst_gost.h |
|
new file mode 100644 |
|
index 0000000..37a4200 |
|
--- /dev/null |
|
+++ b/lib/dns/dst_gost.h |
|
@@ -0,0 +1,57 @@ |
|
+/* |
|
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+#ifndef DST_GOST_H |
|
+#define DST_GOST_H 1 |
|
+ |
|
+#include <isc/lang.h> |
|
+#include <isc/log.h> |
|
+#include <dst/result.h> |
|
+ |
|
+#define ISC_GOST_DIGESTLENGTH 32U |
|
+ |
|
+#ifdef HAVE_OPENSSL_GOST |
|
+#include <openssl/evp.h> |
|
+ |
|
+typedef EVP_MD_CTX isc_gost_t; |
|
+#endif |
|
+#ifdef HAVE_PKCS11_GOST |
|
+#include <pk11/pk11.h> |
|
+ |
|
+typedef pk11_context_t isc_gost_t; |
|
+#endif |
|
+ |
|
+ISC_LANG_BEGINDECLS |
|
+ |
|
+#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) |
|
+ |
|
+isc_result_t |
|
+isc_gost_init(isc_gost_t *ctx); |
|
+ |
|
+void |
|
+isc_gost_invalidate(isc_gost_t *ctx); |
|
+ |
|
+isc_result_t |
|
+isc_gost_update(isc_gost_t *ctx, const unsigned char *data, unsigned int len); |
|
+ |
|
+isc_result_t |
|
+isc_gost_final(isc_gost_t *ctx, unsigned char *digest); |
|
+ |
|
+ISC_LANG_ENDDECLS |
|
+ |
|
+#endif /* HAVE_OPENSSL_GOST || HAVE_PKCS11_GOST */ |
|
+ |
|
+#endif /* DST_GOST_H */ |
|
diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h |
|
index 49ca424..b15135e 100644 |
|
--- a/lib/dns/dst_internal.h |
|
+++ b/lib/dns/dst_internal.h |
|
@@ -84,6 +84,12 @@ typedef struct dst_hmacsha256_key dst_hmacsha256_key_t; |
|
typedef struct dst_hmacsha384_key dst_hmacsha384_key_t; |
|
typedef struct dst_hmacsha512_key dst_hmacsha512_key_t; |
|
|
|
+/*% |
|
+ * Indicate whether a DST context will be used for signing |
|
+ * or for verification |
|
+ */ |
|
+typedef enum { DO_SIGN, DO_VERIFY } dst_use_t; |
|
+ |
|
/*% DST Key Structure */ |
|
struct dst_key { |
|
unsigned int magic; |
|
@@ -112,6 +118,8 @@ struct dst_key { |
|
DSA *dsa; |
|
DH *dh; |
|
EVP_PKEY *pkey; |
|
+#elif PKCS11CRYPTO |
|
+ pk11_object_t *pkey; |
|
#endif |
|
dst_hmacmd5_key_t *hmacmd5; |
|
dst_hmacsha1_key_t *hmacsha1; |
|
@@ -139,6 +147,7 @@ struct dst_key { |
|
|
|
struct dst_context { |
|
unsigned int magic; |
|
+ dst_use_t use; |
|
dst_key_t *key; |
|
isc_mem_t *mctx; |
|
isc_logcategory_t *category; |
|
@@ -157,6 +166,8 @@ struct dst_context { |
|
isc_hmacsha512_t *hmacsha512ctx; |
|
#ifdef OPENSSL |
|
EVP_MD_CTX *evp_md_ctx; |
|
+#elif PKCS11CRYPTO |
|
+ pk11_context_t *pk11_ctx; |
|
#endif |
|
} ctxdata; |
|
}; |
|
@@ -166,6 +177,8 @@ struct dst_func { |
|
* Context functions |
|
*/ |
|
isc_result_t (*createctx)(dst_key_t *key, dst_context_t *dctx); |
|
+ isc_result_t (*createctx2)(dst_key_t *key, int maxbits, |
|
+ dst_context_t *dctx); |
|
void (*destroyctx)(dst_context_t *dctx); |
|
isc_result_t (*adddata)(dst_context_t *dctx, const isc_region_t *data); |
|
|
|
@@ -209,6 +222,7 @@ struct dst_func { |
|
* Initializers |
|
*/ |
|
isc_result_t dst__openssl_init(const char *engine); |
|
+#define dst__pkcs11_init pk11_initialize |
|
|
|
isc_result_t dst__hmacmd5_init(struct dst_func **funcp); |
|
isc_result_t dst__hmacsha1_init(struct dst_func **funcp); |
|
@@ -218,20 +232,30 @@ isc_result_t dst__hmacsha384_init(struct dst_func **funcp); |
|
isc_result_t dst__hmacsha512_init(struct dst_func **funcp); |
|
isc_result_t dst__opensslrsa_init(struct dst_func **funcp, |
|
unsigned char algorithm); |
|
+isc_result_t dst__pkcs11rsa_init(struct dst_func **funcp); |
|
isc_result_t dst__openssldsa_init(struct dst_func **funcp); |
|
+isc_result_t dst__pkcs11dsa_init(struct dst_func **funcp); |
|
isc_result_t dst__openssldh_init(struct dst_func **funcp); |
|
+isc_result_t dst__pkcs11dh_init(struct dst_func **funcp); |
|
isc_result_t dst__gssapi_init(struct dst_func **funcp); |
|
+#ifdef HAVE_OPENSSL_ECDSA |
|
+isc_result_t dst__opensslecdsa_init(struct dst_func **funcp); |
|
+#endif |
|
+#ifdef HAVE_PKCS11_ECDSA |
|
+isc_result_t dst__pkcs11ecdsa_init(struct dst_func **funcp); |
|
+#endif |
|
#ifdef HAVE_OPENSSL_GOST |
|
isc_result_t dst__opensslgost_init(struct dst_func **funcp); |
|
#endif |
|
-#ifdef HAVE_OPENSSL_ECDSA |
|
-isc_result_t dst__opensslecdsa_init(struct dst_func **funcp); |
|
+#ifdef HAVE_PKCS11_GOST |
|
+isc_result_t dst__pkcs11gost_init(struct dst_func **funcp); |
|
#endif |
|
|
|
/*% |
|
* Destructors |
|
*/ |
|
void dst__openssl_destroy(void); |
|
+#define dst__pkcs11_destroy pk11_finalize |
|
|
|
/*% |
|
* Memory allocators using the DST memory pool. |
|
diff --git a/lib/dns/dst_parse.c b/lib/dns/dst_parse.c |
|
index 6348cc1..ec622d9 100644 |
|
--- a/lib/dns/dst_parse.c |
|
+++ b/lib/dns/dst_parse.c |
|
@@ -93,7 +93,6 @@ static struct parse_map map[] = { |
|
{TAG_RSA_COEFFICIENT, "Coefficient:"}, |
|
{TAG_RSA_ENGINE, "Engine:" }, |
|
{TAG_RSA_LABEL, "Label:" }, |
|
- {TAG_RSA_PIN, "PIN:" }, |
|
|
|
{TAG_DH_PRIME, "Prime(p):"}, |
|
{TAG_DH_GENERATOR, "Generator(g):"}, |
|
@@ -107,8 +106,11 @@ static struct parse_map map[] = { |
|
{TAG_DSA_PUBLIC, "Public_value(y):"}, |
|
|
|
{TAG_GOST_PRIVASN1, "GostAsn1:"}, |
|
+ {TAG_GOST_PRIVRAW, "PrivateKey:"}, |
|
|
|
{TAG_ECDSA_PRIVATEKEY, "PrivateKey:"}, |
|
+ {TAG_ECDSA_ENGINE, "Engine:" }, |
|
+ {TAG_ECDSA_LABEL, "Label:" }, |
|
|
|
{TAG_HMACMD5_KEY, "Key:"}, |
|
{TAG_HMACMD5_BITS, "Bits:"}, |
|
@@ -262,22 +264,42 @@ check_gost(const dst_private_t *priv, isc_boolean_t external) { |
|
|
|
if (priv->nelements != GOST_NTAGS) |
|
return (-1); |
|
- if (priv->elements[0].tag != TAG(DST_ALG_ECCGOST, 0)) |
|
+ if ((priv->elements[0].tag != TAG(DST_ALG_ECCGOST, 0)) && |
|
+ (priv->elements[0].tag != TAG(DST_ALG_ECCGOST, 1))) |
|
return (-1); |
|
return (0); |
|
} |
|
|
|
static int |
|
check_ecdsa(const dst_private_t *priv, isc_boolean_t external) { |
|
+ int i, j; |
|
+ isc_boolean_t have[ECDSA_NTAGS]; |
|
+ isc_boolean_t ok; |
|
+ unsigned int mask; |
|
|
|
if (external) |
|
return ((priv->nelements == 0) ? 0 : -1); |
|
|
|
- if (priv->nelements != ECDSA_NTAGS) |
|
- return (-1); |
|
- if (priv->elements[0].tag != TAG(DST_ALG_ECDSA256, 0)) |
|
- return (-1); |
|
- return (0); |
|
+ for (i = 0; i < ECDSA_NTAGS; i++) |
|
+ have[i] = ISC_FALSE; |
|
+ for (j = 0; j < priv->nelements; j++) { |
|
+ for (i = 0; i < ECDSA_NTAGS; i++) |
|
+ if (priv->elements[j].tag == TAG(DST_ALG_ECDSA256, i)) |
|
+ break; |
|
+ if (i == ECDSA_NTAGS) |
|
+ return (-1); |
|
+ have[i] = ISC_TRUE; |
|
+ } |
|
+ |
|
+ mask = ~0; |
|
+ mask <<= sizeof(mask) * 8 - TAG_SHIFT; |
|
+ mask >>= sizeof(mask) * 8 - TAG_SHIFT; |
|
+ |
|
+ if (have[TAG_ECDSA_ENGINE & mask]) |
|
+ ok = have[TAG_ECDSA_LABEL & mask]; |
|
+ else |
|
+ ok = have[TAG_ECDSA_PRIVATEKEY & mask]; |
|
+ return (ok ? 0 : -1 ); |
|
} |
|
|
|
static int |
|
diff --git a/lib/dns/dst_parse.h b/lib/dns/dst_parse.h |
|
index f048bf0..a8a5641 100644 |
|
--- a/lib/dns/dst_parse.h |
|
+++ b/lib/dns/dst_parse.h |
|
@@ -63,7 +63,6 @@ |
|
#define TAG_RSA_COEFFICIENT ((DST_ALG_RSAMD5 << TAG_SHIFT) + 7) |
|
#define TAG_RSA_ENGINE ((DST_ALG_RSAMD5 << TAG_SHIFT) + 8) |
|
#define TAG_RSA_LABEL ((DST_ALG_RSAMD5 << TAG_SHIFT) + 9) |
|
-#define TAG_RSA_PIN ((DST_ALG_RSAMD5 << TAG_SHIFT) + 10) |
|
|
|
#define DH_NTAGS 4 |
|
#define TAG_DH_PRIME ((DST_ALG_DH << TAG_SHIFT) + 0) |
|
@@ -80,9 +79,12 @@ |
|
|
|
#define GOST_NTAGS 1 |
|
#define TAG_GOST_PRIVASN1 ((DST_ALG_ECCGOST << TAG_SHIFT) + 0) |
|
+#define TAG_GOST_PRIVRAW ((DST_ALG_ECCGOST << TAG_SHIFT) + 1) |
|
|
|
-#define ECDSA_NTAGS 1 |
|
+#define ECDSA_NTAGS 4 |
|
#define TAG_ECDSA_PRIVATEKEY ((DST_ALG_ECDSA256 << TAG_SHIFT) + 0) |
|
+#define TAG_ECDSA_ENGINE ((DST_ALG_ECDSA256 << TAG_SHIFT) + 1) |
|
+#define TAG_ECDSA_LABEL ((DST_ALG_ECDSA256 << TAG_SHIFT) + 2) |
|
|
|
#define OLD_HMACMD5_NTAGS 1 |
|
#define HMACMD5_NTAGS 2 |
|
diff --git a/lib/dns/dst_pkcs11.h b/lib/dns/dst_pkcs11.h |
|
new file mode 100644 |
|
index 0000000..1c35b6b |
|
--- /dev/null |
|
+++ b/lib/dns/dst_pkcs11.h |
|
@@ -0,0 +1,43 @@ |
|
+/* |
|
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+#ifndef DST_PKCS11_H |
|
+#define DST_PKCS11_H 1 |
|
+ |
|
+#include <isc/lang.h> |
|
+#include <isc/log.h> |
|
+#include <isc/result.h> |
|
+ |
|
+ISC_LANG_BEGINDECLS |
|
+ |
|
+isc_result_t |
|
+dst__pkcs11_toresult(const char *funcname, const char *file, int line, |
|
+ isc_result_t fallback, CK_RV rv); |
|
+ |
|
+#define PK11_CALL(func, args, fallback) \ |
|
+ ((void) (((rv = (func) args) == CKR_OK) || \ |
|
+ ((ret = dst__pkcs11_toresult(#func, __FILE__, __LINE__, \ |
|
+ fallback, rv)), 0))) |
|
+ |
|
+#define PK11_RET(func, args, fallback) \ |
|
+ ((void) (((rv = (func) args) == CKR_OK) || \ |
|
+ ((ret = dst__pkcs11_toresult(#func, __FILE__, __LINE__, \ |
|
+ fallback, rv)), 0))); \ |
|
+ if (rv != CKR_OK) goto err; |
|
+ |
|
+ISC_LANG_ENDDECLS |
|
+ |
|
+#endif /* DST_PKCS11_H */ |
|
diff --git a/lib/dns/dst_result.c b/lib/dns/dst_result.c |
|
index 30aa1fa..79fa7d3 100644 |
|
--- a/lib/dns/dst_result.c |
|
+++ b/lib/dns/dst_result.c |
|
@@ -50,7 +50,8 @@ static const char *text[DST_R_NRESULTS] = { |
|
"failure computing a shared secret", /*%< 18 */ |
|
"no randomness available", /*%< 19 */ |
|
"bad key type", /*%< 20 */ |
|
- "no engine" /*%< 21 */ |
|
+ "no engine", /*%< 21 */ |
|
+ "illegal operation for an external key",/*%< 22 */ |
|
}; |
|
|
|
#define DST_RESULT_RESULTSET 2 |
|
diff --git a/lib/dns/gssapi_link.c b/lib/dns/gssapi_link.c |
|
index 5ad81cd..1c35959 100644 |
|
--- a/lib/dns/gssapi_link.c |
|
+++ b/lib/dns/gssapi_link.c |
|
@@ -358,6 +358,7 @@ gssapi_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length) { |
|
|
|
static dst_func_t gssapi_functions = { |
|
gssapi_create_signverify_ctx, |
|
+ NULL, /*%< createctx2 */ |
|
gssapi_destroy_signverify_ctx, |
|
gssapi_adddata, |
|
gssapi_sign, |
|
diff --git a/lib/dns/hmac_link.c b/lib/dns/hmac_link.c |
|
index 1f1a0ca..7a56c79 100644 |
|
--- a/lib/dns/hmac_link.c |
|
+++ b/lib/dns/hmac_link.c |
|
@@ -282,6 +282,9 @@ hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
if (result != ISC_R_SUCCESS) |
|
return (result); |
|
|
|
+ if (key->external) |
|
+ result = DST_R_EXTERNALKEY; |
|
+ |
|
key->key_bits = 0; |
|
for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { |
|
switch (priv.elements[i].tag) { |
|
@@ -310,6 +313,7 @@ hmacmd5_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
|
|
static dst_func_t hmacmd5_functions = { |
|
hmacmd5_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
hmacmd5_destroyctx, |
|
hmacmd5_adddata, |
|
hmacmd5_sign, |
|
@@ -528,6 +532,9 @@ hmacsha1_tofile(const dst_key_t *key, const char *directory) { |
|
if (key->keydata.hmacsha1 == NULL) |
|
return (DST_R_NULLKEY); |
|
|
|
+ if (key->external) |
|
+ return (DST_R_EXTERNALKEY); |
|
+ |
|
hkey = key->keydata.hmacsha1; |
|
|
|
priv.elements[cnt].tag = TAG_HMACSHA1_KEY; |
|
@@ -559,8 +566,11 @@ hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
if (result != ISC_R_SUCCESS) |
|
return (result); |
|
|
|
+ if (key->external) |
|
+ result = DST_R_EXTERNALKEY; |
|
+ |
|
key->key_bits = 0; |
|
- for (i = 0; i < priv.nelements; i++) { |
|
+ for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { |
|
switch (priv.elements[i].tag) { |
|
case TAG_HMACSHA1_KEY: |
|
isc_buffer_init(&b, priv.elements[i].data, |
|
@@ -587,6 +597,7 @@ hmacsha1_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
|
|
static dst_func_t hmacsha1_functions = { |
|
hmacsha1_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
hmacsha1_destroyctx, |
|
hmacsha1_adddata, |
|
hmacsha1_sign, |
|
@@ -807,6 +818,9 @@ hmacsha224_tofile(const dst_key_t *key, const char *directory) { |
|
if (key->keydata.hmacsha224 == NULL) |
|
return (DST_R_NULLKEY); |
|
|
|
+ if (key->external) |
|
+ return (DST_R_EXTERNALKEY); |
|
+ |
|
hkey = key->keydata.hmacsha224; |
|
|
|
priv.elements[cnt].tag = TAG_HMACSHA224_KEY; |
|
@@ -838,6 +852,9 @@ hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
if (result != ISC_R_SUCCESS) |
|
return (result); |
|
|
|
+ if (key->external) |
|
+ result = DST_R_EXTERNALKEY; |
|
+ |
|
key->key_bits = 0; |
|
for (i = 0; i < priv.nelements; i++) { |
|
switch (priv.elements[i].tag) { |
|
@@ -866,6 +883,7 @@ hmacsha224_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
|
|
static dst_func_t hmacsha224_functions = { |
|
hmacsha224_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
hmacsha224_destroyctx, |
|
hmacsha224_adddata, |
|
hmacsha224_sign, |
|
@@ -1086,6 +1104,9 @@ hmacsha256_tofile(const dst_key_t *key, const char *directory) { |
|
if (key->keydata.hmacsha256 == NULL) |
|
return (DST_R_NULLKEY); |
|
|
|
+ if (key->external) |
|
+ return (DST_R_EXTERNALKEY); |
|
+ |
|
hkey = key->keydata.hmacsha256; |
|
|
|
priv.elements[cnt].tag = TAG_HMACSHA256_KEY; |
|
@@ -1117,8 +1138,11 @@ hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
if (result != ISC_R_SUCCESS) |
|
return (result); |
|
|
|
+ if (key->external) |
|
+ result = DST_R_EXTERNALKEY; |
|
+ |
|
key->key_bits = 0; |
|
- for (i = 0; i < priv.nelements; i++) { |
|
+ for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { |
|
switch (priv.elements[i].tag) { |
|
case TAG_HMACSHA256_KEY: |
|
isc_buffer_init(&b, priv.elements[i].data, |
|
@@ -1145,6 +1169,7 @@ hmacsha256_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
|
|
static dst_func_t hmacsha256_functions = { |
|
hmacsha256_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
hmacsha256_destroyctx, |
|
hmacsha256_adddata, |
|
hmacsha256_sign, |
|
@@ -1365,6 +1390,9 @@ hmacsha384_tofile(const dst_key_t *key, const char *directory) { |
|
if (key->keydata.hmacsha384 == NULL) |
|
return (DST_R_NULLKEY); |
|
|
|
+ if (key->external) |
|
+ return (DST_R_EXTERNALKEY); |
|
+ |
|
hkey = key->keydata.hmacsha384; |
|
|
|
priv.elements[cnt].tag = TAG_HMACSHA384_KEY; |
|
@@ -1396,8 +1424,11 @@ hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
if (result != ISC_R_SUCCESS) |
|
return (result); |
|
|
|
+ if (key->external) |
|
+ result = DST_R_EXTERNALKEY; |
|
+ |
|
key->key_bits = 0; |
|
- for (i = 0; i < priv.nelements; i++) { |
|
+ for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { |
|
switch (priv.elements[i].tag) { |
|
case TAG_HMACSHA384_KEY: |
|
isc_buffer_init(&b, priv.elements[i].data, |
|
@@ -1424,6 +1455,7 @@ hmacsha384_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
|
|
static dst_func_t hmacsha384_functions = { |
|
hmacsha384_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
hmacsha384_destroyctx, |
|
hmacsha384_adddata, |
|
hmacsha384_sign, |
|
@@ -1644,6 +1676,9 @@ hmacsha512_tofile(const dst_key_t *key, const char *directory) { |
|
if (key->keydata.hmacsha512 == NULL) |
|
return (DST_R_NULLKEY); |
|
|
|
+ if (key->external) |
|
+ return (DST_R_EXTERNALKEY); |
|
+ |
|
hkey = key->keydata.hmacsha512; |
|
|
|
priv.elements[cnt].tag = TAG_HMACSHA512_KEY; |
|
@@ -1675,8 +1710,11 @@ hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
if (result != ISC_R_SUCCESS) |
|
return (result); |
|
|
|
+ if (key->external) |
|
+ result = DST_R_EXTERNALKEY; |
|
+ |
|
key->key_bits = 0; |
|
- for (i = 0; i < priv.nelements; i++) { |
|
+ for (i = 0; i < priv.nelements && result == ISC_R_SUCCESS; i++) { |
|
switch (priv.elements[i].tag) { |
|
case TAG_HMACSHA512_KEY: |
|
isc_buffer_init(&b, priv.elements[i].data, |
|
@@ -1703,6 +1741,7 @@ hmacsha512_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
|
|
static dst_func_t hmacsha512_functions = { |
|
hmacsha512_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
hmacsha512_destroyctx, |
|
hmacsha512_adddata, |
|
hmacsha512_sign, |
|
diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h |
|
index 1fdce4c..bdbd269 100644 |
|
--- a/lib/dns/include/dst/dst.h |
|
+++ b/lib/dns/include/dst/dst.h |
|
@@ -175,6 +175,16 @@ isc_result_t |
|
dst_context_create2(dst_key_t *key, isc_mem_t *mctx, |
|
isc_logcategory_t *category, dst_context_t **dctxp); |
|
|
|
+isc_result_t |
|
+dst_context_create3(dst_key_t *key, isc_mem_t *mctx, |
|
+ isc_logcategory_t *category, isc_boolean_t useforsigning, |
|
+ dst_context_t **dctxp); |
|
+ |
|
+isc_result_t |
|
+dst_context_create4(dst_key_t *key, isc_mem_t *mctx, |
|
+ isc_logcategory_t *category, isc_boolean_t useforsigning, |
|
+ int maxbits, dst_context_t **dctxp); |
|
+ |
|
/*%< |
|
* Creates a context to be used for a sign or verify operation. |
|
* |
|
diff --git a/lib/dns/include/dst/result.h b/lib/dns/include/dst/result.h |
|
index 00640a1..cf9428f 100644 |
|
--- a/lib/dns/include/dst/result.h |
|
+++ b/lib/dns/include/dst/result.h |
|
@@ -57,8 +57,9 @@ |
|
#define DST_R_NORANDOMNESS (ISC_RESULTCLASS_DST + 19) |
|
#define DST_R_BADKEYTYPE (ISC_RESULTCLASS_DST + 20) |
|
#define DST_R_NOENGINE (ISC_RESULTCLASS_DST + 21) |
|
+#define DST_R_EXTERNALKEY (ISC_RESULTCLASS_DST + 22) |
|
|
|
-#define DST_R_NRESULTS 22 /* Number of results */ |
|
+#define DST_R_NRESULTS 23 /* Number of results */ |
|
|
|
ISC_LANG_BEGINDECLS |
|
|
|
diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c |
|
index 36b8a41..55752da 100644 |
|
--- a/lib/dns/openssldh_link.c |
|
+++ b/lib/dns/openssldh_link.c |
|
@@ -463,6 +463,9 @@ openssldh_tofile(const dst_key_t *key, const char *directory) { |
|
if (key->keydata.dh == NULL) |
|
return (DST_R_NULLKEY); |
|
|
|
+ if (key->external) |
|
+ return (DST_R_EXTERNALKEY); |
|
+ |
|
dh = key->keydata.dh; |
|
|
|
memset(bufs, 0, sizeof(bufs)); |
|
@@ -528,6 +531,9 @@ openssldh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
if (ret != ISC_R_SUCCESS) |
|
return (ret); |
|
|
|
+ if (key->external) |
|
+ DST_RET(DST_R_EXTERNALKEY); |
|
+ |
|
dh = DH_new(); |
|
if (dh == NULL) |
|
DST_RET(ISC_R_NOMEMORY); |
|
@@ -630,6 +636,7 @@ openssldh_cleanup(void) { |
|
|
|
static dst_func_t openssldh_functions = { |
|
NULL, /*%< createctx */ |
|
+ NULL, /*%< createctx2 */ |
|
NULL, /*%< destroyctx */ |
|
NULL, /*%< adddata */ |
|
NULL, /*%< openssldh_sign */ |
|
diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c |
|
index a24baae..fd6e91e 100644 |
|
--- a/lib/dns/openssldsa_link.c |
|
+++ b/lib/dns/openssldsa_link.c |
|
@@ -522,7 +522,7 @@ openssldsa_tofile(const dst_key_t *key, const char *directory) { |
|
|
|
if (key->keydata.dsa == NULL) |
|
return (DST_R_NULLKEY); |
|
- |
|
+ |
|
if (key->external) { |
|
priv.nelements = 0; |
|
return (dst__privstruct_writefile(key, &priv, directory)); |
|
@@ -573,20 +573,31 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
isc_mem_t *mctx = key->mctx; |
|
#define DST_RET(a) {ret = a; goto err;} |
|
|
|
- UNUSED(pub); |
|
- |
|
/* read private key file */ |
|
ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv); |
|
if (ret != ISC_R_SUCCESS) |
|
return (ret); |
|
|
|
+ if (key->external) { |
|
+ if (priv.nelements != 0) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ if (pub == NULL) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ key->keydata.pkey = pub->keydata.pkey; |
|
+ pub->keydata.pkey = NULL; |
|
+ key->key_size = pub->key_size; |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ return (ISC_R_SUCCESS); |
|
+ } |
|
+ |
|
dsa = DSA_new(); |
|
if (dsa == NULL) |
|
DST_RET(ISC_R_NOMEMORY); |
|
dsa->flags &= ~DSA_FLAG_CACHE_MONT_P; |
|
key->keydata.dsa = dsa; |
|
|
|
- for (i=0; i < priv.nelements; i++) { |
|
+ for (i = 0; i < priv.nelements; i++) { |
|
BIGNUM *bn; |
|
bn = BN_bin2bn(priv.elements[i].data, |
|
priv.elements[i].length, NULL); |
|
@@ -612,22 +623,8 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
} |
|
} |
|
dst__privstruct_free(&priv, mctx); |
|
- |
|
- if (key->external) { |
|
- if (pub == NULL) |
|
- DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
- dsa->q = pub->keydata.dsa->q; |
|
- pub->keydata.dsa->q = NULL; |
|
- dsa->p = pub->keydata.dsa->p; |
|
- pub->keydata.dsa->p = NULL; |
|
- dsa->g = pub->keydata.dsa->g; |
|
- pub->keydata.dsa->g = NULL; |
|
- dsa->pub_key = pub->keydata.dsa->pub_key; |
|
- pub->keydata.dsa->pub_key = NULL; |
|
- } |
|
- |
|
+ memset(&priv, 0, sizeof(priv)); |
|
key->key_size = BN_num_bits(dsa->p); |
|
- |
|
return (ISC_R_SUCCESS); |
|
|
|
err: |
|
@@ -639,6 +636,7 @@ openssldsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
|
|
static dst_func_t openssldsa_functions = { |
|
openssldsa_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
openssldsa_destroyctx, |
|
openssldsa_adddata, |
|
openssldsa_sign, |
|
diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c |
|
index 7eff9a0..c64cc55 100644 |
|
--- a/lib/dns/opensslecdsa_link.c |
|
+++ b/lib/dns/opensslecdsa_link.c |
|
@@ -18,7 +18,7 @@ |
|
|
|
#include <config.h> |
|
|
|
-#ifdef HAVE_OPENSSL_ECDSA |
|
+#if defined(OPENSSL) && defined(HAVE_OPENSSL_ECDSA) |
|
|
|
#if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA384) |
|
#error "ECDSA without EVP for SHA2?" |
|
@@ -474,7 +474,7 @@ opensslecdsa_tofile(const dst_key_t *key, const char *directory) { |
|
priv.elements[0].length = BN_num_bytes(privkey); |
|
BN_bn2bin(privkey, buf); |
|
priv.elements[0].data = buf; |
|
- priv.nelements = ECDSA_NTAGS; |
|
+ priv.nelements = 1; |
|
ret = dst__privstruct_writefile(key, &priv, directory); |
|
|
|
err: |
|
@@ -519,60 +519,50 @@ static isc_result_t |
|
opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
dst_private_t priv; |
|
isc_result_t ret; |
|
- EVP_PKEY *pkey, *pubpkey; |
|
- EC_KEY *eckey = NULL, *pubeckey = NULL; |
|
- const EC_POINT *pubkey; |
|
- BIGNUM *privkey; |
|
+ EVP_PKEY *pkey; |
|
+ EC_KEY *eckey = NULL; |
|
+ BIGNUM *privkey = NULL; |
|
int group_nid; |
|
isc_mem_t *mctx = key->mctx; |
|
|
|
REQUIRE(key->key_alg == DST_ALG_ECDSA256 || |
|
key->key_alg == DST_ALG_ECDSA384); |
|
|
|
- if (key->key_alg == DST_ALG_ECDSA256) |
|
- group_nid = NID_X9_62_prime256v1; |
|
- else |
|
- group_nid = NID_secp384r1; |
|
- |
|
- eckey = EC_KEY_new_by_curve_name(group_nid); |
|
- if (eckey == NULL) |
|
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); |
|
- |
|
/* read private key file */ |
|
ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); |
|
if (ret != ISC_R_SUCCESS) |
|
goto err; |
|
|
|
if (key->external) { |
|
- /* |
|
- * Copy the public key to this new key. |
|
- */ |
|
- if (pub == NULL) |
|
- DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
- pubpkey = pub->keydata.pkey; |
|
- pubeckey = EVP_PKEY_get1_EC_KEY(pubpkey); |
|
- if (pubeckey == NULL) |
|
- DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
- pubkey = EC_KEY_get0_public_key(pubeckey); |
|
- if (pubkey == NULL) |
|
- DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
- if (EC_KEY_set_public_key(eckey, pubkey) != 1) |
|
- DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
- if (EC_KEY_check_key(eckey) != 1) |
|
+ if (priv.nelements != 0) |
|
DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
- } else { |
|
- privkey = BN_bin2bn(priv.elements[0].data, |
|
- priv.elements[0].length, NULL); |
|
- if (privkey == NULL) |
|
- DST_RET(ISC_R_NOMEMORY); |
|
- if (!EC_KEY_set_private_key(eckey, privkey)) |
|
- DST_RET(ISC_R_NOMEMORY); |
|
- if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS) |
|
+ if (pub == NULL) |
|
DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ key->keydata.pkey = pub->keydata.pkey; |
|
+ pub->keydata.pkey = NULL; |
|
dst__privstruct_free(&priv, mctx); |
|
memset(&priv, 0, sizeof(priv)); |
|
+ return (ISC_R_SUCCESS); |
|
} |
|
- |
|
+ |
|
+ if (key->key_alg == DST_ALG_ECDSA256) |
|
+ group_nid = NID_X9_62_prime256v1; |
|
+ else |
|
+ group_nid = NID_secp384r1; |
|
+ |
|
+ eckey = EC_KEY_new_by_curve_name(group_nid); |
|
+ if (eckey == NULL) |
|
+ return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); |
|
+ |
|
+ privkey = BN_bin2bn(priv.elements[0].data, |
|
+ priv.elements[0].length, NULL); |
|
+ if (privkey == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ if (!EC_KEY_set_private_key(eckey, privkey)) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ |
|
pkey = EVP_PKEY_new(); |
|
if (pkey == NULL) |
|
DST_RET (ISC_R_NOMEMORY); |
|
@@ -584,10 +574,10 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
ret = ISC_R_SUCCESS; |
|
|
|
err: |
|
+ if (privkey != NULL) |
|
+ BN_clear_free(privkey); |
|
if (eckey != NULL) |
|
EC_KEY_free(eckey); |
|
- if (pubeckey != NULL) |
|
- EC_KEY_free(pubeckey); |
|
dst__privstruct_free(&priv, mctx); |
|
memset(&priv, 0, sizeof(priv)); |
|
return (ret); |
|
@@ -595,6 +585,7 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
|
|
static dst_func_t opensslecdsa_functions = { |
|
opensslecdsa_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
opensslecdsa_destroyctx, |
|
opensslecdsa_adddata, |
|
opensslecdsa_sign, |
|
diff --git a/lib/dns/opensslgost_link.c b/lib/dns/opensslgost_link.c |
|
index 325a7c0..9b4ff55 100644 |
|
--- a/lib/dns/opensslgost_link.c |
|
+++ b/lib/dns/opensslgost_link.c |
|
@@ -30,6 +30,7 @@ |
|
#include "dst_internal.h" |
|
#include "dst_openssl.h" |
|
#include "dst_parse.h" |
|
+#include "dst_gost.h" |
|
|
|
#include <openssl/err.h> |
|
#include <openssl/objects.h> |
|
@@ -44,6 +45,60 @@ const EVP_MD *EVP_gost(void) { |
|
return (opensslgost_digest); |
|
} |
|
|
|
+/* ISC methods */ |
|
+ |
|
+isc_result_t |
|
+isc_gost_init(isc_gost_t *ctx) { |
|
+ const EVP_MD *md; |
|
+ int ret; |
|
+ |
|
+ INSIST(ctx != NULL); |
|
+ |
|
+ md = EVP_gost(); |
|
+ if (md == NULL) |
|
+ return (DST_R_CRYPTOFAILURE); |
|
+ EVP_MD_CTX_init(ctx); |
|
+ ret = EVP_DigestInit(ctx, md); |
|
+ if (ret != 1) |
|
+ return (DST_R_CRYPTOFAILURE); |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+void |
|
+isc_gost_invalidate(isc_gost_t *ctx) { |
|
+ EVP_MD_CTX_cleanup(ctx); |
|
+} |
|
+ |
|
+isc_result_t |
|
+isc_gost_update(isc_gost_t *ctx, const unsigned char *data, |
|
+ unsigned int len) |
|
+{ |
|
+ int ret; |
|
+ |
|
+ INSIST(ctx != NULL); |
|
+ INSIST(data != NULL); |
|
+ |
|
+ ret = EVP_DigestUpdate(ctx, (const void *) data, (size_t) len); |
|
+ if (ret != 1) |
|
+ return (DST_R_CRYPTOFAILURE); |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+isc_result_t |
|
+isc_gost_final(isc_gost_t *ctx, unsigned char *digest) { |
|
+ int ret; |
|
+ |
|
+ INSIST(ctx != NULL); |
|
+ INSIST(digest != NULL); |
|
+ |
|
+ ret = EVP_DigestFinal(ctx, digest, NULL); |
|
+ if (ret != 1) |
|
+ return (DST_R_CRYPTOFAILURE); |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+/* DST methods */ |
|
+ |
|
#define DST_RET(a) {ret = a; goto err;} |
|
|
|
static isc_result_t opensslgost_todns(const dst_key_t *key, |
|
@@ -285,6 +340,8 @@ opensslgost_fromdns(dst_key_t *key, isc_buffer_t *data) { |
|
return (ISC_R_SUCCESS); |
|
} |
|
|
|
+#ifdef PREFER_GOSTASN1 |
|
+ |
|
static isc_result_t |
|
opensslgost_tofile(const dst_key_t *key, const char *directory) { |
|
EVP_PKEY *pkey; |
|
@@ -318,7 +375,7 @@ opensslgost_tofile(const dst_key_t *key, const char *directory) { |
|
priv.elements[0].tag = TAG_GOST_PRIVASN1; |
|
priv.elements[0].length = len; |
|
priv.elements[0].data = der; |
|
- priv.nelements = GOST_NTAGS; |
|
+ priv.nelements = 1; |
|
|
|
result = dst__privstruct_writefile(key, &priv, directory); |
|
fail: |
|
@@ -327,42 +384,146 @@ opensslgost_tofile(const dst_key_t *key, const char *directory) { |
|
return (result); |
|
} |
|
|
|
+#else |
|
+ |
|
+static isc_result_t |
|
+opensslgost_tofile(const dst_key_t *key, const char *directory) { |
|
+ EVP_PKEY *pkey; |
|
+ EC_KEY *eckey; |
|
+ const BIGNUM *privkey; |
|
+ dst_private_t priv; |
|
+ isc_result_t ret; |
|
+ unsigned char *buf = NULL; |
|
+ |
|
+ if (key->keydata.pkey == NULL) |
|
+ return (DST_R_NULLKEY); |
|
+ |
|
+ if (key->external) { |
|
+ priv.nelements = 0; |
|
+ return (dst__privstruct_writefile(key, &priv, directory)); |
|
+ } |
|
+ |
|
+ pkey = key->keydata.pkey; |
|
+ eckey = EVP_PKEY_get0(pkey); |
|
+ if (eckey == NULL) |
|
+ return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); |
|
+ privkey = EC_KEY_get0_private_key(eckey); |
|
+ if (privkey == NULL) |
|
+ return (ISC_R_FAILURE); |
|
+ |
|
+ buf = isc_mem_get(key->mctx, BN_num_bytes(privkey)); |
|
+ if (buf == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ |
|
+ priv.elements[0].tag = TAG_GOST_PRIVRAW; |
|
+ priv.elements[0].length = BN_num_bytes(privkey); |
|
+ BN_bn2bin(privkey, buf); |
|
+ priv.elements[0].data = buf; |
|
+ priv.nelements = 1; |
|
+ |
|
+ ret = dst__privstruct_writefile(key, &priv, directory); |
|
+ |
|
+ if (buf != NULL) |
|
+ isc_mem_put(key->mctx, buf, BN_num_bytes(privkey)); |
|
+ return (ret); |
|
+} |
|
+#endif |
|
+ |
|
+static unsigned char gost_dummy_key[71] = { |
|
+ 0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06, |
|
+ 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30, |
|
+ 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, |
|
+ 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, |
|
+ 0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20, 0x1b, |
|
+ 0x3f, 0x94, 0xf7, 0x1a, 0x5f, 0x2f, 0xe7, 0xe5, |
|
+ 0x74, 0x0b, 0x8c, 0xd4, 0xb7, 0x18, 0xdd, 0x65, |
|
+ 0x68, 0x26, 0xd1, 0x54, 0xfb, 0x77, 0xba, 0x63, |
|
+ 0x72, 0xd9, 0xf0, 0x63, 0x87, 0xe0, 0xd6 |
|
+}; |
|
+ |
|
static isc_result_t |
|
opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
dst_private_t priv; |
|
isc_result_t ret; |
|
isc_mem_t *mctx = key->mctx; |
|
EVP_PKEY *pkey = NULL; |
|
+ EC_KEY *eckey; |
|
+ const EC_POINT *pubkey = NULL; |
|
+ BIGNUM *privkey = NULL; |
|
const unsigned char *p; |
|
|
|
- UNUSED(pub); |
|
- |
|
/* read private key file */ |
|
ret = dst__privstruct_parse(key, DST_ALG_ECCGOST, lexer, mctx, &priv); |
|
if (ret != ISC_R_SUCCESS) |
|
return (ret); |
|
|
|
if (key->external) { |
|
- INSIST(priv.nelements == 0); |
|
+ if (priv.nelements != 0) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
if (pub == NULL) |
|
DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
key->keydata.pkey = pub->keydata.pkey; |
|
pub->keydata.pkey = NULL; |
|
- } else { |
|
- INSIST(priv.elements[0].tag == TAG_GOST_PRIVASN1); |
|
+ key->key_size = pub->key_size; |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ return (ISC_R_SUCCESS); |
|
+ } |
|
+ |
|
+ INSIST((priv.elements[0].tag == TAG_GOST_PRIVASN1) || |
|
+ (priv.elements[0].tag == TAG_GOST_PRIVRAW)); |
|
+ |
|
+ if (priv.elements[0].tag == TAG_GOST_PRIVASN1) { |
|
p = priv.elements[0].data; |
|
if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, |
|
(long) priv.elements[0].length) == NULL) |
|
- DST_RET(dst__openssl_toresult2("d2i_PrivateKey", |
|
- DST_R_INVALIDPRIVATEKEY)); |
|
- key->keydata.pkey = pkey; |
|
+ DST_RET(dst__openssl_toresult2( |
|
+ "d2i_PrivateKey", |
|
+ DST_R_INVALIDPRIVATEKEY)); |
|
+ } else { |
|
+ if ((pub != NULL) && (pub->keydata.pkey != NULL)) { |
|
+ eckey = EVP_PKEY_get0(pub->keydata.pkey); |
|
+ pubkey = EC_KEY_get0_public_key(eckey); |
|
+ } |
|
+ |
|
+ privkey = BN_bin2bn(priv.elements[0].data, |
|
+ priv.elements[0].length, NULL); |
|
+ if (privkey == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ |
|
+ /* can't create directly the whole key */ |
|
+ p = gost_dummy_key; |
|
+ if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, |
|
+ (long) sizeof(gost_dummy_key)) == NULL) |
|
+ DST_RET(dst__openssl_toresult2( |
|
+ "d2i_PrivateKey", |
|
+ DST_R_INVALIDPRIVATEKEY)); |
|
+ |
|
+ eckey = EVP_PKEY_get0(pkey); |
|
+ if (eckey == NULL) |
|
+ return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); |
|
+ if (!EC_KEY_set_private_key(eckey, privkey)) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ |
|
+ /* have to (re)set the public key */ |
|
+#ifdef notyet |
|
+ (void) gost2001_compute_public(eckey); |
|
+#else |
|
+ if ((pubkey != NULL) && !EC_KEY_set_public_key(eckey, pubkey)) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+#endif |
|
+ BN_clear_free(privkey); |
|
+ privkey = NULL; |
|
} |
|
+ key->keydata.pkey = pkey; |
|
key->key_size = EVP_PKEY_bits(pkey); |
|
dst__privstruct_free(&priv, mctx); |
|
memset(&priv, 0, sizeof(priv)); |
|
return (ISC_R_SUCCESS); |
|
|
|
err: |
|
+ if (privkey != NULL) |
|
+ BN_clear_free(privkey); |
|
if (pkey != NULL) |
|
EVP_PKEY_free(pkey); |
|
opensslgost_destroy(key); |
|
@@ -382,6 +543,7 @@ opensslgost_cleanup(void) { |
|
|
|
static dst_func_t opensslgost_functions = { |
|
opensslgost_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
opensslgost_destroyctx, |
|
opensslgost_adddata, |
|
opensslgost_sign, |
|
diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c |
|
index 894c7ae..1edeb8d 100644 |
|
--- a/lib/dns/opensslrsa_link.c |
|
+++ b/lib/dns/opensslrsa_link.c |
|
@@ -1196,6 +1196,24 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
EVP_PKEY *pkey = NULL; |
|
#endif |
|
|
|
+ /* read private key file */ |
|
+ ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ if (key->external) { |
|
+ if (priv.nelements != 0) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ if (pub == NULL) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ key->keydata.pkey = pub->keydata.pkey; |
|
+ pub->keydata.pkey = NULL; |
|
+ key->key_size = pub->key_size; |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ return (ISC_R_SUCCESS); |
|
+ } |
|
+ |
|
#if USE_EVP |
|
if (pub != NULL && pub->keydata.pkey != NULL) |
|
pubrsa = EVP_PKEY_get1_RSA(pub->keydata.pkey); |
|
@@ -1206,14 +1224,6 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
} |
|
#endif |
|
|
|
- /* read private key file */ |
|
- ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); |
|
- if (ret != ISC_R_SUCCESS) |
|
- goto err; |
|
- |
|
- if (key->external && priv.nelements != 0) |
|
- DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
- |
|
for (i = 0; i < priv.nelements; i++) { |
|
switch (priv.elements[i].tag) { |
|
case TAG_RSA_ENGINE: |
|
@@ -1297,8 +1307,6 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
continue; |
|
case TAG_RSA_LABEL: |
|
continue; |
|
- case TAG_RSA_PIN: |
|
- continue; |
|
default: |
|
bn = BN_bin2bn(priv.elements[i].data, |
|
priv.elements[i].length, NULL); |
|
@@ -1338,10 +1346,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
|
|
if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) |
|
DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
- if (!key->external) { |
|
- if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) |
|
- DST_RET(ISC_R_RANGE); |
|
- } |
|
+ if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS) |
|
+ DST_RET(ISC_R_RANGE); |
|
key->key_size = BN_num_bits(rsa->n); |
|
if (pubrsa != NULL) |
|
RSA_free(pubrsa); |
|
@@ -1448,6 +1454,7 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label, |
|
|
|
static dst_func_t opensslrsa_functions = { |
|
opensslrsa_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
opensslrsa_destroyctx, |
|
opensslrsa_adddata, |
|
opensslrsa_sign, |
|
diff --git a/lib/dns/pkcs11.c b/lib/dns/pkcs11.c |
|
new file mode 100644 |
|
index 0000000..7aa15fa |
|
--- /dev/null |
|
+++ b/lib/dns/pkcs11.c |
|
@@ -0,0 +1,50 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+#ifdef PKCS11CRYPTO |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <dns/log.h> |
|
+#include <dns/result.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/internal.h> |
|
+ |
|
+#include "dst_pkcs11.h" |
|
+ |
|
+isc_result_t |
|
+dst__pkcs11_toresult(const char *funcname, const char *file, int line, |
|
+ isc_result_t fallback, CK_RV rv) |
|
+{ |
|
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, |
|
+ DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING, |
|
+ "%s:%d: %s: Error = 0x%.8lX\n", |
|
+ file, line, funcname, rv); |
|
+ if (rv == CKR_HOST_MEMORY) |
|
+ return (ISC_R_NOMEMORY); |
|
+ return (fallback); |
|
+} |
|
+ |
|
+ |
|
+#else /* PKCS11CRYPTO */ |
|
+ |
|
+#include <isc/util.h> |
|
+ |
|
+EMPTY_TRANSLATION_UNIT |
|
+ |
|
+#endif /* PKCS11CRYPTO */ |
|
+/*! \file */ |
|
diff --git a/lib/dns/pkcs11dh_link.c b/lib/dns/pkcs11dh_link.c |
|
new file mode 100644 |
|
index 0000000..87afc02 |
|
--- /dev/null |
|
+++ b/lib/dns/pkcs11dh_link.c |
|
@@ -0,0 +1,1140 @@ |
|
+/* |
|
+ * Portions Copyright (C) 20012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ * |
|
+ * Portions Copyright (C) 1995-2000 by Network Associates, Inc. |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+#ifdef PKCS11CRYPTO |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <ctype.h> |
|
+ |
|
+#include <isc/mem.h> |
|
+#include <isc/string.h> |
|
+#include <isc/util.h> |
|
+ |
|
+#include <dst/result.h> |
|
+ |
|
+#include "dst_internal.h" |
|
+#include "dst_parse.h" |
|
+#include "dst_pkcs11.h" |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/internal.h> |
|
+#define WANT_DH_PRIMES |
|
+#include <pk11/constants.h> |
|
+ |
|
+#include <pkcs11/pkcs11.h> |
|
+ |
|
+/* |
|
+ * PKCS#3 DH keys: |
|
+ * mechanisms: |
|
+ * CKM_DH_PKCS_PARAMETER_GEN, |
|
+ * CKM_DH_PKCS_KEY_PAIR_GEN, |
|
+ * CKM_DH_PKCS_DERIVE |
|
+ * domain parameters: |
|
+ * object class CKO_DOMAIN_PARAMETERS |
|
+ * key type CKK_DH |
|
+ * attribute CKA_PRIME (prime p) |
|
+ * attribute CKA_BASE (base g) |
|
+ * optional attribute CKA_PRIME_BITS (p length in bits) |
|
+ * public key: |
|
+ * object class CKO_PUBLIC_KEY |
|
+ * key type CKK_DH |
|
+ * attribute CKA_PRIME (prime p) |
|
+ * attribute CKA_BASE (base g) |
|
+ * attribute CKA_VALUE (public value y) |
|
+ * private key: |
|
+ * object class CKO_PRIVATE_KEY |
|
+ * key type CKK_DH |
|
+ * attribute CKA_PRIME (prime p) |
|
+ * attribute CKA_BASE (base g) |
|
+ * attribute CKA_VALUE (private value x) |
|
+ * optional attribute CKA_VALUE_BITS (x length in bits) |
|
+ * reuse CKA_PRIVATE_EXPONENT for key pair private value |
|
+ */ |
|
+ |
|
+#define CKA_VALUE2 CKA_PRIVATE_EXPONENT |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+#define DST_RET(a) {ret = a; goto err;} |
|
+ |
|
+static void pkcs11dh_destroy(dst_key_t *key); |
|
+static isc_result_t pkcs11dh_todns(const dst_key_t *key, isc_buffer_t *data); |
|
+ |
|
+static isc_result_t |
|
+pkcs11dh_loadpriv(const dst_key_t *key, |
|
+ CK_SESSION_HANDLE session, |
|
+ CK_OBJECT_HANDLE *hKey) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_DH; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_PRIME, NULL, 0 }, |
|
+ { CKA_BASE, NULL, 0 }, |
|
+ { CKA_VALUE, NULL, 0 } |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ const pk11_object_t *priv; |
|
+ isc_result_t ret; |
|
+ unsigned int i; |
|
+ |
|
+ priv = key->keydata.pkey; |
|
+ if ((priv->object != CK_INVALID_HANDLE) && priv->ontoken) { |
|
+ *hKey = priv->object; |
|
+ return (ISC_R_SUCCESS); |
|
+ } |
|
+ |
|
+ attr = pk11_attribute_bytype(priv, CKA_PRIME); |
|
+ if (attr == NULL) |
|
+ return (DST_R_INVALIDPRIVATEKEY); |
|
+ keyTemplate[6].pValue = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (keyTemplate[6].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[6].pValue, attr->pValue, attr->ulValueLen); |
|
+ keyTemplate[6].ulValueLen = attr->ulValueLen; |
|
+ |
|
+ attr = pk11_attribute_bytype(priv, CKA_BASE); |
|
+ if (attr == NULL) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ keyTemplate[7].pValue = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (keyTemplate[7].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[7].pValue, attr->pValue, attr->ulValueLen); |
|
+ keyTemplate[7].ulValueLen = attr->ulValueLen; |
|
+ |
|
+ attr = pk11_attribute_bytype(priv, CKA_VALUE2); |
|
+ if (attr == NULL) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ keyTemplate[8].pValue = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (keyTemplate[8].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[8].pValue, attr->pValue, attr->ulValueLen); |
|
+ keyTemplate[8].ulValueLen = attr->ulValueLen; |
|
+ |
|
+ PK11_CALL(pkcs_C_CreateObject, |
|
+ (session, keyTemplate, (CK_ULONG) 9, hKey), |
|
+ DST_R_COMPUTESECRETFAILURE); |
|
+ if (rv == CKR_OK) |
|
+ ret = ISC_R_SUCCESS; |
|
+ |
|
+ err: |
|
+ for (i = 6; i <= 8; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dh_computesecret(const dst_key_t *pub, const dst_key_t *priv, |
|
+ isc_buffer_t *secret) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_DH_PKCS_DERIVE, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_GENERIC_SECRET; |
|
+ CK_OBJECT_HANDLE hDerived = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; |
|
+ CK_ATTRIBUTE *attr; |
|
+ CK_ULONG secLen; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_VALUE_LEN, &secLen, (CK_ULONG) sizeof(secLen) } |
|
+ }; |
|
+ CK_ATTRIBUTE valTemplate[] = |
|
+ { |
|
+ { CKA_VALUE, NULL, 0 } |
|
+ }; |
|
+ CK_BYTE *secValue; |
|
+ pk11_context_t ctx; |
|
+ isc_result_t ret; |
|
+ unsigned int i; |
|
+ isc_region_t r; |
|
+ |
|
+ REQUIRE(pub->keydata.pkey != NULL); |
|
+ REQUIRE(priv->keydata.pkey != NULL); |
|
+ REQUIRE(priv->keydata.pkey->repr != NULL); |
|
+ attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_PRIME); |
|
+ if (attr == NULL) |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ REQUIRE(attr != NULL); |
|
+ secLen = attr->ulValueLen; |
|
+ attr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE); |
|
+ if (attr == NULL) |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ |
|
+ ret = pk11_get_session(&ctx, OP_DH, ISC_TRUE, ISC_FALSE, ISC_FALSE, |
|
+ NULL, pk11_get_best_token(OP_DH)); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ return (ret); |
|
+ |
|
+ mech.ulParameterLen = attr->ulValueLen; |
|
+ mech.pParameter = isc_mem_get(pub->mctx, mech.ulParameterLen); |
|
+ if (mech.pParameter == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(mech.pParameter, attr->pValue, mech.ulParameterLen); |
|
+ |
|
+ ret = pkcs11dh_loadpriv(priv, ctx.session, &hKey); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ PK11_RET(pkcs_C_DeriveKey, |
|
+ (ctx.session, &mech, hKey, |
|
+ keyTemplate, (CK_ULONG) 6, &hDerived), |
|
+ DST_R_COMPUTESECRETFAILURE); |
|
+ |
|
+ attr = valTemplate; |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (ctx.session, hDerived, attr, (CK_ULONG) 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ attr->pValue = isc_mem_get(pub->mctx, attr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (ctx.session, hDerived, attr, (CK_ULONG) 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ /* strip leading zeros */ |
|
+ secValue = (CK_BYTE_PTR) attr->pValue; |
|
+ for (i = 0; i < attr->ulValueLen; i++) |
|
+ if (secValue[i] != 0) |
|
+ break; |
|
+ isc_buffer_availableregion(secret, &r); |
|
+ if (r.length < attr->ulValueLen - i) |
|
+ DST_RET(ISC_R_NOSPACE); |
|
+ memcpy(r.base, secValue + i, attr->ulValueLen - i); |
|
+ isc_buffer_add(secret, attr->ulValueLen - i); |
|
+ ret = ISC_R_SUCCESS; |
|
+ |
|
+ err: |
|
+ if (hDerived != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx.session, hDerived); |
|
+ if (valTemplate[0].pValue != NULL) { |
|
+ memset(valTemplate[0].pValue, 0, valTemplate[0].ulValueLen); |
|
+ isc_mem_put(pub->mctx, |
|
+ valTemplate[0].pValue, |
|
+ valTemplate[0].ulValueLen); |
|
+ } |
|
+ if ((hKey != CK_INVALID_HANDLE) && !priv->keydata.pkey->ontoken) |
|
+ (void) pkcs_C_DestroyObject(ctx.session, hKey); |
|
+ if (mech.pParameter != NULL) { |
|
+ memset(mech.pParameter, 0, mech.ulParameterLen); |
|
+ isc_mem_put(pub->mctx, mech.pParameter, mech.ulParameterLen); |
|
+ } |
|
+ pk11_return_session(&ctx); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_boolean_t |
|
+pkcs11dh_compare(const dst_key_t *key1, const dst_key_t *key2) { |
|
+ pk11_object_t *dh1, *dh2; |
|
+ CK_ATTRIBUTE *attr1, *attr2; |
|
+ |
|
+ dh1 = key1->keydata.pkey; |
|
+ dh2 = key2->keydata.pkey; |
|
+ |
|
+ if ((dh1 == NULL) && (dh2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((dh1 == NULL) || (dh2 == NULL)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(dh1, CKA_PRIME); |
|
+ attr2 = pk11_attribute_bytype(dh2, CKA_PRIME); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(dh1, CKA_BASE); |
|
+ attr2 = pk11_attribute_bytype(dh2, CKA_BASE); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(dh1, CKA_VALUE); |
|
+ attr2 = pk11_attribute_bytype(dh2, CKA_VALUE); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(dh1, CKA_VALUE2); |
|
+ attr2 = pk11_attribute_bytype(dh2, CKA_VALUE2); |
|
+ if (((attr1 != NULL) || (attr2 != NULL)) && |
|
+ ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ if (!dh1->ontoken && !dh2->ontoken) |
|
+ return (ISC_TRUE); |
|
+ else if (dh1->ontoken || dh2->ontoken || |
|
+ (dh1->object != dh2->object)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ return (ISC_TRUE); |
|
+} |
|
+ |
|
+static isc_boolean_t |
|
+pkcs11dh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { |
|
+ pk11_object_t *dh1, *dh2; |
|
+ CK_ATTRIBUTE *attr1, *attr2; |
|
+ |
|
+ dh1 = key1->keydata.pkey; |
|
+ dh2 = key2->keydata.pkey; |
|
+ |
|
+ if ((dh1 == NULL) && (dh2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((dh1 == NULL) || (dh2 == NULL)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(dh1, CKA_PRIME); |
|
+ attr2 = pk11_attribute_bytype(dh2, CKA_PRIME); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(dh1, CKA_BASE); |
|
+ attr2 = pk11_attribute_bytype(dh2, CKA_BASE); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ return (ISC_TRUE); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dh_generate(dst_key_t *key, int generator, void (*callback)(int)) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_DH_PKCS_PARAMETER_GEN, NULL, 0 }; |
|
+ CK_OBJECT_HANDLE domainparams = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS dClass = CKO_DOMAIN_PARAMETERS; |
|
+ CK_KEY_TYPE keyType = CKK_DH; |
|
+ CK_ULONG bits = 0; |
|
+ CK_ATTRIBUTE dTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &dClass, (CK_ULONG) sizeof(dClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) } |
|
+ }; |
|
+ CK_ATTRIBUTE pTemplate[] = |
|
+ { |
|
+ { CKA_PRIME, NULL, 0 }, |
|
+ { CKA_BASE, NULL, 0 } |
|
+ }; |
|
+ CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; |
|
+ CK_ATTRIBUTE pubTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, |
|
+ { CKA_KEY_TYPE,&keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIME, NULL, 0 }, |
|
+ { CKA_BASE, NULL, 0 }, |
|
+ }; |
|
+ CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; |
|
+ CK_ATTRIBUTE privTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_DERIVE, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_object_t *dh = NULL; |
|
+ pk11_context_t *pk11_ctx; |
|
+ isc_result_t ret; |
|
+ |
|
+ UNUSED(callback); |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_DH, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, pk11_get_best_token(OP_DH)); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ bits = key->key_size; |
|
+ if ((generator == 0) && |
|
+ ((bits == 768) || (bits == 1024) || (bits == 1536))) { |
|
+ if (bits == 768) { |
|
+ pubTemplate[4].pValue = |
|
+ isc_mem_get(key->mctx, sizeof(pk11_dh_bn768)); |
|
+ if (pubTemplate[4].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(pubTemplate[4].pValue, |
|
+ pk11_dh_bn768, sizeof(pk11_dh_bn768)); |
|
+ pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn768); |
|
+ } else if (bits == 1024) { |
|
+ pubTemplate[4].pValue = |
|
+ isc_mem_get(key->mctx, sizeof(pk11_dh_bn1024)); |
|
+ if (pubTemplate[4].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(pubTemplate[4].pValue, |
|
+ pk11_dh_bn1024, sizeof(pk11_dh_bn1024)); |
|
+ pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1024); |
|
+ } else { |
|
+ pubTemplate[4].pValue = |
|
+ isc_mem_get(key->mctx, sizeof(pk11_dh_bn1536)); |
|
+ if (pubTemplate[4].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(pubTemplate[4].pValue, |
|
+ pk11_dh_bn1536, sizeof(pk11_dh_bn1536)); |
|
+ pubTemplate[4].ulValueLen = sizeof(pk11_dh_bn1536); |
|
+ } |
|
+ pubTemplate[5].pValue = isc_mem_get(key->mctx, |
|
+ sizeof(pk11_dh_bn2)); |
|
+ if (pubTemplate[5].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(pubTemplate[5].pValue, pk11_dh_bn2, sizeof(pk11_dh_bn2)); |
|
+ pubTemplate[5].ulValueLen = sizeof(pk11_dh_bn2); |
|
+ } else { |
|
+ PK11_RET(pkcs_C_GenerateKey, |
|
+ (pk11_ctx->session, &mech, |
|
+ dTemplate, (CK_ULONG) 5, &domainparams), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, domainparams, |
|
+ pTemplate, (CK_ULONG) 2), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ pTemplate[0].pValue = isc_mem_get(key->mctx, |
|
+ pTemplate[0].ulValueLen); |
|
+ if (pTemplate[0].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen); |
|
+ pTemplate[1].pValue = isc_mem_get(key->mctx, |
|
+ pTemplate[1].ulValueLen); |
|
+ if (pTemplate[1].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen); |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, domainparams, |
|
+ pTemplate, (CK_ULONG) 2), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ pubTemplate[4].pValue = pTemplate[0].pValue; |
|
+ pubTemplate[4].ulValueLen = pTemplate[0].ulValueLen; |
|
+ pTemplate[0].pValue = NULL; |
|
+ pubTemplate[5].pValue = pTemplate[1].pValue; |
|
+ pubTemplate[5].ulValueLen = pTemplate[1].ulValueLen; |
|
+ pTemplate[1].pValue = NULL; |
|
+ } |
|
+ |
|
+ mech.mechanism = CKM_DH_PKCS_KEY_PAIR_GEN; |
|
+ PK11_RET(pkcs_C_GenerateKeyPair, |
|
+ (pk11_ctx->session, &mech, |
|
+ pubTemplate, (CK_ULONG) 6, |
|
+ privTemplate, (CK_ULONG) 7, |
|
+ &pub, &priv), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); |
|
+ if (dh == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ key->keydata.pkey = dh; |
|
+ dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); |
|
+ if (dh->repr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(dh->repr, 0, sizeof(*attr) * 4); |
|
+ dh->attrcnt = 4; |
|
+ |
|
+ attr = dh->repr; |
|
+ attr[0].type = CKA_PRIME; |
|
+ attr[0].pValue = pubTemplate[4].pValue; |
|
+ attr[0].ulValueLen = pubTemplate[4].ulValueLen; |
|
+ pubTemplate[4].pValue = NULL; |
|
+ |
|
+ attr[1].type = CKA_BASE; |
|
+ attr[1].pValue = pubTemplate[5].pValue; |
|
+ attr[1].ulValueLen = pubTemplate[5].ulValueLen; |
|
+ pubTemplate[5].pValue =NULL; |
|
+ |
|
+ attr += 2; |
|
+ attr->type = CKA_VALUE; |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, pub, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, pub, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ attr++; |
|
+ attr->type = CKA_VALUE; |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, priv, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, priv, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ attr->type = CKA_VALUE2; |
|
+ |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pkcs11dh_destroy(key); |
|
+ if (priv != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); |
|
+ if (pub != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); |
|
+ if (domainparams != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, domainparams); |
|
+ |
|
+ if (pubTemplate[4].pValue != NULL) { |
|
+ memset(pubTemplate[4].pValue, 0, pubTemplate[4].ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ pubTemplate[4].pValue, |
|
+ pubTemplate[4].ulValueLen); |
|
+ } |
|
+ if (pubTemplate[5].pValue != NULL) { |
|
+ memset(pubTemplate[5].pValue, 0, pubTemplate[5].ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ pubTemplate[5].pValue, |
|
+ pubTemplate[5].ulValueLen); |
|
+ } |
|
+ if (pTemplate[0].pValue != NULL) { |
|
+ memset(pTemplate[0].pValue, 0, pTemplate[0].ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ pTemplate[0].pValue, |
|
+ pTemplate[0].ulValueLen); |
|
+ } |
|
+ if (pTemplate[1].pValue != NULL) { |
|
+ memset(pTemplate[1].pValue, 0, pTemplate[1].ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ pTemplate[1].pValue, |
|
+ pTemplate[1].ulValueLen); |
|
+ } |
|
+ |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_boolean_t |
|
+pkcs11dh_isprivate(const dst_key_t *key) { |
|
+ pk11_object_t *dh = key->keydata.pkey; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ if (dh == NULL) |
|
+ return (ISC_FALSE); |
|
+ attr = pk11_attribute_bytype(dh, CKA_VALUE2); |
|
+ return (ISC_TF((attr != NULL) || dh->ontoken)); |
|
+} |
|
+ |
|
+static void |
|
+pkcs11dh_destroy(dst_key_t *key) { |
|
+ pk11_object_t *dh = key->keydata.pkey; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ if (dh == NULL) |
|
+ return; |
|
+ |
|
+ INSIST((dh->object == CK_INVALID_HANDLE) || dh->ontoken); |
|
+ |
|
+ for (attr = pk11_attribute_first(dh); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(dh, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_VALUE: |
|
+ case CKA_VALUE2: |
|
+ case CKA_PRIME: |
|
+ case CKA_BASE: |
|
+ if (attr->pValue != NULL) { |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ } |
|
+ break; |
|
+ } |
|
+ if (dh->repr != NULL) { |
|
+ memset(dh->repr, 0, dh->attrcnt * sizeof(*attr)); |
|
+ isc_mem_put(key->mctx, dh->repr, dh->attrcnt * sizeof(*attr)); |
|
+ } |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ isc_mem_put(key->mctx, dh, sizeof(*dh)); |
|
+ key->keydata.pkey = NULL; |
|
+} |
|
+ |
|
+static void |
|
+uint16_toregion(isc_uint16_t val, isc_region_t *region) { |
|
+ *region->base++ = (val & 0xff00) >> 8; |
|
+ *region->base++ = (val & 0x00ff); |
|
+} |
|
+ |
|
+static isc_uint16_t |
|
+uint16_fromregion(isc_region_t *region) { |
|
+ isc_uint16_t val; |
|
+ unsigned char *cp = region->base; |
|
+ |
|
+ val = ((unsigned int)(cp[0])) << 8; |
|
+ val |= ((unsigned int)(cp[1])); |
|
+ |
|
+ region->base += 2; |
|
+ return (val); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dh_todns(const dst_key_t *key, isc_buffer_t *data) { |
|
+ pk11_object_t *dh; |
|
+ CK_ATTRIBUTE *attr; |
|
+ isc_region_t r; |
|
+ isc_uint16_t dnslen, plen = 0, glen = 0, publen = 0; |
|
+ CK_BYTE *prime = NULL, *base = NULL, *pub = NULL; |
|
+ |
|
+ REQUIRE(key->keydata.pkey != NULL); |
|
+ |
|
+ dh = key->keydata.pkey; |
|
+ |
|
+ for (attr = pk11_attribute_first(dh); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(dh, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_VALUE: |
|
+ pub = (CK_BYTE *) attr->pValue; |
|
+ publen = (isc_uint16_t) attr->ulValueLen; |
|
+ break; |
|
+ case CKA_PRIME: |
|
+ prime = (CK_BYTE *) attr->pValue; |
|
+ plen = (isc_uint16_t) attr->ulValueLen; |
|
+ break; |
|
+ case CKA_BASE: |
|
+ base = (CK_BYTE *) attr->pValue; |
|
+ glen = (isc_uint16_t) attr->ulValueLen; |
|
+ break; |
|
+ } |
|
+ REQUIRE((prime != NULL) && (base != NULL) && (pub != NULL)); |
|
+ |
|
+ isc_buffer_availableregion(data, &r); |
|
+ |
|
+ if ((glen == 1) && (memcmp(pk11_dh_bn2, base, glen) == 0) && |
|
+ (((plen == sizeof(pk11_dh_bn768)) && |
|
+ (memcmp(pk11_dh_bn768, prime, plen) == 0)) || |
|
+ ((plen == sizeof(pk11_dh_bn1024)) && |
|
+ (memcmp(pk11_dh_bn1024, prime, plen) == 0)) || |
|
+ ((plen == sizeof(pk11_dh_bn1536)) && |
|
+ (memcmp(pk11_dh_bn1536, prime, plen) == 0)))) { |
|
+ plen = 1; |
|
+ glen = 0; |
|
+ } |
|
+ |
|
+ dnslen = plen + glen + publen + 6; |
|
+ if (r.length < (unsigned int) dnslen) |
|
+ return (ISC_R_NOSPACE); |
|
+ |
|
+ uint16_toregion(plen, &r); |
|
+ if (plen == 1) { |
|
+ if (memcmp(pk11_dh_bn768, prime, sizeof(pk11_dh_bn768)) == 0) |
|
+ *r.base = 1; |
|
+ else if (memcmp(pk11_dh_bn1024, prime, |
|
+ sizeof(pk11_dh_bn1024)) == 0) |
|
+ *r.base = 2; |
|
+ else |
|
+ *r.base = 3; |
|
+ } |
|
+ else |
|
+ memcpy(r.base, prime, plen); |
|
+ r.base += plen; |
|
+ |
|
+ uint16_toregion(glen, &r); |
|
+ if (glen > 0) |
|
+ memcpy(r.base, base, glen); |
|
+ r.base += glen; |
|
+ |
|
+ uint16_toregion(publen, &r); |
|
+ memcpy(r.base, pub, publen); |
|
+ r.base += publen; |
|
+ |
|
+ isc_buffer_add(data, dnslen); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dh_fromdns(dst_key_t *key, isc_buffer_t *data) { |
|
+ pk11_object_t *dh; |
|
+ isc_region_t r; |
|
+ isc_uint16_t plen, glen, plen_, glen_, publen; |
|
+ CK_BYTE *prime = NULL, *base = NULL, *pub = NULL; |
|
+ CK_ATTRIBUTE *attr; |
|
+ int special = 0; |
|
+ |
|
+ isc_buffer_remainingregion(data, &r); |
|
+ if (r.length == 0) |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); |
|
+ if (dh == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ |
|
+ /* |
|
+ * Read the prime length. 1 & 2 are table entries, > 16 means a |
|
+ * prime follows, otherwise an error. |
|
+ */ |
|
+ if (r.length < 2) { |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ isc_mem_put(key->mctx, dh, sizeof(*dh)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ plen = uint16_fromregion(&r); |
|
+ if (plen < 16 && plen != 1 && plen != 2) { |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ isc_mem_put(key->mctx, dh, sizeof(*dh)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ if (r.length < plen) { |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ isc_mem_put(key->mctx, dh, sizeof(*dh)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ plen_ = plen; |
|
+ if (plen == 1 || plen == 2) { |
|
+ if (plen == 1) |
|
+ special = *r.base++; |
|
+ else |
|
+ special = uint16_fromregion(&r); |
|
+ switch (special) { |
|
+ case 1: |
|
+ prime = pk11_dh_bn768; |
|
+ plen_ = sizeof(pk11_dh_bn768); |
|
+ break; |
|
+ case 2: |
|
+ prime = pk11_dh_bn1024; |
|
+ plen_ = sizeof(pk11_dh_bn1024); |
|
+ break; |
|
+ case 3: |
|
+ prime = pk11_dh_bn1536; |
|
+ plen_ = sizeof(pk11_dh_bn1536); |
|
+ break; |
|
+ default: |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ isc_mem_put(key->mctx, dh, sizeof(*dh)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ } |
|
+ else { |
|
+ prime = r.base; |
|
+ r.base += plen; |
|
+ } |
|
+ |
|
+ /* |
|
+ * Read the generator length. This should be 0 if the prime was |
|
+ * special, but it might not be. If it's 0 and the prime is not |
|
+ * special, we have a problem. |
|
+ */ |
|
+ if (r.length < 2) { |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ isc_mem_put(key->mctx, dh, sizeof(*dh)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ glen = uint16_fromregion(&r); |
|
+ if (r.length < glen) { |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ isc_mem_put(key->mctx, dh, sizeof(*dh)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ glen_ = glen; |
|
+ if (special != 0) { |
|
+ if (glen == 0) { |
|
+ base = pk11_dh_bn2; |
|
+ glen_ = sizeof(pk11_dh_bn2); |
|
+ } |
|
+ else { |
|
+ base = r.base; |
|
+ if (memcmp(base, pk11_dh_bn2, glen) == 0) { |
|
+ base = pk11_dh_bn2; |
|
+ glen_ = sizeof(pk11_dh_bn2); |
|
+ } |
|
+ else { |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ isc_mem_put(key->mctx, dh, sizeof(*dh)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ } |
|
+ } |
|
+ else { |
|
+ if (glen == 0) { |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ isc_mem_put(key->mctx, dh, sizeof(*dh)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ base = r.base; |
|
+ } |
|
+ r.base += glen; |
|
+ |
|
+ if (r.length < 2) { |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ isc_mem_put(key->mctx, dh, sizeof(*dh)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ publen = uint16_fromregion(&r); |
|
+ if (r.length < publen) { |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ isc_mem_put(key->mctx, dh, sizeof(*dh)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ pub = r.base; |
|
+ r.base += publen; |
|
+ |
|
+ key->key_size = pk11_numbits(prime, plen_); |
|
+ |
|
+ dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); |
|
+ if (dh->repr == NULL) |
|
+ goto nomemory; |
|
+ memset(dh->repr, 0, sizeof(*attr) * 3); |
|
+ dh->attrcnt = 3; |
|
+ |
|
+ attr = dh->repr; |
|
+ attr[0].type = CKA_PRIME; |
|
+ attr[0].pValue = isc_mem_get(key->mctx, plen_); |
|
+ if (attr[0].pValue == NULL) |
|
+ goto nomemory; |
|
+ memcpy(attr[0].pValue, prime, plen_); |
|
+ attr[0].ulValueLen = (CK_ULONG) plen_; |
|
+ |
|
+ attr[1].type = CKA_BASE; |
|
+ attr[1].pValue = isc_mem_get(key->mctx, glen_); |
|
+ if (attr[1].pValue == NULL) |
|
+ goto nomemory; |
|
+ memcpy(attr[1].pValue, base, glen_); |
|
+ attr[1].ulValueLen = (CK_ULONG) glen_; |
|
+ |
|
+ attr[2].type = CKA_VALUE; |
|
+ attr[2].pValue = isc_mem_get(key->mctx, publen); |
|
+ if (attr[2].pValue == NULL) |
|
+ goto nomemory; |
|
+ memcpy(attr[2].pValue, pub, publen); |
|
+ attr[2].ulValueLen = (CK_ULONG) publen; |
|
+ |
|
+ isc_buffer_forward(data, plen + glen + publen + 6); |
|
+ |
|
+ key->keydata.pkey = dh; |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ nomemory: |
|
+ for (attr = pk11_attribute_first(dh); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(dh, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_VALUE: |
|
+ case CKA_PRIME: |
|
+ case CKA_BASE: |
|
+ if (attr->pValue != NULL) { |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ } |
|
+ break; |
|
+ } |
|
+ if (dh->repr != NULL) { |
|
+ memset(dh->repr, 0, dh->attrcnt * sizeof(*attr)); |
|
+ isc_mem_put(key->mctx, dh->repr, dh->attrcnt * sizeof(*attr)); |
|
+ } |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ isc_mem_put(key->mctx, dh, sizeof(*dh)); |
|
+ return (ISC_R_NOMEMORY); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dh_tofile(const dst_key_t *key, const char *directory) { |
|
+ int i; |
|
+ pk11_object_t *dh; |
|
+ CK_ATTRIBUTE *attr; |
|
+ CK_ATTRIBUTE *prime = NULL, *base = NULL, *pub = NULL, *prv = NULL; |
|
+ dst_private_t priv; |
|
+ unsigned char *bufs[4]; |
|
+ isc_result_t result; |
|
+ |
|
+ if (key->keydata.pkey == NULL) |
|
+ return (DST_R_NULLKEY); |
|
+ |
|
+ if (key->external) |
|
+ return (DST_R_EXTERNALKEY); |
|
+ |
|
+ dh = key->keydata.pkey; |
|
+ |
|
+ for (attr = pk11_attribute_first(dh); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(dh, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_VALUE: |
|
+ pub = attr; |
|
+ break; |
|
+ case CKA_VALUE2: |
|
+ prv = attr; |
|
+ break; |
|
+ case CKA_PRIME: |
|
+ prime = attr; |
|
+ break; |
|
+ case CKA_BASE: |
|
+ base = attr; |
|
+ break; |
|
+ } |
|
+ if ((prime == NULL) || (base == NULL) || |
|
+ (pub == NULL) || (prv == NULL)) |
|
+ return (DST_R_NULLKEY); |
|
+ |
|
+ memset(bufs, 0, sizeof(bufs)); |
|
+ for (i = 0; i < 4; i++) { |
|
+ bufs[i] = isc_mem_get(key->mctx, prime->ulValueLen); |
|
+ if (bufs[i] == NULL) { |
|
+ result = ISC_R_NOMEMORY; |
|
+ goto fail; |
|
+ } |
|
+ memset(bufs[i], 0, prime->ulValueLen); |
|
+ } |
|
+ |
|
+ i = 0; |
|
+ |
|
+ priv.elements[i].tag = TAG_DH_PRIME; |
|
+ priv.elements[i].length = (unsigned short) prime->ulValueLen; |
|
+ memcpy(bufs[i], prime->pValue, prime->ulValueLen); |
|
+ priv.elements[i].data = bufs[i]; |
|
+ i++; |
|
+ |
|
+ priv.elements[i].tag = TAG_DH_GENERATOR; |
|
+ priv.elements[i].length = (unsigned short) base->ulValueLen; |
|
+ memcpy(bufs[i], base->pValue, base->ulValueLen); |
|
+ priv.elements[i].data = bufs[i]; |
|
+ i++; |
|
+ |
|
+ priv.elements[i].tag = TAG_DH_PRIVATE; |
|
+ priv.elements[i].length = (unsigned short) prv->ulValueLen; |
|
+ memcpy(bufs[i], prv->pValue, prv->ulValueLen); |
|
+ priv.elements[i].data = bufs[i]; |
|
+ i++; |
|
+ |
|
+ priv.elements[i].tag = TAG_DH_PUBLIC; |
|
+ priv.elements[i].length = (unsigned short) pub->ulValueLen; |
|
+ memcpy(bufs[i], pub->pValue, pub->ulValueLen); |
|
+ priv.elements[i].data = bufs[i]; |
|
+ i++; |
|
+ |
|
+ priv.nelements = i; |
|
+ result = dst__privstruct_writefile(key, &priv, directory); |
|
+ fail: |
|
+ for (i = 0; i < 4; i++) { |
|
+ if (bufs[i] == NULL) |
|
+ break; |
|
+ memset(bufs[i], 0, prime->ulValueLen); |
|
+ isc_mem_put(key->mctx, bufs[i], prime->ulValueLen); |
|
+ } |
|
+ return (result); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dh_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
+ dst_private_t priv; |
|
+ isc_result_t ret; |
|
+ int i; |
|
+ pk11_object_t *dh = NULL; |
|
+ CK_ATTRIBUTE *attr; |
|
+ isc_mem_t *mctx; |
|
+ |
|
+ UNUSED(pub); |
|
+ mctx = key->mctx; |
|
+ |
|
+ /* read private key file */ |
|
+ ret = dst__privstruct_parse(key, DST_ALG_DH, lexer, mctx, &priv); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ return (ret); |
|
+ |
|
+ if (key->external) |
|
+ DST_RET(DST_R_EXTERNALKEY); |
|
+ |
|
+ dh = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dh)); |
|
+ if (dh == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(dh, 0, sizeof(*dh)); |
|
+ key->keydata.pkey = dh; |
|
+ dh->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); |
|
+ if (dh->repr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(dh->repr, 0, sizeof(*attr) * 4); |
|
+ dh->attrcnt = 4; |
|
+ attr = dh->repr; |
|
+ attr[0].type = CKA_PRIME; |
|
+ attr[1].type = CKA_BASE; |
|
+ attr[2].type = CKA_VALUE; |
|
+ attr[3].type = CKA_VALUE2; |
|
+ |
|
+ for (i = 0; i < priv.nelements; i++) { |
|
+ CK_BYTE *bn; |
|
+ |
|
+ bn = isc_mem_get(key->mctx, priv.elements[i].length); |
|
+ if (bn == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(bn, priv.elements[i].data, priv.elements[i].length); |
|
+ |
|
+ switch (priv.elements[i].tag) { |
|
+ case TAG_DH_PRIME: |
|
+ attr = pk11_attribute_bytype(dh, CKA_PRIME); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_DH_GENERATOR: |
|
+ attr = pk11_attribute_bytype(dh, CKA_BASE); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_DH_PRIVATE: |
|
+ attr = pk11_attribute_bytype(dh, CKA_VALUE2); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_DH_PUBLIC: |
|
+ attr = pk11_attribute_bytype(dh, CKA_VALUE); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ } |
|
+ } |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ |
|
+ attr = pk11_attribute_bytype(dh, CKA_PRIME); |
|
+ INSIST(attr != NULL); |
|
+ key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pkcs11dh_destroy(key); |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static dst_func_t pkcs11dh_functions = { |
|
+ NULL, /*%< createctx */ |
|
+ NULL, /*%< createctx2 */ |
|
+ NULL, /*%< destroyctx */ |
|
+ NULL, /*%< adddata */ |
|
+ NULL, /*%< sign */ |
|
+ NULL, /*%< verify */ |
|
+ NULL, /*%< verify2 */ |
|
+ pkcs11dh_computesecret, |
|
+ pkcs11dh_compare, |
|
+ pkcs11dh_paramcompare, |
|
+ pkcs11dh_generate, |
|
+ pkcs11dh_isprivate, |
|
+ pkcs11dh_destroy, |
|
+ pkcs11dh_todns, |
|
+ pkcs11dh_fromdns, |
|
+ pkcs11dh_tofile, |
|
+ pkcs11dh_parse, |
|
+ NULL, /*%< cleanup */ |
|
+ NULL, /*%< fromlabel */ |
|
+ NULL, /*%< dump */ |
|
+ NULL, /*%< restore */ |
|
+}; |
|
+ |
|
+isc_result_t |
|
+dst__pkcs11dh_init(dst_func_t **funcp) { |
|
+ REQUIRE(funcp != NULL); |
|
+ if (*funcp == NULL) |
|
+ *funcp = &pkcs11dh_functions; |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+#else /* PKCS11CRYPTO */ |
|
+ |
|
+#include <isc/util.h> |
|
+ |
|
+EMPTY_TRANSLATION_UNIT |
|
+ |
|
+#endif /* PKCS11CRYPTO */ |
|
+/*! \file */ |
|
diff --git a/lib/dns/pkcs11dsa_link.c b/lib/dns/pkcs11dsa_link.c |
|
new file mode 100644 |
|
index 0000000..6c8e46c |
|
--- /dev/null |
|
+++ b/lib/dns/pkcs11dsa_link.c |
|
@@ -0,0 +1,1130 @@ |
|
+/* |
|
+ * Portions Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ * |
|
+ * Portions Copyright (C) 1995-2000 by Network Associates, Inc. |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+#ifdef PKCS11CRYPTO |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <string.h> |
|
+ |
|
+#include <isc/entropy.h> |
|
+#include <isc/mem.h> |
|
+#include <isc/sha1.h> |
|
+#include <isc/util.h> |
|
+ |
|
+#include <dst/result.h> |
|
+ |
|
+#include "dst_internal.h" |
|
+#include "dst_parse.h" |
|
+#include "dst_pkcs11.h" |
|
+ |
|
+#include <pk11/internal.h> |
|
+ |
|
+/* |
|
+ * FIPS 186-2 DSA keys: |
|
+ * mechanisms: |
|
+ * CKM_DSA_SHA1, |
|
+ * CKM_DSA_KEY_PAIR_GEN, |
|
+ * CKM_DSA_PARAMETER_GEN |
|
+ * domain parameters: |
|
+ * object class CKO_DOMAIN_PARAMETERS |
|
+ * key type CKK_DSA |
|
+ * attribute CKA_PRIME (prime p) |
|
+ * attribute CKA_SUBPRIME (subprime q) |
|
+ * attribute CKA_BASE (base g) |
|
+ * optional attribute CKA_PRIME_BITS (p length in bits) |
|
+ * public keys: |
|
+ * object class CKO_PUBLIC_KEY |
|
+ * key type CKK_DSA |
|
+ * attribute CKA_PRIME (prime p) |
|
+ * attribute CKA_SUBPRIME (subprime q) |
|
+ * attribute CKA_BASE (base g) |
|
+ * attribute CKA_VALUE (public value y) |
|
+ * private keys: |
|
+ * object class CKO_PRIVATE_KEY |
|
+ * key type CKK_DSA |
|
+ * attribute CKA_PRIME (prime p) |
|
+ * attribute CKA_SUBPRIME (subprime q) |
|
+ * attribute CKA_BASE (base g) |
|
+ * attribute CKA_VALUE (private value x) |
|
+ * reuse CKA_PRIVATE_EXPONENT for key pair private value |
|
+ */ |
|
+ |
|
+#define CKA_VALUE2 CKA_PRIVATE_EXPONENT |
|
+ |
|
+#define DST_RET(a) {ret = a; goto err;} |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+static isc_result_t pkcs11dsa_todns(const dst_key_t *key, isc_buffer_t *data); |
|
+static void pkcs11dsa_destroy(dst_key_t *key); |
|
+ |
|
+static isc_result_t |
|
+pkcs11dsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_DSA_SHA1, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_DSA; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_PRIME, NULL, 0 }, |
|
+ { CKA_SUBPRIME, NULL, 0 }, |
|
+ { CKA_BASE, NULL, 0 }, |
|
+ { CKA_VALUE, NULL, 0 } |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_object_t *dsa; |
|
+ pk11_context_t *pk11_ctx; |
|
+ isc_result_t ret; |
|
+ unsigned int i; |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, pk11_get_best_token(OP_DSA)); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ dsa = key->keydata.pkey; |
|
+ if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) { |
|
+ pk11_ctx->ontoken = dsa->ontoken; |
|
+ pk11_ctx->object = dsa->object; |
|
+ goto token_key; |
|
+ } |
|
+ |
|
+ for (attr = pk11_attribute_first(dsa); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(dsa, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_PRIME: |
|
+ INSIST(keyTemplate[6].type == attr->type); |
|
+ keyTemplate[6].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[6].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[6].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[6].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_SUBPRIME: |
|
+ INSIST(keyTemplate[7].type == attr->type); |
|
+ keyTemplate[7].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[7].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[7].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[7].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_BASE: |
|
+ INSIST(keyTemplate[8].type == attr->type); |
|
+ keyTemplate[8].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[8].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[8].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[8].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_VALUE2: |
|
+ INSIST(keyTemplate[9].type == CKA_VALUE); |
|
+ keyTemplate[9].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[9].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[9].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[9].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ } |
|
+ pk11_ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_ctx->ontoken = ISC_FALSE; |
|
+ PK11_RET(pkcs_C_CreateObject, |
|
+ (pk11_ctx->session, |
|
+ keyTemplate, (CK_ULONG) 10, |
|
+ &pk11_ctx->object), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ token_key: |
|
+ |
|
+ PK11_RET(pkcs_C_SignInit, |
|
+ (pk11_ctx->session, &mech, pk11_ctx->object), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ dctx->ctxdata.pk11_ctx = pk11_ctx; |
|
+ |
|
+ for (i = 6; i <= 9; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); |
|
+ for (i = 6; i <= 9; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dsa_createctx_verify(dst_key_t *key, dst_context_t *dctx) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_DSA_SHA1, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_DSA; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_PRIME, NULL, 0 }, |
|
+ { CKA_SUBPRIME, NULL, 0 }, |
|
+ { CKA_BASE, NULL, 0 }, |
|
+ { CKA_VALUE, NULL, 0 } |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_object_t *dsa; |
|
+ pk11_context_t *pk11_ctx; |
|
+ isc_result_t ret; |
|
+ unsigned int i; |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, pk11_get_best_token(OP_DSA)); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ dsa = key->keydata.pkey; |
|
+ if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) { |
|
+ pk11_ctx->ontoken = dsa->ontoken; |
|
+ pk11_ctx->object = dsa->object; |
|
+ goto token_key; |
|
+ } |
|
+ |
|
+ for (attr = pk11_attribute_first(dsa); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(dsa, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_PRIME: |
|
+ INSIST(keyTemplate[5].type == attr->type); |
|
+ keyTemplate[5].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[5].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[5].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[5].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_SUBPRIME: |
|
+ INSIST(keyTemplate[6].type == attr->type); |
|
+ keyTemplate[6].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[6].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[6].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[6].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_BASE: |
|
+ INSIST(keyTemplate[7].type == attr->type); |
|
+ keyTemplate[7].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[7].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[7].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[7].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_VALUE: |
|
+ INSIST(keyTemplate[8].type == attr->type); |
|
+ keyTemplate[8].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[8].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[8].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[8].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ } |
|
+ pk11_ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_ctx->ontoken = ISC_FALSE; |
|
+ PK11_RET(pkcs_C_CreateObject, |
|
+ (pk11_ctx->session, |
|
+ keyTemplate, (CK_ULONG) 9, |
|
+ &pk11_ctx->object), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ token_key: |
|
+ |
|
+ PK11_RET(pkcs_C_VerifyInit, |
|
+ (pk11_ctx->session, &mech, pk11_ctx->object), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ dctx->ctxdata.pk11_ctx = pk11_ctx; |
|
+ |
|
+ for (i = 5; i <= 8; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); |
|
+ for (i = 5; i <= 8; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dsa_createctx(dst_key_t *key, dst_context_t *dctx) { |
|
+ if (dctx->use == DO_SIGN) |
|
+ return (pkcs11dsa_createctx_sign(key, dctx)); |
|
+ else |
|
+ return (pkcs11dsa_createctx_verify(key, dctx)); |
|
+} |
|
+ |
|
+static void |
|
+pkcs11dsa_destroyctx(dst_context_t *dctx) { |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ |
|
+ if (pk11_ctx != NULL) { |
|
+ if (!pk11_ctx->ontoken && |
|
+ (pk11_ctx->object != CK_INVALID_HANDLE)) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, |
|
+ pk11_ctx->object); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ dctx->ctxdata.pk11_ctx = NULL; |
|
+ } |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dsa_adddata(dst_context_t *dctx, const isc_region_t *data) { |
|
+ CK_RV rv; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ |
|
+ if (dctx->use == DO_SIGN) |
|
+ PK11_CALL(pkcs_C_SignUpdate, |
|
+ (pk11_ctx->session, |
|
+ (CK_BYTE_PTR) data->base, |
|
+ (CK_ULONG) data->length), |
|
+ ISC_R_FAILURE); |
|
+ else |
|
+ PK11_CALL(pkcs_C_VerifyUpdate, |
|
+ (pk11_ctx->session, |
|
+ (CK_BYTE_PTR) data->base, |
|
+ (CK_ULONG) data->length), |
|
+ ISC_R_FAILURE); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { |
|
+ CK_RV rv; |
|
+ CK_ULONG siglen = ISC_SHA1_DIGESTLENGTH * 2; |
|
+ isc_region_t r; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ |
|
+ isc_buffer_availableregion(sig, &r); |
|
+ if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1) |
|
+ return (ISC_R_NOSPACE); |
|
+ |
|
+ PK11_RET(pkcs_C_SignFinal, |
|
+ (pk11_ctx->session, (CK_BYTE_PTR) r.base + 1, &siglen), |
|
+ DST_R_SIGNFAILURE); |
|
+ if (siglen != ISC_SHA1_DIGESTLENGTH * 2) |
|
+ return (DST_R_SIGNFAILURE); |
|
+ |
|
+ *r.base = (dctx->key->key_size - 512)/64; |
|
+ isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1); |
|
+ |
|
+ err: |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dsa_verify(dst_context_t *dctx, const isc_region_t *sig) { |
|
+ CK_RV rv; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ |
|
+ PK11_CALL(pkcs_C_VerifyFinal, |
|
+ (pk11_ctx->session, |
|
+ (CK_BYTE_PTR) sig->base + 1, |
|
+ (CK_ULONG) sig->length - 1), |
|
+ DST_R_VERIFYFAILURE); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_boolean_t |
|
+pkcs11dsa_compare(const dst_key_t *key1, const dst_key_t *key2) { |
|
+ pk11_object_t *dsa1, *dsa2; |
|
+ CK_ATTRIBUTE *attr1, *attr2; |
|
+ |
|
+ dsa1 = key1->keydata.pkey; |
|
+ dsa2 = key2->keydata.pkey; |
|
+ |
|
+ if ((dsa1 == NULL) && (dsa2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((dsa1 == NULL) || (dsa2 == NULL)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(dsa1, CKA_PRIME); |
|
+ attr2 = pk11_attribute_bytype(dsa2, CKA_PRIME); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(dsa1, CKA_SUBPRIME); |
|
+ attr2 = pk11_attribute_bytype(dsa2, CKA_SUBPRIME); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(dsa1, CKA_BASE); |
|
+ attr2 = pk11_attribute_bytype(dsa2, CKA_BASE); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(dsa1, CKA_VALUE); |
|
+ attr2 = pk11_attribute_bytype(dsa2, CKA_VALUE); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(dsa1, CKA_VALUE2); |
|
+ attr2 = pk11_attribute_bytype(dsa2, CKA_VALUE2); |
|
+ if (((attr1 != NULL) || (attr2 != NULL)) && |
|
+ ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ if (!dsa1->ontoken && !dsa2->ontoken) |
|
+ return (ISC_TRUE); |
|
+ else if (dsa1->ontoken || dsa2->ontoken || |
|
+ (dsa1->object != dsa2->object)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ return (ISC_TRUE); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_DSA_PARAMETER_GEN, NULL, 0 }; |
|
+ CK_OBJECT_HANDLE dp = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS dpClass = CKO_DOMAIN_PARAMETERS; |
|
+ CK_KEY_TYPE keyType = CKK_DSA; |
|
+ CK_ULONG bits = 0; |
|
+ CK_ATTRIBUTE dpTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &dpClass, (CK_ULONG) sizeof(dpClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) }, |
|
+ }; |
|
+ CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; |
|
+ CK_ATTRIBUTE pubTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_PRIME, NULL, 0 }, |
|
+ { CKA_SUBPRIME, NULL, 0 }, |
|
+ { CKA_BASE, NULL, 0 } |
|
+ }; |
|
+ CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; |
|
+ CK_ATTRIBUTE privTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_object_t *dsa; |
|
+ pk11_context_t *pk11_ctx; |
|
+ isc_result_t ret; |
|
+ unsigned int i; |
|
+ |
|
+ UNUSED(unused); |
|
+ UNUSED(callback); |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, pk11_get_best_token(OP_DSA)); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ bits = key->key_size; |
|
+ PK11_RET(pkcs_C_GenerateKey, |
|
+ (pk11_ctx->session, &mech, dpTemplate, (CK_ULONG) 5, &dp), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); |
|
+ if (dsa == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(dsa, 0, sizeof(*dsa)); |
|
+ key->keydata.pkey = dsa; |
|
+ dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 5); |
|
+ if (dsa->repr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(dsa->repr, 0, sizeof(*attr) * 5); |
|
+ dsa->attrcnt = 5; |
|
+ |
|
+ attr = dsa->repr; |
|
+ attr[0].type = CKA_PRIME; |
|
+ attr[1].type = CKA_SUBPRIME; |
|
+ attr[2].type = CKA_BASE; |
|
+ attr[3].type = CKA_VALUE; |
|
+ attr[4].type = CKA_VALUE2; |
|
+ |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, dp, attr, 3), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ for (i = 0; i <= 2; i++) { |
|
+ attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); |
|
+ if (attr[i].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr[i].pValue, 0, attr[i].ulValueLen); |
|
+ } |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, dp, attr, 3), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ pubTemplate[5].pValue = attr[0].pValue; |
|
+ pubTemplate[5].ulValueLen = attr[0].ulValueLen; |
|
+ pubTemplate[6].pValue = attr[1].pValue; |
|
+ pubTemplate[6].ulValueLen = attr[1].ulValueLen; |
|
+ pubTemplate[7].pValue = attr[2].pValue; |
|
+ pubTemplate[7].ulValueLen = attr[2].ulValueLen; |
|
+ |
|
+ mech.mechanism = CKM_DSA_KEY_PAIR_GEN; |
|
+ PK11_RET(pkcs_C_GenerateKeyPair, |
|
+ (pk11_ctx->session, &mech, |
|
+ pubTemplate, (CK_ULONG) 8, |
|
+ privTemplate, (CK_ULONG) 7, |
|
+ &pub, &priv), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ attr = dsa->repr; |
|
+ attr += 3; |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, pub, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, pub, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ attr++; |
|
+ attr->type = CKA_VALUE; |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, priv, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, priv, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ attr->type = CKA_VALUE2; |
|
+ |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, dp); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pkcs11dsa_destroy(key); |
|
+ if (priv != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); |
|
+ if (pub != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); |
|
+ if (dp != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, dp); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_boolean_t |
|
+pkcs11dsa_isprivate(const dst_key_t *key) { |
|
+ pk11_object_t *dsa = key->keydata.pkey; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ if (dsa == NULL) |
|
+ return (ISC_FALSE); |
|
+ attr = pk11_attribute_bytype(dsa, CKA_VALUE2); |
|
+ return (ISC_TF((attr != NULL) || dsa->ontoken)); |
|
+} |
|
+ |
|
+static void |
|
+pkcs11dsa_destroy(dst_key_t *key) { |
|
+ pk11_object_t *dsa = key->keydata.pkey; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ if (dsa == NULL) |
|
+ return; |
|
+ |
|
+ INSIST((dsa->object == CK_INVALID_HANDLE) || dsa->ontoken); |
|
+ |
|
+ for (attr = pk11_attribute_first(dsa); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(dsa, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_PRIME: |
|
+ case CKA_SUBPRIME: |
|
+ case CKA_BASE: |
|
+ case CKA_VALUE: |
|
+ case CKA_VALUE2: |
|
+ if (attr->pValue != NULL) { |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ } |
|
+ break; |
|
+ } |
|
+ if (dsa->repr != NULL) { |
|
+ memset(dsa->repr, 0, dsa->attrcnt * sizeof(*attr)); |
|
+ isc_mem_put(key->mctx, |
|
+ dsa->repr, |
|
+ dsa->attrcnt * sizeof(*attr)); |
|
+ } |
|
+ memset(dsa, 0, sizeof(*dsa)); |
|
+ isc_mem_put(key->mctx, dsa, sizeof(*dsa)); |
|
+ key->keydata.pkey = NULL; |
|
+} |
|
+ |
|
+ |
|
+static isc_result_t |
|
+pkcs11dsa_todns(const dst_key_t *key, isc_buffer_t *data) { |
|
+ pk11_object_t *dsa; |
|
+ CK_ATTRIBUTE *attr; |
|
+ isc_region_t r; |
|
+ int dnslen; |
|
+ unsigned int t, p_bytes; |
|
+ CK_ATTRIBUTE *prime = NULL, *subprime = NULL; |
|
+ CK_ATTRIBUTE *base = NULL, *pub_key = NULL; |
|
+ CK_BYTE *cp; |
|
+ |
|
+ REQUIRE(key->keydata.pkey != NULL); |
|
+ |
|
+ dsa = key->keydata.pkey; |
|
+ |
|
+ for (attr = pk11_attribute_first(dsa); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(dsa, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_PRIME: |
|
+ prime = attr; |
|
+ break; |
|
+ case CKA_SUBPRIME: |
|
+ subprime = attr; |
|
+ break; |
|
+ case CKA_BASE: |
|
+ base = attr; |
|
+ break; |
|
+ case CKA_VALUE: |
|
+ pub_key = attr; |
|
+ break; |
|
+ } |
|
+ REQUIRE((prime != NULL) && (subprime != NULL) && |
|
+ (base != NULL) && (pub_key != NULL)); |
|
+ |
|
+ isc_buffer_availableregion(data, &r); |
|
+ |
|
+ t = (prime->ulValueLen - 64) / 8; |
|
+ if (t > 8) |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ p_bytes = 64 + 8 * t; |
|
+ |
|
+ dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH; |
|
+ if (r.length < (unsigned int) dnslen) |
|
+ return (ISC_R_NOSPACE); |
|
+ |
|
+ memset(r.base, 0, dnslen); |
|
+ *r.base++ = t; |
|
+ cp = (CK_BYTE *) subprime->pValue; |
|
+ memcpy(r.base + ISC_SHA1_DIGESTLENGTH - subprime->ulValueLen, |
|
+ cp, subprime->ulValueLen); |
|
+ r.base += ISC_SHA1_DIGESTLENGTH; |
|
+ cp = (CK_BYTE *) prime->pValue; |
|
+ memcpy(r.base + key->key_size/8 - prime->ulValueLen, |
|
+ cp, prime->ulValueLen); |
|
+ r.base += p_bytes; |
|
+ cp = (CK_BYTE *) base->pValue; |
|
+ memcpy(r.base + key->key_size/8 - base->ulValueLen, |
|
+ cp, base->ulValueLen); |
|
+ r.base += p_bytes; |
|
+ cp = (CK_BYTE *) pub_key->pValue; |
|
+ memcpy(r.base + key->key_size/8 - pub_key->ulValueLen, |
|
+ cp, pub_key->ulValueLen); |
|
+ r.base += p_bytes; |
|
+ |
|
+ isc_buffer_add(data, dnslen); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dsa_fromdns(dst_key_t *key, isc_buffer_t *data) { |
|
+ pk11_object_t *dsa; |
|
+ isc_region_t r; |
|
+ unsigned int t, p_bytes; |
|
+ CK_BYTE *prime, *subprime, *base, *pub_key; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ isc_buffer_remainingregion(data, &r); |
|
+ if (r.length == 0) |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); |
|
+ if (dsa == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ memset(dsa, 0, sizeof(*dsa)); |
|
+ |
|
+ t = (unsigned int) *r.base++; |
|
+ if (t > 8) { |
|
+ memset(dsa, 0, sizeof(*dsa)); |
|
+ isc_mem_put(key->mctx, dsa, sizeof(*dsa)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ p_bytes = 64 + 8 * t; |
|
+ |
|
+ if (r.length < 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) { |
|
+ memset(dsa, 0, sizeof(*dsa)); |
|
+ isc_mem_put(key->mctx, dsa, sizeof(*dsa)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ |
|
+ subprime = r.base; |
|
+ r.base += ISC_SHA1_DIGESTLENGTH; |
|
+ |
|
+ prime = r.base; |
|
+ r.base += p_bytes; |
|
+ |
|
+ base = r.base; |
|
+ r.base += p_bytes; |
|
+ |
|
+ pub_key = r.base; |
|
+ r.base += p_bytes; |
|
+ |
|
+ key->key_size = p_bytes * 8; |
|
+ |
|
+ isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes); |
|
+ |
|
+ dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4); |
|
+ if (dsa->repr == NULL) |
|
+ goto nomemory; |
|
+ memset(dsa->repr, 0, sizeof(*attr) * 4); |
|
+ dsa->attrcnt = 4; |
|
+ |
|
+ attr = dsa->repr; |
|
+ attr[0].type = CKA_PRIME; |
|
+ attr[0].pValue = isc_mem_get(key->mctx, p_bytes); |
|
+ if (attr[0].pValue == NULL) |
|
+ goto nomemory; |
|
+ memcpy(attr[0].pValue, prime, p_bytes); |
|
+ attr[0].ulValueLen = p_bytes; |
|
+ |
|
+ attr[1].type = CKA_SUBPRIME; |
|
+ attr[1].pValue = isc_mem_get(key->mctx, ISC_SHA1_DIGESTLENGTH); |
|
+ if (attr[1].pValue == NULL) |
|
+ goto nomemory; |
|
+ memcpy(attr[1].pValue, subprime, ISC_SHA1_DIGESTLENGTH); |
|
+ attr[1].ulValueLen = ISC_SHA1_DIGESTLENGTH; |
|
+ |
|
+ attr[2].type = CKA_BASE; |
|
+ attr[2].pValue = isc_mem_get(key->mctx, p_bytes); |
|
+ if (attr[2].pValue == NULL) |
|
+ goto nomemory; |
|
+ memcpy(attr[2].pValue, base, p_bytes); |
|
+ attr[2].ulValueLen = p_bytes; |
|
+ |
|
+ attr[3].type = CKA_VALUE; |
|
+ attr[3].pValue = isc_mem_get(key->mctx, p_bytes); |
|
+ if (attr[3].pValue == NULL) |
|
+ goto nomemory; |
|
+ memcpy(attr[3].pValue, pub_key, p_bytes); |
|
+ attr[3].ulValueLen = p_bytes; |
|
+ |
|
+ key->keydata.pkey = dsa; |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ nomemory: |
|
+ for (attr = pk11_attribute_first(dsa); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(dsa, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_PRIME: |
|
+ case CKA_SUBPRIME: |
|
+ case CKA_BASE: |
|
+ case CKA_VALUE: |
|
+ if (attr->pValue != NULL) { |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ } |
|
+ break; |
|
+ } |
|
+ if (dsa->repr != NULL) { |
|
+ memset(dsa->repr, 0, dsa->attrcnt * sizeof(*attr)); |
|
+ isc_mem_put(key->mctx, |
|
+ dsa->repr, |
|
+ dsa->attrcnt * sizeof(*attr)); |
|
+ } |
|
+ memset(dsa, 0, sizeof(*dsa)); |
|
+ isc_mem_put(key->mctx, dsa, sizeof(*dsa)); |
|
+ return (ISC_R_NOMEMORY); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dsa_tofile(const dst_key_t *key, const char *directory) { |
|
+ int cnt = 0; |
|
+ pk11_object_t *dsa; |
|
+ CK_ATTRIBUTE *attr; |
|
+ CK_ATTRIBUTE *prime = NULL, *subprime = NULL, *base = NULL; |
|
+ CK_ATTRIBUTE *pub_key = NULL, *priv_key = NULL; |
|
+ dst_private_t priv; |
|
+ unsigned char bufs[5][128]; |
|
+ |
|
+ if (key->keydata.pkey == NULL) |
|
+ return (DST_R_NULLKEY); |
|
+ |
|
+ if (key->external) { |
|
+ priv.nelements = 0; |
|
+ return (dst__privstruct_writefile(key, &priv, directory)); |
|
+ } |
|
+ |
|
+ dsa = key->keydata.pkey; |
|
+ |
|
+ for (attr = pk11_attribute_first(dsa); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(dsa, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_PRIME: |
|
+ prime = attr; |
|
+ break; |
|
+ case CKA_SUBPRIME: |
|
+ subprime = attr; |
|
+ break; |
|
+ case CKA_BASE: |
|
+ base = attr; |
|
+ break; |
|
+ case CKA_VALUE: |
|
+ pub_key = attr; |
|
+ break; |
|
+ case CKA_VALUE2: |
|
+ priv_key = attr; |
|
+ break; |
|
+ } |
|
+ if ((prime == NULL) || (subprime == NULL) || (base == NULL) || |
|
+ (pub_key == NULL) || (priv_key ==NULL)) |
|
+ return (DST_R_NULLKEY); |
|
+ |
|
+ priv.elements[cnt].tag = TAG_DSA_PRIME; |
|
+ priv.elements[cnt].length = (unsigned short) prime->ulValueLen; |
|
+ memcpy(bufs[cnt], prime->pValue, prime->ulValueLen); |
|
+ priv.elements[cnt].data = bufs[cnt]; |
|
+ cnt++; |
|
+ |
|
+ priv.elements[cnt].tag = TAG_DSA_SUBPRIME; |
|
+ priv.elements[cnt].length = (unsigned short) subprime->ulValueLen; |
|
+ memcpy(bufs[cnt], subprime->pValue, subprime->ulValueLen); |
|
+ priv.elements[cnt].data = bufs[cnt]; |
|
+ cnt++; |
|
+ |
|
+ priv.elements[cnt].tag = TAG_DSA_BASE; |
|
+ priv.elements[cnt].length = (unsigned short) base->ulValueLen; |
|
+ memcpy(bufs[cnt], base->pValue, base->ulValueLen); |
|
+ priv.elements[cnt].data = bufs[cnt]; |
|
+ cnt++; |
|
+ |
|
+ priv.elements[cnt].tag = TAG_DSA_PRIVATE; |
|
+ priv.elements[cnt].length = (unsigned short) priv_key->ulValueLen; |
|
+ memcpy(bufs[cnt], priv_key->pValue, priv_key->ulValueLen); |
|
+ priv.elements[cnt].data = bufs[cnt]; |
|
+ cnt++; |
|
+ |
|
+ priv.elements[cnt].tag = TAG_DSA_PUBLIC; |
|
+ priv.elements[cnt].length = (unsigned short) pub_key->ulValueLen; |
|
+ memcpy(bufs[cnt], pub_key->pValue, pub_key->ulValueLen); |
|
+ priv.elements[cnt].data = bufs[cnt]; |
|
+ cnt++; |
|
+ |
|
+ priv.nelements = cnt; |
|
+ return (dst__privstruct_writefile(key, &priv, directory)); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
+ dst_private_t priv; |
|
+ isc_result_t ret; |
|
+ int i; |
|
+ pk11_object_t *dsa = NULL; |
|
+ CK_ATTRIBUTE *attr; |
|
+ isc_mem_t *mctx = key->mctx; |
|
+ |
|
+ /* read private key file */ |
|
+ ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ return (ret); |
|
+ |
|
+ if (key->external) { |
|
+ if (priv.nelements != 0) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ if (pub == NULL) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ |
|
+ key->keydata.pkey = pub->keydata.pkey; |
|
+ pub->keydata.pkey = NULL; |
|
+ key->key_size = pub->key_size; |
|
+ |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ } |
|
+ |
|
+ dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa)); |
|
+ if (dsa == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(dsa, 0, sizeof(*dsa)); |
|
+ key->keydata.pkey = dsa; |
|
+ |
|
+ dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 5); |
|
+ if (dsa->repr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(dsa->repr, 0, sizeof(*attr) * 5); |
|
+ dsa->attrcnt = 5; |
|
+ attr = dsa->repr; |
|
+ attr[0].type = CKA_PRIME; |
|
+ attr[1].type = CKA_SUBPRIME; |
|
+ attr[2].type = CKA_BASE; |
|
+ attr[3].type = CKA_VALUE; |
|
+ attr[4].type = CKA_VALUE2; |
|
+ |
|
+ for (i = 0; i < priv.nelements; i++) { |
|
+ CK_BYTE *bn; |
|
+ |
|
+ bn = isc_mem_get(key->mctx, priv.elements[i].length); |
|
+ if (bn == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(bn, |
|
+ priv.elements[i].data, |
|
+ priv.elements[i].length); |
|
+ |
|
+ switch (priv.elements[i].tag) { |
|
+ case TAG_DSA_PRIME: |
|
+ attr = pk11_attribute_bytype(dsa, CKA_PRIME); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_DSA_SUBPRIME: |
|
+ attr = pk11_attribute_bytype(dsa, |
|
+ CKA_SUBPRIME); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_DSA_BASE: |
|
+ attr = pk11_attribute_bytype(dsa, CKA_BASE); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_DSA_PRIVATE: |
|
+ attr = pk11_attribute_bytype(dsa, CKA_VALUE2); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_DSA_PUBLIC: |
|
+ attr = pk11_attribute_bytype(dsa, CKA_VALUE); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ } |
|
+ } |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ |
|
+ attr = pk11_attribute_bytype(dsa, CKA_PRIME); |
|
+ INSIST(attr != NULL); |
|
+ key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pkcs11dsa_destroy(key); |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static dst_func_t pkcs11dsa_functions = { |
|
+ pkcs11dsa_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
+ pkcs11dsa_destroyctx, |
|
+ pkcs11dsa_adddata, |
|
+ pkcs11dsa_sign, |
|
+ pkcs11dsa_verify, |
|
+ NULL, /*%< verify2 */ |
|
+ NULL, /*%< computesecret */ |
|
+ pkcs11dsa_compare, |
|
+ NULL, /*%< paramcompare */ |
|
+ pkcs11dsa_generate, |
|
+ pkcs11dsa_isprivate, |
|
+ pkcs11dsa_destroy, |
|
+ pkcs11dsa_todns, |
|
+ pkcs11dsa_fromdns, |
|
+ pkcs11dsa_tofile, |
|
+ pkcs11dsa_parse, |
|
+ NULL, /*%< cleanup */ |
|
+ NULL, /*%< fromlabel */ |
|
+ NULL, /*%< dump */ |
|
+ NULL, /*%< restore */ |
|
+}; |
|
+ |
|
+isc_result_t |
|
+dst__pkcs11dsa_init(dst_func_t **funcp) { |
|
+ REQUIRE(funcp != NULL); |
|
+ if (*funcp == NULL) |
|
+ *funcp = &pkcs11dsa_functions; |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+#else /* PKCS11CRYPTO */ |
|
+ |
|
+#include <isc/util.h> |
|
+ |
|
+EMPTY_TRANSLATION_UNIT |
|
+ |
|
+#endif /* PKCS11CRYPTO */ |
|
+/*! \file */ |
|
diff --git a/lib/dns/pkcs11ecdsa_link.c b/lib/dns/pkcs11ecdsa_link.c |
|
new file mode 100644 |
|
index 0000000..4f56050 |
|
--- /dev/null |
|
+++ b/lib/dns/pkcs11ecdsa_link.c |
|
@@ -0,0 +1,1189 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#if defined(PKCS11CRYPTO) && defined(HAVE_PKCS11_ECDSA) |
|
+ |
|
+#include <isc/entropy.h> |
|
+#include <isc/mem.h> |
|
+#include <isc/sha2.h> |
|
+#include <isc/string.h> |
|
+#include <isc/util.h> |
|
+ |
|
+#include <dns/keyvalues.h> |
|
+#include <dst/result.h> |
|
+ |
|
+#include "dst_internal.h" |
|
+#include "dst_parse.h" |
|
+#include "dst_pkcs11.h" |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/internal.h> |
|
+#define WANT_ECC_CURVES |
|
+#include <pk11/constants.h> |
|
+ |
|
+#include <pkcs11/pkcs11.h> |
|
+ |
|
+/* |
|
+ * FIPS 186-3 ECDSA keys: |
|
+ * mechanisms: |
|
+ * CKM_ECDSA, |
|
+ * CKM_EC_KEY_PAIR_GEN |
|
+ * domain parameters: |
|
+ * CKA_EC_PARAMS (choice with OID namedCurve) |
|
+ * public keys: |
|
+ * object class CKO_PUBLIC_KEY |
|
+ * key type CKK_EC |
|
+ * attribute CKA_EC_PARAMS (choice with OID namedCurve) |
|
+ * attribute CKA_EC_POINT (point Q) |
|
+ * private keys: |
|
+ * object class CKO_PRIVATE_KEY |
|
+ * key type CKK_EC |
|
+ * attribute CKA_EC_PARAMS (choice with OID namedCurve) |
|
+ * attribute CKA_VALUE (big int d) |
|
+ * point format: 0x04 (octet-string) <2*size+1> 0x4 (uncompressed) <x> <y> |
|
+ */ |
|
+ |
|
+#define TAG_OCTECT_STRING 0x04 |
|
+#define UNCOMPRESSED 0x04 |
|
+ |
|
+#define DST_RET(a) {ret = a; goto err;} |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+static isc_result_t pkcs11ecdsa_todns(const dst_key_t *key, |
|
+ isc_buffer_t *data); |
|
+static void pkcs11ecdsa_destroy(dst_key_t *key); |
|
+static isc_result_t pkcs11ecdsa_fetch(dst_key_t *key, const char *engine, |
|
+ const char *label, dst_key_t *pub); |
|
+ |
|
+static isc_result_t |
|
+pkcs11ecdsa_createctx(dst_key_t *key, dst_context_t *dctx) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = {0, NULL, 0 }; |
|
+ CK_SLOT_ID slotid; |
|
+ pk11_context_t *pk11_ctx; |
|
+ pk11_object_t *ec = key->keydata.pkey; |
|
+ isc_result_t ret; |
|
+ |
|
+ UNUSED(key); |
|
+ REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || |
|
+ dctx->key->key_alg == DST_ALG_ECDSA384); |
|
+ |
|
+ if (dctx->key->key_alg == DST_ALG_ECDSA256) |
|
+ mech.mechanism = CKM_SHA256; |
|
+ else |
|
+ mech.mechanism = CKM_SHA384; |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ if (ec->ontoken && (dctx->use == DO_SIGN)) |
|
+ slotid = ec->slot; |
|
+ else |
|
+ slotid = pk11_get_best_token(OP_EC); |
|
+ ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, ISC_FALSE, |
|
+ NULL, slotid); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ PK11_RET(pkcs_C_DigestInit, (pk11_ctx->session, &mech), ISC_R_FAILURE); |
|
+ dctx->ctxdata.pk11_ctx = pk11_ctx; |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static void |
|
+pkcs11ecdsa_destroyctx(dst_context_t *dctx) { |
|
+ CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_SHA384_DIGESTLENGTH; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ |
|
+ REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || |
|
+ dctx->key->key_alg == DST_ALG_ECDSA384); |
|
+ |
|
+ if (pk11_ctx != NULL) { |
|
+ (void) pkcs_C_DigestFinal(pk11_ctx->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ dctx->ctxdata.pk11_ctx = NULL; |
|
+ } |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11ecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) { |
|
+ CK_RV rv; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ |
|
+ REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 || |
|
+ dctx->key->key_alg == DST_ALG_ECDSA384); |
|
+ |
|
+ PK11_CALL(pkcs_C_DigestUpdate, |
|
+ (pk11_ctx->session, |
|
+ (CK_BYTE_PTR) data->base, |
|
+ (CK_ULONG) data->length), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11ecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_ECDSA, NULL, 0 }; |
|
+ CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_EC; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_EC_PARAMS, NULL, 0 }, |
|
+ { CKA_VALUE, NULL, 0 } |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ CK_BYTE digest[ISC_SHA384_DIGESTLENGTH]; |
|
+ CK_ULONG dgstlen; |
|
+ CK_ULONG siglen; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ dst_key_t *key = dctx->key; |
|
+ pk11_object_t *ec = key->keydata.pkey; |
|
+ isc_region_t r; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ unsigned int i; |
|
+ |
|
+ REQUIRE(key->key_alg == DST_ALG_ECDSA256 || |
|
+ key->key_alg == DST_ALG_ECDSA384); |
|
+ REQUIRE(ec != NULL); |
|
+ |
|
+ if (key->key_alg == DST_ALG_ECDSA256) { |
|
+ dgstlen = ISC_SHA256_DIGESTLENGTH; |
|
+ siglen = DNS_SIG_ECDSA256SIZE; |
|
+ } else { |
|
+ siglen = DNS_SIG_ECDSA384SIZE; |
|
+ dgstlen = ISC_SHA384_DIGESTLENGTH; |
|
+ } |
|
+ |
|
+ PK11_RET(pkcs_C_DigestFinal, |
|
+ (pk11_ctx->session, digest, &dgstlen), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ isc_buffer_availableregion(sig, &r); |
|
+ if (r.length < siglen) |
|
+ DST_RET(ISC_R_NOSPACE); |
|
+ |
|
+ if (ec->ontoken && (ec->object != CK_INVALID_HANDLE)) { |
|
+ pk11_ctx->ontoken = ec->ontoken; |
|
+ pk11_ctx->object = ec->object; |
|
+ goto token_key; |
|
+ } |
|
+ |
|
+ for (attr = pk11_attribute_first(ec); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(ec, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_EC_PARAMS: |
|
+ INSIST(keyTemplate[5].type == attr->type); |
|
+ keyTemplate[5].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[5].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[5].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[5].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_VALUE: |
|
+ INSIST(keyTemplate[6].type == attr->type); |
|
+ keyTemplate[6].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[6].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[6].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[6].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ } |
|
+ pk11_ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_ctx->ontoken = ISC_FALSE; |
|
+ PK11_RET(pkcs_C_CreateObject, |
|
+ (pk11_ctx->session, |
|
+ keyTemplate, (CK_ULONG) 7, |
|
+ &hKey), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ token_key: |
|
+ |
|
+ PK11_RET(pkcs_C_SignInit, |
|
+ (pk11_ctx->session, &mech, |
|
+ pk11_ctx->ontoken ? pk11_ctx->object : hKey), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ PK11_RET(pkcs_C_Sign, |
|
+ (pk11_ctx->session, |
|
+ digest, dgstlen, |
|
+ (CK_BYTE_PTR) r.base, &siglen), |
|
+ DST_R_SIGNFAILURE); |
|
+ |
|
+ isc_buffer_add(sig, (unsigned int) siglen); |
|
+ |
|
+ err: |
|
+ |
|
+ if (hKey != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); |
|
+ for (i = 5; i <= 6; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ dctx->ctxdata.pk11_ctx = NULL; |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11ecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_ECDSA, NULL, 0 }; |
|
+ CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_EC; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_EC_PARAMS, NULL, 0 }, |
|
+ { CKA_EC_POINT, NULL, 0 } |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ CK_BYTE digest[ISC_SHA384_DIGESTLENGTH]; |
|
+ CK_ULONG dgstlen; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ dst_key_t *key = dctx->key; |
|
+ pk11_object_t *ec = key->keydata.pkey; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ unsigned int i; |
|
+ |
|
+ REQUIRE(key->key_alg == DST_ALG_ECDSA256 || |
|
+ key->key_alg == DST_ALG_ECDSA384); |
|
+ REQUIRE(ec != NULL); |
|
+ |
|
+ if (key->key_alg == DST_ALG_ECDSA256) |
|
+ dgstlen = ISC_SHA256_DIGESTLENGTH; |
|
+ else |
|
+ dgstlen = ISC_SHA384_DIGESTLENGTH; |
|
+ |
|
+ PK11_RET(pkcs_C_DigestFinal, |
|
+ (pk11_ctx->session, digest, &dgstlen), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ for (attr = pk11_attribute_first(ec); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(ec, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_EC_PARAMS: |
|
+ INSIST(keyTemplate[5].type == attr->type); |
|
+ keyTemplate[5].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[5].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[5].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[5].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_EC_POINT: |
|
+ INSIST(keyTemplate[6].type == attr->type); |
|
+ keyTemplate[6].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[6].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[6].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[6].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ } |
|
+ pk11_ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_ctx->ontoken = ISC_FALSE; |
|
+ PK11_RET(pkcs_C_CreateObject, |
|
+ (pk11_ctx->session, |
|
+ keyTemplate, (CK_ULONG) 7, |
|
+ &hKey), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ PK11_RET(pkcs_C_VerifyInit, |
|
+ (pk11_ctx->session, &mech, hKey), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ PK11_RET(pkcs_C_Verify, |
|
+ (pk11_ctx->session, |
|
+ digest, dgstlen, |
|
+ (CK_BYTE_PTR) sig->base, (CK_ULONG) sig->length), |
|
+ DST_R_SIGNFAILURE); |
|
+ |
|
+ err: |
|
+ |
|
+ if (hKey != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, hKey); |
|
+ for (i = 5; i <= 6; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ dctx->ctxdata.pk11_ctx = NULL; |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_boolean_t |
|
+pkcs11ecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) { |
|
+ pk11_object_t *ec1, *ec2; |
|
+ CK_ATTRIBUTE *attr1, *attr2; |
|
+ |
|
+ ec1 = key1->keydata.pkey; |
|
+ ec2 = key2->keydata.pkey; |
|
+ |
|
+ if ((ec1 == NULL) && (ec2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((ec1 == NULL) || (ec2 == NULL)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(ec1, CKA_EC_PARAMS); |
|
+ attr2 = pk11_attribute_bytype(ec2, CKA_EC_PARAMS); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(ec1, CKA_EC_POINT); |
|
+ attr2 = pk11_attribute_bytype(ec2, CKA_EC_POINT); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(ec1, CKA_VALUE); |
|
+ attr2 = pk11_attribute_bytype(ec2, CKA_VALUE); |
|
+ if (((attr1 != NULL) || (attr2 != NULL)) && |
|
+ ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ if (!ec1->ontoken && !ec2->ontoken) |
|
+ return (ISC_TRUE); |
|
+ else if (ec1->ontoken || ec2->ontoken || |
|
+ (ec1->object != ec2->object)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ return (ISC_TRUE); |
|
+} |
|
+ |
|
+#define SETCURVE() \ |
|
+ if (key->key_alg == DST_ALG_ECDSA256) { \ |
|
+ attr->pValue = isc_mem_get(key->mctx, \ |
|
+ sizeof(pk11_ecc_prime256v1)); \ |
|
+ if (attr->pValue == NULL) \ |
|
+ DST_RET(ISC_R_NOMEMORY); \ |
|
+ memcpy(attr->pValue, \ |
|
+ pk11_ecc_prime256v1, sizeof(pk11_ecc_prime256v1)); \ |
|
+ attr->ulValueLen = sizeof(pk11_ecc_prime256v1); \ |
|
+ } else { \ |
|
+ attr->pValue = isc_mem_get(key->mctx, \ |
|
+ sizeof(pk11_ecc_secp384r1)); \ |
|
+ if (attr->pValue == NULL) \ |
|
+ DST_RET(ISC_R_NOMEMORY); \ |
|
+ memcpy(attr->pValue, \ |
|
+ pk11_ecc_secp384r1, sizeof(pk11_ecc_secp384r1)); \ |
|
+ attr->ulValueLen = sizeof(pk11_ecc_secp384r1); \ |
|
+ } |
|
+ |
|
+#define FREECURVE() \ |
|
+ if (attr->pValue != NULL) { \ |
|
+ memset(attr->pValue, 0, attr->ulValueLen); \ |
|
+ isc_mem_put(key->mctx, attr->pValue, attr->ulValueLen); \ |
|
+ attr->pValue = NULL; \ |
|
+ } |
|
+ |
|
+static isc_result_t |
|
+pkcs11ecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_EC_KEY_PAIR_GEN, NULL, 0 }; |
|
+ CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_EC; |
|
+ CK_ATTRIBUTE pubTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_EC_PARAMS, NULL, 0 } |
|
+ }; |
|
+ CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; |
|
+ CK_ATTRIBUTE privTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) } |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_object_t *ec; |
|
+ pk11_context_t *pk11_ctx; |
|
+ isc_result_t ret; |
|
+ |
|
+ REQUIRE(key->key_alg == DST_ALG_ECDSA256 || |
|
+ key->key_alg == DST_ALG_ECDSA384); |
|
+ UNUSED(unused); |
|
+ UNUSED(callback); |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, pk11_get_best_token(OP_EC)); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); |
|
+ if (ec == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(ec, 0, sizeof(*ec)); |
|
+ key->keydata.pkey = ec; |
|
+ ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); |
|
+ if (ec->repr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(ec->repr, 0, sizeof(*attr) * 3); |
|
+ ec->attrcnt = 3; |
|
+ |
|
+ attr = ec->repr; |
|
+ attr[0].type = CKA_EC_PARAMS; |
|
+ attr[1].type = CKA_EC_POINT; |
|
+ attr[2].type = CKA_VALUE; |
|
+ |
|
+ attr = &pubTemplate[5]; |
|
+ SETCURVE(); |
|
+ |
|
+ PK11_RET(pkcs_C_GenerateKeyPair, |
|
+ (pk11_ctx->session, &mech, |
|
+ pubTemplate, (CK_ULONG) 6, |
|
+ privTemplate, (CK_ULONG) 7, |
|
+ &pub, &priv), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ attr = &pubTemplate[5]; |
|
+ FREECURVE(); |
|
+ |
|
+ attr = ec->repr; |
|
+ SETCURVE(); |
|
+ |
|
+ attr++; |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, pub, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, pub, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ attr++; |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, priv, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, priv, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pkcs11ecdsa_destroy(key); |
|
+ if (priv != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); |
|
+ if (pub != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_boolean_t |
|
+pkcs11ecdsa_isprivate(const dst_key_t *key) { |
|
+ pk11_object_t *ec = key->keydata.pkey; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ if (ec == NULL) |
|
+ return (ISC_FALSE); |
|
+ attr = pk11_attribute_bytype(ec, CKA_VALUE); |
|
+ return (ISC_TF((attr != NULL) || ec->ontoken)); |
|
+} |
|
+ |
|
+static void |
|
+pkcs11ecdsa_destroy(dst_key_t *key) { |
|
+ pk11_object_t *ec = key->keydata.pkey; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ if (ec == NULL) |
|
+ return; |
|
+ |
|
+ INSIST((ec->object == CK_INVALID_HANDLE) || ec->ontoken); |
|
+ |
|
+ for (attr = pk11_attribute_first(ec); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(ec, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_LABEL: |
|
+ case CKA_ID: |
|
+ case CKA_EC_PARAMS: |
|
+ case CKA_EC_POINT: |
|
+ case CKA_VALUE: |
|
+ FREECURVE(); |
|
+ break; |
|
+ } |
|
+ if (ec->repr != NULL) { |
|
+ memset(ec->repr, 0, ec->attrcnt * sizeof(*attr)); |
|
+ isc_mem_put(key->mctx, |
|
+ ec->repr, |
|
+ ec->attrcnt * sizeof(*attr)); |
|
+ } |
|
+ memset(ec, 0, sizeof(*ec)); |
|
+ isc_mem_put(key->mctx, ec, sizeof(*ec)); |
|
+ key->keydata.pkey = NULL; |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11ecdsa_todns(const dst_key_t *key, isc_buffer_t *data) { |
|
+ pk11_object_t *ec; |
|
+ isc_region_t r; |
|
+ unsigned int len; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ REQUIRE(key->keydata.pkey != NULL); |
|
+ |
|
+ if (key->key_alg == DST_ALG_ECDSA256) |
|
+ len = DNS_KEY_ECDSA256SIZE; |
|
+ else |
|
+ len = DNS_KEY_ECDSA384SIZE; |
|
+ |
|
+ ec = key->keydata.pkey; |
|
+ attr = pk11_attribute_bytype(ec, CKA_EC_POINT); |
|
+ if ((attr == NULL) || |
|
+ (attr->ulValueLen != len + 3) || |
|
+ (((CK_BYTE_PTR) attr->pValue)[0] != TAG_OCTECT_STRING) || |
|
+ (((CK_BYTE_PTR) attr->pValue)[1] != len + 1) || |
|
+ (((CK_BYTE_PTR) attr->pValue)[2] != UNCOMPRESSED)) |
|
+ return (ISC_R_FAILURE); |
|
+ |
|
+ isc_buffer_availableregion(data, &r); |
|
+ if (r.length < len) |
|
+ return (ISC_R_NOSPACE); |
|
+ memcpy(r.base, (CK_BYTE_PTR) attr->pValue + 3, len); |
|
+ isc_buffer_add(data, len); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11ecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) { |
|
+ pk11_object_t *ec; |
|
+ isc_region_t r; |
|
+ unsigned int len; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ REQUIRE(key->key_alg == DST_ALG_ECDSA256 || |
|
+ key->key_alg == DST_ALG_ECDSA384); |
|
+ |
|
+ if (key->key_alg == DST_ALG_ECDSA256) |
|
+ len = DNS_KEY_ECDSA256SIZE; |
|
+ else |
|
+ len = DNS_KEY_ECDSA384SIZE; |
|
+ |
|
+ isc_buffer_remainingregion(data, &r); |
|
+ if (r.length == 0) |
|
+ return (ISC_R_SUCCESS); |
|
+ if (r.length != len) |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ |
|
+ ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); |
|
+ if (ec == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ memset(ec, 0, sizeof(*ec)); |
|
+ ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); |
|
+ if (ec->repr == NULL) |
|
+ goto nomemory; |
|
+ ec->attrcnt = 2; |
|
+ |
|
+ attr = ec->repr; |
|
+ attr->type = CKA_EC_PARAMS; |
|
+ if (key->key_alg == DST_ALG_ECDSA256) { |
|
+ attr->pValue = |
|
+ isc_mem_get(key->mctx, sizeof(pk11_ecc_prime256v1)); |
|
+ if (attr->pValue == NULL) |
|
+ goto nomemory; |
|
+ memcpy(attr->pValue, |
|
+ pk11_ecc_prime256v1, sizeof(pk11_ecc_prime256v1)); |
|
+ attr->ulValueLen = sizeof(pk11_ecc_prime256v1); |
|
+ } else { |
|
+ attr->pValue = |
|
+ isc_mem_get(key->mctx, sizeof(pk11_ecc_secp384r1)); |
|
+ if (attr->pValue == NULL) |
|
+ goto nomemory; |
|
+ memcpy(attr->pValue, |
|
+ pk11_ecc_secp384r1, sizeof(pk11_ecc_secp384r1)); |
|
+ attr->ulValueLen = sizeof(pk11_ecc_secp384r1); |
|
+ } |
|
+ |
|
+ attr++; |
|
+ attr->type = CKA_EC_POINT; |
|
+ attr->pValue = isc_mem_get(key->mctx, len + 3); |
|
+ if (attr->pValue == NULL) |
|
+ goto nomemory; |
|
+ ((CK_BYTE_PTR) attr->pValue)[0] = TAG_OCTECT_STRING; |
|
+ ((CK_BYTE_PTR) attr->pValue)[1] = len + 1; |
|
+ ((CK_BYTE_PTR) attr->pValue)[2] = UNCOMPRESSED; |
|
+ memcpy((CK_BYTE_PTR) attr->pValue + 3, r.base, len); |
|
+ attr->ulValueLen = len + 3; |
|
+ |
|
+ isc_buffer_forward(data, len); |
|
+ key->keydata.pkey = ec; |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ nomemory: |
|
+ for (attr = pk11_attribute_first(ec); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(ec, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_EC_PARAMS: |
|
+ case CKA_EC_POINT: |
|
+ FREECURVE(); |
|
+ break; |
|
+ } |
|
+ if (ec->repr != NULL) { |
|
+ memset(ec->repr, 0, ec->attrcnt * sizeof(*attr)); |
|
+ isc_mem_put(key->mctx, |
|
+ ec->repr, |
|
+ ec->attrcnt * sizeof(*attr)); |
|
+ } |
|
+ memset(ec, 0, sizeof(*ec)); |
|
+ isc_mem_put(key->mctx, ec, sizeof(*ec)); |
|
+ return (ISC_R_NOMEMORY); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11ecdsa_tofile(const dst_key_t *key, const char *directory) { |
|
+ isc_result_t ret; |
|
+ pk11_object_t *ec; |
|
+ dst_private_t priv; |
|
+ unsigned char *buf = NULL; |
|
+ unsigned int i = 0; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ if (key->keydata.pkey == NULL) |
|
+ return (DST_R_NULLKEY); |
|
+ |
|
+ if (key->external) { |
|
+ priv.nelements = 0; |
|
+ return (dst__privstruct_writefile(key, &priv, directory)); |
|
+ } |
|
+ |
|
+ ec = key->keydata.pkey; |
|
+ attr = pk11_attribute_bytype(ec, CKA_VALUE); |
|
+ if (attr != NULL) { |
|
+ buf = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (buf == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ priv.elements[i].tag = TAG_ECDSA_PRIVATEKEY; |
|
+ priv.elements[i].length = (unsigned short) attr->ulValueLen; |
|
+ memcpy(buf, attr->pValue, attr->ulValueLen); |
|
+ priv.elements[i].data = buf; |
|
+ i++; |
|
+ } |
|
+ |
|
+ if (key->engine != NULL) { |
|
+ priv.elements[i].tag = TAG_ECDSA_ENGINE; |
|
+ priv.elements[i].length = strlen(key->engine) + 1; |
|
+ priv.elements[i].data = (unsigned char *)key->engine; |
|
+ i++; |
|
+ } |
|
+ |
|
+ if (key->label != NULL) { |
|
+ priv.elements[i].tag = TAG_ECDSA_LABEL; |
|
+ priv.elements[i].length = strlen(key->label) + 1; |
|
+ priv.elements[i].data = (unsigned char *)key->label; |
|
+ i++; |
|
+ } |
|
+ |
|
+ priv.nelements = i; |
|
+ ret = dst__privstruct_writefile(key, &priv, directory); |
|
+ |
|
+ if (buf != NULL) { |
|
+ memset(buf, 0, attr->ulValueLen); |
|
+ isc_mem_put(key->mctx, buf, attr->ulValueLen); |
|
+ } |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11ecdsa_fetch(dst_key_t *key, const char *engine, const char *label, |
|
+ dst_key_t *pub) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_EC; |
|
+ CK_ATTRIBUTE searchTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_LABEL, NULL, 0 } |
|
+ }; |
|
+ CK_ULONG cnt; |
|
+ CK_ATTRIBUTE *attr; |
|
+ CK_ATTRIBUTE *pubattr; |
|
+ pk11_object_t *ec; |
|
+ pk11_object_t *pubec; |
|
+ pk11_context_t *pk11_ctx = NULL; |
|
+ isc_result_t ret; |
|
+ |
|
+ if (label == NULL) |
|
+ return (DST_R_NOENGINE); |
|
+ |
|
+ ec = key->keydata.pkey; |
|
+ pubec = pub->keydata.pkey; |
|
+ |
|
+ ec->object = CK_INVALID_HANDLE; |
|
+ ec->ontoken = ISC_TRUE; |
|
+ ec->reqlogon = ISC_TRUE; |
|
+ ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); |
|
+ if (ec->repr == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ memset(ec->repr, 0, sizeof(*attr) * 2); |
|
+ ec->attrcnt = 2; |
|
+ attr = ec->repr; |
|
+ |
|
+ attr->type = CKA_EC_PARAMS; |
|
+ pubattr = pk11_attribute_bytype(pubec, CKA_EC_PARAMS); |
|
+ attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(attr->pValue, pubattr->pValue, pubattr->ulValueLen); |
|
+ attr->ulValueLen = pubattr->ulValueLen; |
|
+ attr++; |
|
+ |
|
+ attr->type = CKA_EC_POINT; |
|
+ pubattr = pk11_attribute_bytype(pubec, CKA_EC_POINT); |
|
+ attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(attr->pValue, pubattr->pValue, pubattr->ulValueLen); |
|
+ attr->ulValueLen = pubattr->ulValueLen; |
|
+ |
|
+ ret = pk11_parse_uri(ec, label, key->mctx, OP_EC); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, |
|
+ ec->reqlogon, NULL, ec->slot); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ attr = pk11_attribute_bytype(ec, CKA_LABEL); |
|
+ if (attr == NULL) { |
|
+ attr = pk11_attribute_bytype(ec, CKA_ID); |
|
+ INSIST(attr != NULL); |
|
+ searchTemplate[3].type = CKA_ID; |
|
+ } |
|
+ searchTemplate[3].pValue = attr->pValue; |
|
+ searchTemplate[3].ulValueLen = attr->ulValueLen; |
|
+ |
|
+ PK11_RET(pkcs_C_FindObjectsInit, |
|
+ (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ PK11_RET(pkcs_C_FindObjects, |
|
+ (pk11_ctx->session, &ec->object, (CK_ULONG) 1, &cnt), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); |
|
+ if (cnt == 0) |
|
+ DST_RET(ISC_R_NOTFOUND); |
|
+ if (cnt > 1) |
|
+ DST_RET(ISC_R_EXISTS); |
|
+ |
|
+ if (engine != NULL) { |
|
+ key->engine = isc_mem_strdup(key->mctx, engine); |
|
+ if (key->engine == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ } |
|
+ |
|
+ key->label = isc_mem_strdup(key->mctx, label); |
|
+ if (key->label == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ if (pk11_ctx != NULL) { |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ } |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11ecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
+ dst_private_t priv; |
|
+ isc_result_t ret; |
|
+ pk11_object_t *ec = NULL; |
|
+ CK_ATTRIBUTE *attr, *pattr; |
|
+ isc_mem_t *mctx = key->mctx; |
|
+ unsigned int i; |
|
+ const char *engine = NULL, *label = NULL; |
|
+ |
|
+ REQUIRE(key->key_alg == DST_ALG_ECDSA256 || |
|
+ key->key_alg == DST_ALG_ECDSA384); |
|
+ |
|
+ if ((pub == NULL) || (pub->keydata.pkey == NULL)) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ |
|
+ /* read private key file */ |
|
+ ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ return (ret); |
|
+ |
|
+ if (key->external) { |
|
+ if (priv.nelements != 0) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ |
|
+ key->keydata.pkey = pub->keydata.pkey; |
|
+ pub->keydata.pkey = NULL; |
|
+ key->key_size = pub->key_size; |
|
+ |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ } |
|
+ |
|
+ for (i = 0; i < priv.nelements; i++) { |
|
+ switch (priv.elements[i].tag) { |
|
+ case TAG_ECDSA_ENGINE: |
|
+ engine = (char *)priv.elements[i].data; |
|
+ break; |
|
+ case TAG_ECDSA_LABEL: |
|
+ label = (char *)priv.elements[i].data; |
|
+ break; |
|
+ default: |
|
+ break; |
|
+ } |
|
+ } |
|
+ ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); |
|
+ if (ec == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(ec, 0, sizeof(*ec)); |
|
+ key->keydata.pkey = ec; |
|
+ |
|
+ /* Is this key is stored in a HSM? See if we can fetch it. */ |
|
+ if ((label != NULL) || (engine != NULL)) { |
|
+ ret = pkcs11ecdsa_fetch(key, engine, label, pub); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ return (ret); |
|
+ } |
|
+ |
|
+ ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 3); |
|
+ if (ec->repr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(ec->repr, 0, sizeof(*attr) * 3); |
|
+ ec->attrcnt = 3; |
|
+ |
|
+ attr = ec->repr; |
|
+ attr->type = CKA_EC_PARAMS; |
|
+ pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_EC_PARAMS); |
|
+ INSIST(pattr != NULL); |
|
+ attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(attr->pValue, pattr->pValue, pattr->ulValueLen); |
|
+ attr->ulValueLen = pattr->ulValueLen; |
|
+ |
|
+ attr++; |
|
+ attr->type = CKA_EC_POINT; |
|
+ pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_EC_POINT); |
|
+ INSIST(pattr != NULL); |
|
+ attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(attr->pValue, pattr->pValue, pattr->ulValueLen); |
|
+ attr->ulValueLen = pattr->ulValueLen; |
|
+ |
|
+ attr++; |
|
+ attr->type = CKA_VALUE; |
|
+ attr->pValue = isc_mem_get(key->mctx, priv.elements[0].length); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(attr->pValue, priv.elements[0].data, priv.elements[0].length); |
|
+ attr->ulValueLen = priv.elements[0].length; |
|
+ |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pkcs11ecdsa_destroy(key); |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11ecdsa_fromlabel(dst_key_t *key, const char *engine, const char *label, |
|
+ const char *pin) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_EC; |
|
+ CK_ATTRIBUTE searchTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_LABEL, NULL, 0 } |
|
+ }; |
|
+ CK_ULONG cnt; |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_object_t *ec; |
|
+ pk11_context_t *pk11_ctx = NULL; |
|
+ isc_result_t ret; |
|
+ unsigned int i; |
|
+ |
|
+ UNUSED(pin); |
|
+ |
|
+ ec = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*ec)); |
|
+ if (ec == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ memset(ec, 0, sizeof(*ec)); |
|
+ ec->object = CK_INVALID_HANDLE; |
|
+ ec->ontoken = ISC_TRUE; |
|
+ ec->reqlogon = ISC_TRUE; |
|
+ key->keydata.pkey = ec; |
|
+ |
|
+ ec->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); |
|
+ if (ec->repr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(ec->repr, 0, sizeof(*attr) * 2); |
|
+ ec->attrcnt = 2; |
|
+ attr = ec->repr; |
|
+ attr[0].type = CKA_EC_PARAMS; |
|
+ attr[1].type = CKA_EC_POINT; |
|
+ |
|
+ ret = pk11_parse_uri(ec, label, key->mctx, OP_EC); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_EC, ISC_TRUE, ISC_FALSE, |
|
+ ec->reqlogon, NULL, ec->slot); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ attr = pk11_attribute_bytype(ec, CKA_LABEL); |
|
+ if (attr == NULL) { |
|
+ attr = pk11_attribute_bytype(ec, CKA_ID); |
|
+ INSIST(attr != NULL); |
|
+ searchTemplate[3].type = CKA_ID; |
|
+ } |
|
+ searchTemplate[3].pValue = attr->pValue; |
|
+ searchTemplate[3].ulValueLen = attr->ulValueLen; |
|
+ |
|
+ PK11_RET(pkcs_C_FindObjectsInit, |
|
+ (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ PK11_RET(pkcs_C_FindObjects, |
|
+ (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); |
|
+ if (cnt == 0) |
|
+ DST_RET(ISC_R_NOTFOUND); |
|
+ if (cnt > 1) |
|
+ DST_RET(ISC_R_EXISTS); |
|
+ |
|
+ attr = ec->repr; |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, hKey, attr, 2), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ for (i = 0; i <= 1; i++) { |
|
+ attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); |
|
+ if (attr[i].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr[i].pValue, 0, attr[i].ulValueLen); |
|
+ } |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, hKey, attr, 2), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ keyClass = CKO_PRIVATE_KEY; |
|
+ PK11_RET(pkcs_C_FindObjectsInit, |
|
+ (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ PK11_RET(pkcs_C_FindObjects, |
|
+ (pk11_ctx->session, &ec->object, (CK_ULONG) 1, &cnt), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); |
|
+ if (cnt == 0) |
|
+ DST_RET(ISC_R_NOTFOUND); |
|
+ if (cnt > 1) |
|
+ DST_RET(ISC_R_EXISTS); |
|
+ |
|
+ if (engine != NULL) { |
|
+ key->engine = isc_mem_strdup(key->mctx, engine); |
|
+ if (key->engine == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ } |
|
+ |
|
+ key->label = isc_mem_strdup(key->mctx, label); |
|
+ if (key->label == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pkcs11ecdsa_destroy(key); |
|
+ if (pk11_ctx != NULL) { |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ } |
|
+ return (ret); |
|
+} |
|
+ |
|
+static dst_func_t pkcs11ecdsa_functions = { |
|
+ pkcs11ecdsa_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
+ pkcs11ecdsa_destroyctx, |
|
+ pkcs11ecdsa_adddata, |
|
+ pkcs11ecdsa_sign, |
|
+ pkcs11ecdsa_verify, |
|
+ NULL, /*%< verify2 */ |
|
+ NULL, /*%< computesecret */ |
|
+ pkcs11ecdsa_compare, |
|
+ NULL, /*%< paramcompare */ |
|
+ pkcs11ecdsa_generate, |
|
+ pkcs11ecdsa_isprivate, |
|
+ pkcs11ecdsa_destroy, |
|
+ pkcs11ecdsa_todns, |
|
+ pkcs11ecdsa_fromdns, |
|
+ pkcs11ecdsa_tofile, |
|
+ pkcs11ecdsa_parse, |
|
+ NULL, /*%< cleanup */ |
|
+ pkcs11ecdsa_fromlabel, |
|
+ NULL, /*%< dump */ |
|
+ NULL, /*%< restore */ |
|
+}; |
|
+ |
|
+isc_result_t |
|
+dst__pkcs11ecdsa_init(dst_func_t **funcp) { |
|
+ REQUIRE(funcp != NULL); |
|
+ if (*funcp == NULL) |
|
+ *funcp = &pkcs11ecdsa_functions; |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+#else /* PKCS11CRYPTO && HAVE_PKCS11_ECDSA */ |
|
+ |
|
+#include <isc/util.h> |
|
+ |
|
+EMPTY_TRANSLATION_UNIT |
|
+ |
|
+#endif /* PKCS11CRYPTO && HAVE_PKCS11_ECDSA */ |
|
+/*! \file */ |
|
diff --git a/lib/dns/pkcs11gost_link.c b/lib/dns/pkcs11gost_link.c |
|
new file mode 100644 |
|
index 0000000..c03b285 |
|
--- /dev/null |
|
+++ b/lib/dns/pkcs11gost_link.c |
|
@@ -0,0 +1,949 @@ |
|
+/* |
|
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#if defined(PKCS11CRYPTO) && defined(HAVE_PKCS11_GOST) |
|
+ |
|
+#include <isc/entropy.h> |
|
+#include <isc/mem.h> |
|
+#include <isc/sha2.h> |
|
+#include <isc/string.h> |
|
+#include <isc/util.h> |
|
+ |
|
+#include <dns/keyvalues.h> |
|
+#include <dns/log.h> |
|
+#include <dst/result.h> |
|
+ |
|
+#include "dst_internal.h" |
|
+#include "dst_parse.h" |
|
+#include "dst_pkcs11.h" |
|
+#include "dst_gost.h" |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/internal.h> |
|
+#define WANT_GOST_PARAMS |
|
+#include <pk11/constants.h> |
|
+ |
|
+#include <pkcs11/pkcs11.h> |
|
+ |
|
+/* |
|
+ * RU CryptoPro GOST keys: |
|
+ * mechanisms: |
|
+ * CKM_GOSTR3411 |
|
+ * CKM_GOSTR3410_WITH_GOSTR3411 |
|
+ * CKM_GOSTR3410_KEY_PAIR_GEN |
|
+ * domain parameters: |
|
+ * CKA_GOSTR3410_PARAMS (fixed BER OID 1.2.643.2.2.35.1) |
|
+ * CKA_GOSTR3411_PARAMS (fixed BER OID 1.2.643.2.2.30.1) |
|
+ * CKA_GOST28147_PARAMS (optional, don't use) |
|
+ * public keys: |
|
+ * object class CKO_PUBLIC_KEY |
|
+ * key type CKK_GOSTR3410 |
|
+ * attribute CKA_VALUE (point Q) |
|
+ * attribute CKA_GOSTR3410_PARAMS |
|
+ * attribute CKA_GOSTR3411_PARAMS |
|
+ * attribute CKA_GOST28147_PARAMS |
|
+ * private keys: |
|
+ * object class CKO_PRIVATE_KEY |
|
+ * key type CKK_GOSTR3410 |
|
+ * attribute CKA_VALUE (big int d) |
|
+ * attribute CKA_GOSTR3410_PARAMS |
|
+ * attribute CKA_GOSTR3411_PARAMS |
|
+ * attribute CKA_GOST28147_PARAMS |
|
+ * point format: <x> <y> (little endian) |
|
+ */ |
|
+ |
|
+#define CKA_VALUE2 CKA_PRIVATE_EXPONENT |
|
+ |
|
+#define ISC_GOST_SIGNATURELENGTH 64 |
|
+#define ISC_GOST_PUBKEYLENGTH 64 |
|
+ |
|
+/* HASH methods */ |
|
+ |
|
+isc_result_t |
|
+isc_gost_init(isc_gost_t *ctx) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_GOSTR3411, NULL, 0 }; |
|
+ int ret = ISC_R_SUCCESS; |
|
+ |
|
+ ret = pk11_get_session(ctx, OP_GOST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ return (ret); |
|
+ PK11_CALL(pkcs_C_DigestInit, (ctx->session, &mech), ISC_R_FAILURE); |
|
+ return (ret); |
|
+} |
|
+ |
|
+void |
|
+isc_gost_invalidate(isc_gost_t *ctx) { |
|
+ CK_BYTE garbage[ISC_GOST_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_GOST_DIGESTLENGTH; |
|
+ |
|
+ if (ctx->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_DigestFinal(ctx->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
+isc_result_t |
|
+isc_gost_update(isc_gost_t *ctx, const unsigned char *buf, unsigned int len) { |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ int ret = ISC_R_SUCCESS; |
|
+ |
|
+ DE_CONST(buf, pPart); |
|
+ PK11_CALL(pkcs_C_DigestUpdate, |
|
+ (ctx->session, pPart, (CK_ULONG) len), |
|
+ ISC_R_FAILURE); |
|
+ return (ret); |
|
+} |
|
+ |
|
+isc_result_t |
|
+isc_gost_final(isc_gost_t *ctx, unsigned char *digest) { |
|
+ CK_RV rv; |
|
+ CK_ULONG len = ISC_GOST_DIGESTLENGTH; |
|
+ int ret = ISC_R_SUCCESS; |
|
+ |
|
+ PK11_CALL(pkcs_C_DigestFinal, |
|
+ (ctx->session, (CK_BYTE_PTR) digest, &len), |
|
+ ISC_R_FAILURE); |
|
+ pk11_return_session(ctx); |
|
+ return (ret); |
|
+} |
|
+ |
|
+/* DST methods */ |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+#define DST_RET(a) {ret = a; goto err;} |
|
+ |
|
+static isc_result_t pkcs11gost_todns(const dst_key_t *key, isc_buffer_t *data); |
|
+static void pkcs11gost_destroy(dst_key_t *key); |
|
+ |
|
+static isc_result_t |
|
+pkcs11gost_createctx_sign(dst_key_t *key, dst_context_t *dctx) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_GOSTR3410; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_VALUE, NULL, 0 }, |
|
+ { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, |
|
+ (CK_ULONG) sizeof(pk11_gost_a_paramset) }, |
|
+ { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, |
|
+ (CK_ULONG) sizeof(pk11_gost_paramset) } |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_object_t *gost; |
|
+ pk11_context_t *pk11_ctx; |
|
+ isc_result_t ret; |
|
+ unsigned int i; |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ gost = key->keydata.pkey; |
|
+ if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) { |
|
+ pk11_ctx->ontoken = gost->ontoken; |
|
+ pk11_ctx->object = gost->object; |
|
+ goto token_key; |
|
+ } |
|
+ |
|
+ for (attr = pk11_attribute_first(gost); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(gost, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_VALUE2: |
|
+ INSIST(keyTemplate[6].type == CKA_VALUE); |
|
+ keyTemplate[6].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[6].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[6].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[6].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ } |
|
+ pk11_ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_ctx->ontoken = ISC_FALSE; |
|
+ PK11_RET(pkcs_C_CreateObject, |
|
+ (pk11_ctx->session, |
|
+ keyTemplate, (CK_ULONG) 9, |
|
+ &pk11_ctx->object), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ token_key: |
|
+ |
|
+ PK11_RET(pkcs_C_SignInit, |
|
+ (pk11_ctx->session, &mech, pk11_ctx->object), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ dctx->ctxdata.pk11_ctx = pk11_ctx; |
|
+ |
|
+ for (i = 6; i <= 6; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); |
|
+ for (i = 6; i <= 6; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11gost_createctx_verify(dst_key_t *key, dst_context_t *dctx) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_GOSTR3410; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_VALUE, NULL, 0 }, |
|
+ { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, |
|
+ (CK_ULONG) sizeof(pk11_gost_a_paramset) }, |
|
+ { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, |
|
+ (CK_ULONG) sizeof(pk11_gost_paramset) } |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_object_t *gost; |
|
+ pk11_context_t *pk11_ctx; |
|
+ isc_result_t ret; |
|
+ unsigned int i; |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ gost = key->keydata.pkey; |
|
+ if (gost->ontoken && (gost->object != CK_INVALID_HANDLE)) { |
|
+ pk11_ctx->ontoken = gost->ontoken; |
|
+ pk11_ctx->object = gost->object; |
|
+ goto token_key; |
|
+ } |
|
+ |
|
+ for (attr = pk11_attribute_first(gost); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(gost, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_VALUE: |
|
+ INSIST(keyTemplate[5].type == attr->type); |
|
+ keyTemplate[5].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[5].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[5].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[5].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ } |
|
+ pk11_ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_ctx->ontoken = ISC_FALSE; |
|
+ PK11_RET(pkcs_C_CreateObject, |
|
+ (pk11_ctx->session, |
|
+ keyTemplate, (CK_ULONG) 8, |
|
+ &pk11_ctx->object), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ token_key: |
|
+ |
|
+ PK11_RET(pkcs_C_VerifyInit, |
|
+ (pk11_ctx->session, &mech, pk11_ctx->object), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ dctx->ctxdata.pk11_ctx = pk11_ctx; |
|
+ |
|
+ for (i = 5; i <= 5; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object); |
|
+ for (i = 5; i <= 5; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11gost_createctx(dst_key_t *key, dst_context_t *dctx) { |
|
+ if (dctx->use == DO_SIGN) |
|
+ return (pkcs11gost_createctx_sign(key, dctx)); |
|
+ else |
|
+ return (pkcs11gost_createctx_verify(key, dctx)); |
|
+} |
|
+ |
|
+static void |
|
+pkcs11gost_destroyctx(dst_context_t *dctx) { |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ |
|
+ if (pk11_ctx != NULL) { |
|
+ if (!pk11_ctx->ontoken && |
|
+ (pk11_ctx->object != CK_INVALID_HANDLE)) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, |
|
+ pk11_ctx->object); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ dctx->ctxdata.pk11_ctx = NULL; |
|
+ } |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11gost_adddata(dst_context_t *dctx, const isc_region_t *data) { |
|
+ CK_RV rv; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ |
|
+ if (dctx->use == DO_SIGN) |
|
+ PK11_CALL(pkcs_C_SignUpdate, |
|
+ (pk11_ctx->session, |
|
+ (CK_BYTE_PTR) data->base, |
|
+ (CK_ULONG) data->length), |
|
+ ISC_R_FAILURE); |
|
+ else |
|
+ PK11_CALL(pkcs_C_VerifyUpdate, |
|
+ (pk11_ctx->session, |
|
+ (CK_BYTE_PTR) data->base, |
|
+ (CK_ULONG) data->length), |
|
+ ISC_R_FAILURE); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11gost_sign(dst_context_t *dctx, isc_buffer_t *sig) { |
|
+ CK_RV rv; |
|
+ CK_ULONG siglen = ISC_GOST_SIGNATURELENGTH; |
|
+ isc_region_t r; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ |
|
+ isc_buffer_availableregion(sig, &r); |
|
+ if (r.length < ISC_GOST_SIGNATURELENGTH) |
|
+ return (ISC_R_NOSPACE); |
|
+ |
|
+ PK11_RET(pkcs_C_SignFinal, |
|
+ (pk11_ctx->session, (CK_BYTE_PTR) r.base, &siglen), |
|
+ DST_R_SIGNFAILURE); |
|
+ if (siglen != ISC_GOST_SIGNATURELENGTH) |
|
+ return (DST_R_SIGNFAILURE); |
|
+ |
|
+ isc_buffer_add(sig, ISC_GOST_SIGNATURELENGTH); |
|
+ |
|
+ err: |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11gost_verify(dst_context_t *dctx, const isc_region_t *sig) { |
|
+ CK_RV rv; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ |
|
+ PK11_CALL(pkcs_C_VerifyFinal, |
|
+ (pk11_ctx->session, |
|
+ (CK_BYTE_PTR) sig->base, |
|
+ (CK_ULONG) sig->length), |
|
+ DST_R_VERIFYFAILURE); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_boolean_t |
|
+pkcs11gost_compare(const dst_key_t *key1, const dst_key_t *key2) { |
|
+ pk11_object_t *gost1, *gost2; |
|
+ CK_ATTRIBUTE *attr1, *attr2; |
|
+ |
|
+ gost1 = key1->keydata.pkey; |
|
+ gost2 = key2->keydata.pkey; |
|
+ |
|
+ if ((gost1 == NULL) && (gost2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((gost1 == NULL) || (gost2 == NULL)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(gost1, CKA_VALUE); |
|
+ attr2 = pk11_attribute_bytype(gost2, CKA_VALUE); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(gost1, CKA_VALUE2); |
|
+ attr2 = pk11_attribute_bytype(gost2, CKA_VALUE2); |
|
+ if (((attr1 != NULL) || (attr2 != NULL)) && |
|
+ ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ if (!gost1->ontoken && !gost2->ontoken) |
|
+ return (ISC_TRUE); |
|
+ else if (gost1->ontoken || gost2->ontoken || |
|
+ (gost1->object != gost2->object)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ return (ISC_TRUE); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11gost_generate(dst_key_t *key, int unused, void (*callback)(int)) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_GOSTR3410_KEY_PAIR_GEN, NULL, 0 }; |
|
+ CK_KEY_TYPE keyType = CKK_GOSTR3410; |
|
+ CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; |
|
+ CK_ATTRIBUTE pubTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset, |
|
+ (CK_ULONG) sizeof(pk11_gost_a_paramset) }, |
|
+ { CKA_GOSTR3411_PARAMS, pk11_gost_paramset, |
|
+ (CK_ULONG) sizeof(pk11_gost_paramset) } |
|
+ }; |
|
+ CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY; |
|
+ CK_ATTRIBUTE privTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_object_t *gost; |
|
+ pk11_context_t *pk11_ctx; |
|
+ isc_result_t ret; |
|
+ |
|
+ UNUSED(unused); |
|
+ UNUSED(callback); |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_GOST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, pk11_get_best_token(OP_GOST)); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ PK11_RET(pkcs_C_GenerateKeyPair, |
|
+ (pk11_ctx->session, &mech, |
|
+ pubTemplate, (CK_ULONG) 7, |
|
+ privTemplate, (CK_ULONG) 7, |
|
+ &pub, &priv), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); |
|
+ if (gost == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(gost, 0, sizeof(*gost)); |
|
+ key->keydata.pkey = gost; |
|
+ gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, |
|
+ sizeof(*attr) * 2); |
|
+ if (gost->repr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(gost->repr, 0, sizeof(*attr) * 2); |
|
+ gost->attrcnt = 2; |
|
+ |
|
+ attr = gost->repr; |
|
+ attr[0].type = CKA_VALUE; |
|
+ attr[1].type = CKA_VALUE2; |
|
+ |
|
+ attr = gost->repr; |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, pub, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, pub, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ attr++; |
|
+ attr->type = CKA_VALUE; |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, priv, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, priv, attr, 1), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ attr->type = CKA_VALUE2; |
|
+ |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pkcs11gost_destroy(key); |
|
+ if (priv != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); |
|
+ if (pub != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_boolean_t |
|
+pkcs11gost_isprivate(const dst_key_t *key) { |
|
+ pk11_object_t *gost = key->keydata.pkey; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ if (gost == NULL) |
|
+ return (ISC_FALSE); |
|
+ attr = pk11_attribute_bytype(gost, CKA_VALUE2); |
|
+ return (ISC_TF((attr != NULL) || gost->ontoken)); |
|
+} |
|
+ |
|
+static void |
|
+pkcs11gost_destroy(dst_key_t *key) { |
|
+ pk11_object_t *gost = key->keydata.pkey; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ if (gost == NULL) |
|
+ return; |
|
+ |
|
+ INSIST((gost->object == CK_INVALID_HANDLE) || gost->ontoken); |
|
+ |
|
+ for (attr = pk11_attribute_first(gost); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(gost, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_VALUE: |
|
+ case CKA_VALUE2: |
|
+ if (attr->pValue != NULL) { |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ } |
|
+ break; |
|
+ } |
|
+ if (gost->repr != NULL) { |
|
+ memset(gost->repr, 0, gost->attrcnt * sizeof(*attr)); |
|
+ isc_mem_put(key->mctx, |
|
+ gost->repr, |
|
+ gost->attrcnt * sizeof(*attr)); |
|
+ } |
|
+ memset(gost, 0, sizeof(*gost)); |
|
+ isc_mem_put(key->mctx, gost, sizeof(*gost)); |
|
+ key->keydata.pkey = NULL; |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11gost_todns(const dst_key_t *key, isc_buffer_t *data) { |
|
+ pk11_object_t *gost; |
|
+ isc_region_t r; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ REQUIRE(key->keydata.pkey != NULL); |
|
+ |
|
+ gost = key->keydata.pkey; |
|
+ attr = pk11_attribute_bytype(gost, CKA_VALUE); |
|
+ if ((attr == NULL) || (attr->ulValueLen != ISC_GOST_PUBKEYLENGTH)) |
|
+ return (ISC_R_FAILURE); |
|
+ |
|
+ isc_buffer_availableregion(data, &r); |
|
+ if (r.length < ISC_GOST_PUBKEYLENGTH) |
|
+ return (ISC_R_NOSPACE); |
|
+ memcpy(r.base, (CK_BYTE_PTR) attr->pValue, ISC_GOST_PUBKEYLENGTH); |
|
+ isc_buffer_add(data, ISC_GOST_PUBKEYLENGTH); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11gost_fromdns(dst_key_t *key, isc_buffer_t *data) { |
|
+ pk11_object_t *gost; |
|
+ isc_region_t r; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ isc_buffer_remainingregion(data, &r); |
|
+ if (r.length == 0) |
|
+ return (ISC_R_SUCCESS); |
|
+ if (r.length != ISC_GOST_PUBKEYLENGTH) |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ |
|
+ gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); |
|
+ if (gost == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ memset(gost, 0, sizeof(*gost)); |
|
+ gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr)); |
|
+ if (gost->repr == NULL) |
|
+ goto nomemory; |
|
+ gost->attrcnt = 1; |
|
+ |
|
+ attr = gost->repr; |
|
+ attr->type = CKA_VALUE; |
|
+ attr->pValue = isc_mem_get(key->mctx, ISC_GOST_PUBKEYLENGTH); |
|
+ if (attr->pValue == NULL) |
|
+ goto nomemory; |
|
+ memcpy((CK_BYTE_PTR) attr->pValue, r.base, ISC_GOST_PUBKEYLENGTH); |
|
+ attr->ulValueLen = ISC_GOST_PUBKEYLENGTH; |
|
+ |
|
+ isc_buffer_forward(data, ISC_GOST_PUBKEYLENGTH); |
|
+ key->keydata.pkey = gost; |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ nomemory: |
|
+ for (attr = pk11_attribute_first(gost); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(gost, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_VALUE: |
|
+ if (attr->pValue != NULL) { |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ } |
|
+ break; |
|
+ } |
|
+ if (gost->repr != NULL) { |
|
+ memset(gost->repr, 0, gost->attrcnt * sizeof(*attr)); |
|
+ isc_mem_put(key->mctx, |
|
+ gost->repr, |
|
+ gost->attrcnt * sizeof(*attr)); |
|
+ } |
|
+ memset(gost, 0, sizeof(*gost)); |
|
+ isc_mem_put(key->mctx, gost, sizeof(*gost)); |
|
+ return (ISC_R_NOMEMORY); |
|
+} |
|
+ |
|
+static unsigned char gost_private_der[39] = { |
|
+ 0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06, |
|
+ 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30, |
|
+ 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, |
|
+ 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, |
|
+ 0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20 |
|
+}; |
|
+ |
|
+#ifdef PREFER_GOSTASN1 |
|
+ |
|
+static isc_result_t |
|
+pkcs11gost_tofile(const dst_key_t *key, const char *directory) { |
|
+ isc_result_t ret; |
|
+ pk11_object_t *gost; |
|
+ dst_private_t priv; |
|
+ unsigned char *buf = NULL; |
|
+ unsigned int i = 0; |
|
+ CK_ATTRIBUTE *attr; |
|
+ int adj; |
|
+ |
|
+ if (key->keydata.pkey == NULL) |
|
+ return (DST_R_NULLKEY); |
|
+ |
|
+ if (key->external) { |
|
+ priv.nelements = 0; |
|
+ return (dst__privstruct_writefile(key, &priv, directory)); |
|
+ } |
|
+ |
|
+ gost = key->keydata.pkey; |
|
+ attr = pk11_attribute_bytype(gost, CKA_VALUE2); |
|
+ if (attr != NULL) { |
|
+ buf = isc_mem_get(key->mctx, attr->ulValueLen + 39); |
|
+ if (buf == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ priv.elements[i].tag = TAG_GOST_PRIVASN1; |
|
+ priv.elements[i].length = |
|
+ (unsigned short) attr->ulValueLen + 39; |
|
+ memcpy(buf, gost_private_der, 39); |
|
+ memcpy(buf +39, attr->pValue, attr->ulValueLen); |
|
+ adj = (int) attr->ulValueLen - 32; |
|
+ if (adj != 0) { |
|
+ buf[1] += adj; |
|
+ buf[36] += adj; |
|
+ buf[38] += adj; |
|
+ } |
|
+ priv.elements[i].data = buf; |
|
+ i++; |
|
+ } else |
|
+ return (DST_R_CRYPTOFAILURE); |
|
+ |
|
+ priv.nelements = i; |
|
+ ret = dst__privstruct_writefile(key, &priv, directory); |
|
+ |
|
+ if (buf != NULL) { |
|
+ memset(buf, 0, attr->ulValueLen); |
|
+ isc_mem_put(key->mctx, buf, attr->ulValueLen); |
|
+ } |
|
+ return (ret); |
|
+} |
|
+ |
|
+#else |
|
+ |
|
+static isc_result_t |
|
+pkcs11gost_tofile(const dst_key_t *key, const char *directory) { |
|
+ isc_result_t ret; |
|
+ pk11_object_t *gost; |
|
+ dst_private_t priv; |
|
+ unsigned char *buf = NULL; |
|
+ unsigned int i = 0; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ if (key->keydata.pkey == NULL) |
|
+ return (DST_R_NULLKEY); |
|
+ |
|
+ if (key->external) { |
|
+ priv.nelements = 0; |
|
+ return (dst__privstruct_writefile(key, &priv, directory)); |
|
+ } |
|
+ |
|
+ gost = key->keydata.pkey; |
|
+ attr = pk11_attribute_bytype(gost, CKA_VALUE2); |
|
+ if (attr != NULL) { |
|
+ buf = isc_mem_get(key->mctx, attr->ulValueLen); |
|
+ if (buf == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ priv.elements[i].tag = TAG_GOST_PRIVRAW; |
|
+ priv.elements[i].length = (unsigned short) attr->ulValueLen; |
|
+ memcpy(buf, attr->pValue, attr->ulValueLen); |
|
+ priv.elements[i].data = buf; |
|
+ i++; |
|
+ } else |
|
+ return (DST_R_CRYPTOFAILURE); |
|
+ |
|
+ priv.nelements = i; |
|
+ ret = dst__privstruct_writefile(key, &priv, directory); |
|
+ |
|
+ if (buf != NULL) { |
|
+ memset(buf, 0, attr->ulValueLen); |
|
+ isc_mem_put(key->mctx, buf, attr->ulValueLen); |
|
+ } |
|
+ return (ret); |
|
+} |
|
+#endif |
|
+ |
|
+static isc_result_t |
|
+pkcs11gost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
+ dst_private_t priv; |
|
+ isc_result_t ret; |
|
+ pk11_object_t *gost = NULL; |
|
+ CK_ATTRIBUTE *attr, *pattr; |
|
+ isc_mem_t *mctx = key->mctx; |
|
+ |
|
+ if ((pub == NULL) || (pub->keydata.pkey == NULL)) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ |
|
+ /* read private key file */ |
|
+ ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ return (ret); |
|
+ |
|
+ if (key->external) { |
|
+ if (priv.nelements != 0) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ |
|
+ key->keydata.pkey = pub->keydata.pkey; |
|
+ pub->keydata.pkey = NULL; |
|
+ key->key_size = pub->key_size; |
|
+ |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ } |
|
+ |
|
+ if (priv.elements[0].tag == TAG_GOST_PRIVASN1) { |
|
+ int adj = (int) priv.elements[0].length - (39 + 32); |
|
+ unsigned char buf[39]; |
|
+ |
|
+ if ((adj > 0) || (adj < -31)) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ memcpy(buf, gost_private_der, 39); |
|
+ if (adj != 0) { |
|
+ buf[1] += adj; |
|
+ buf[36] += adj; |
|
+ buf[38] += adj; |
|
+ } |
|
+ if (memcmp(priv.elements[0].data, buf, 39) != 0) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ priv.elements[0].tag = TAG_GOST_PRIVRAW; |
|
+ priv.elements[0].length -= 39; |
|
+ memmove(priv.elements[0].data, |
|
+ priv.elements[0].data + 39, |
|
+ 32 + adj); |
|
+ } |
|
+ |
|
+ gost = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*gost)); |
|
+ if (gost == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(gost, 0, sizeof(*gost)); |
|
+ key->keydata.pkey = gost; |
|
+ |
|
+ gost->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, |
|
+ sizeof(*attr) * 2); |
|
+ if (gost->repr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(gost->repr, 0, sizeof(*attr) * 2); |
|
+ gost->attrcnt = 2; |
|
+ |
|
+ attr = gost->repr; |
|
+ attr->type = CKA_VALUE; |
|
+ pattr = pk11_attribute_bytype(pub->keydata.pkey, CKA_VALUE); |
|
+ INSIST(pattr != NULL); |
|
+ attr->pValue = isc_mem_get(key->mctx, pattr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(attr->pValue, pattr->pValue, pattr->ulValueLen); |
|
+ attr->ulValueLen = pattr->ulValueLen; |
|
+ |
|
+ attr++; |
|
+ attr->type = CKA_VALUE2; |
|
+ attr->pValue = isc_mem_get(key->mctx, priv.elements[0].length); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(attr->pValue, priv.elements[0].data, priv.elements[0].length); |
|
+ attr->ulValueLen = priv.elements[0].length; |
|
+ |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pkcs11gost_destroy(key); |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static dst_func_t pkcs11gost_functions = { |
|
+ pkcs11gost_createctx, |
|
+ NULL, /*%< createctx2 */ |
|
+ pkcs11gost_destroyctx, |
|
+ pkcs11gost_adddata, |
|
+ pkcs11gost_sign, |
|
+ pkcs11gost_verify, |
|
+ NULL, /*%< verify2 */ |
|
+ NULL, /*%< computesecret */ |
|
+ pkcs11gost_compare, |
|
+ NULL, /*%< paramcompare */ |
|
+ pkcs11gost_generate, |
|
+ pkcs11gost_isprivate, |
|
+ pkcs11gost_destroy, |
|
+ pkcs11gost_todns, |
|
+ pkcs11gost_fromdns, |
|
+ pkcs11gost_tofile, |
|
+ pkcs11gost_parse, |
|
+ NULL, /*%< cleanup */ |
|
+ NULL, /*%< fromlabel */ |
|
+ NULL, /*%< dump */ |
|
+ NULL, /*%< restore */ |
|
+}; |
|
+ |
|
+isc_result_t |
|
+dst__pkcs11gost_init(dst_func_t **funcp) { |
|
+ REQUIRE(funcp != NULL); |
|
+ if (*funcp == NULL) |
|
+ *funcp = &pkcs11gost_functions; |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+#else /* PKCS11CRYPTO && HAVE_PKCS11_GOST */ |
|
+ |
|
+#include <isc/util.h> |
|
+ |
|
+EMPTY_TRANSLATION_UNIT |
|
+ |
|
+#endif /* PKCS11CRYPTO && HAVE_PKCS11_GOST */ |
|
+/*! \file */ |
|
diff --git a/lib/dns/pkcs11rsa_link.c b/lib/dns/pkcs11rsa_link.c |
|
new file mode 100644 |
|
index 0000000..010d4b6 |
|
--- /dev/null |
|
+++ b/lib/dns/pkcs11rsa_link.c |
|
@@ -0,0 +1,1583 @@ |
|
+/* |
|
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+#ifdef PKCS11CRYPTO |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <isc/entropy.h> |
|
+#include <isc/md5.h> |
|
+#include <isc/sha1.h> |
|
+#include <isc/sha2.h> |
|
+#include <isc/mem.h> |
|
+#include <isc/string.h> |
|
+#include <isc/util.h> |
|
+ |
|
+#include <dst/result.h> |
|
+ |
|
+#include "dst_internal.h" |
|
+#include "dst_parse.h" |
|
+#include "dst_pkcs11.h" |
|
+ |
|
+#include <pk11/internal.h> |
|
+ |
|
+/* |
|
+ * Limit the size of public exponents. |
|
+ */ |
|
+#ifndef RSA_MAX_PUBEXP_BITS |
|
+#define RSA_MAX_PUBEXP_BITS 35 |
|
+#endif |
|
+ |
|
+#define DST_RET(a) {ret = a; goto err;} |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+static isc_result_t pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data); |
|
+static void pkcs11rsa_destroy(dst_key_t *key); |
|
+static isc_result_t pkcs11rsa_fetch(dst_key_t *key, const char *engine, |
|
+ const char *label, dst_key_t *pub); |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { 0, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_RSA; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_MODULUS, NULL, 0 }, |
|
+ { CKA_PUBLIC_EXPONENT, NULL, 0 }, |
|
+ { CKA_PRIVATE_EXPONENT, NULL, 0 }, |
|
+ { CKA_PRIME_1, NULL, 0 }, |
|
+ { CKA_PRIME_2, NULL, 0 }, |
|
+ { CKA_EXPONENT_1, NULL, 0 }, |
|
+ { CKA_EXPONENT_2, NULL, 0 }, |
|
+ { CKA_COEFFICIENT, NULL, 0 } |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ CK_SLOT_ID slotid; |
|
+ pk11_object_t *rsa; |
|
+ pk11_context_t *pk11_ctx; |
|
+ isc_result_t ret; |
|
+ unsigned int i; |
|
+ |
|
+ REQUIRE(key->key_alg == DST_ALG_RSAMD5 || |
|
+ key->key_alg == DST_ALG_RSASHA1 || |
|
+ key->key_alg == DST_ALG_NSEC3RSASHA1 || |
|
+ key->key_alg == DST_ALG_RSASHA256 || |
|
+ key->key_alg == DST_ALG_RSASHA512); |
|
+ |
|
+ rsa = key->keydata.pkey; |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ if (rsa->ontoken) |
|
+ slotid = rsa->slot; |
|
+ else |
|
+ slotid = pk11_get_best_token(OP_RSA); |
|
+ ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, |
|
+ rsa->reqlogon, NULL, slotid); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ if (rsa->ontoken && (rsa->object != CK_INVALID_HANDLE)) { |
|
+ pk11_ctx->ontoken = rsa->ontoken; |
|
+ pk11_ctx->object = rsa->object; |
|
+ goto token_key; |
|
+ } |
|
+ |
|
+ for (attr = pk11_attribute_first(rsa); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(rsa, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_MODULUS: |
|
+ INSIST(keyTemplate[6].type == attr->type); |
|
+ keyTemplate[6].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[6].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[6].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[6].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_PUBLIC_EXPONENT: |
|
+ INSIST(keyTemplate[7].type == attr->type); |
|
+ keyTemplate[7].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[7].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[7].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[7].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_PRIVATE_EXPONENT: |
|
+ INSIST(keyTemplate[8].type == attr->type); |
|
+ keyTemplate[8].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[8].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[8].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[8].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_PRIME_1: |
|
+ INSIST(keyTemplate[9].type == attr->type); |
|
+ keyTemplate[9].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[9].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[9].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[9].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_PRIME_2: |
|
+ INSIST(keyTemplate[10].type == attr->type); |
|
+ keyTemplate[10].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[10].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[10].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[10].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_EXPONENT_1: |
|
+ INSIST(keyTemplate[11].type == attr->type); |
|
+ keyTemplate[11].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[11].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[11].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[11].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_EXPONENT_2: |
|
+ INSIST(keyTemplate[12].type == attr->type); |
|
+ keyTemplate[12].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[12].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[12].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[12].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_COEFFICIENT: |
|
+ INSIST(keyTemplate[13].type == attr->type); |
|
+ keyTemplate[13].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[13].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[13].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[13].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ } |
|
+ pk11_ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_ctx->ontoken = ISC_FALSE; |
|
+ PK11_RET(pkcs_C_CreateObject, |
|
+ (pk11_ctx->session, |
|
+ keyTemplate, (CK_ULONG) 14, |
|
+ &pk11_ctx->object), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ token_key: |
|
+ |
|
+ switch (dctx->key->key_alg) { |
|
+ case DST_ALG_RSAMD5: |
|
+ mech.mechanism = CKM_MD5_RSA_PKCS; |
|
+ break; |
|
+ case DST_ALG_RSASHA1: |
|
+ case DST_ALG_NSEC3RSASHA1: |
|
+ mech.mechanism = CKM_SHA1_RSA_PKCS; |
|
+ break; |
|
+ case DST_ALG_RSASHA256: |
|
+ mech.mechanism = CKM_SHA256_RSA_PKCS; |
|
+ break; |
|
+ case DST_ALG_RSASHA512: |
|
+ mech.mechanism = CKM_SHA512_RSA_PKCS; |
|
+ break; |
|
+ default: |
|
+ INSIST(0); |
|
+ } |
|
+ |
|
+ PK11_RET(pkcs_C_SignInit, |
|
+ (pk11_ctx->session, &mech, pk11_ctx->object), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ dctx->ctxdata.pk11_ctx = pk11_ctx; |
|
+ |
|
+ for (i = 6; i <= 13; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, |
|
+ pk11_ctx->object); |
|
+ for (i = 6; i <= 13; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_createctx_verify(dst_key_t *key, unsigned int maxbits, |
|
+ dst_context_t *dctx) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { 0, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_RSA; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_MODULUS, NULL, 0 }, |
|
+ { CKA_PUBLIC_EXPONENT, NULL, 0 }, |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_object_t *rsa; |
|
+ pk11_context_t *pk11_ctx; |
|
+ isc_result_t ret; |
|
+ unsigned int i; |
|
+ |
|
+ REQUIRE(key->key_alg == DST_ALG_RSAMD5 || |
|
+ key->key_alg == DST_ALG_RSASHA1 || |
|
+ key->key_alg == DST_ALG_NSEC3RSASHA1 || |
|
+ key->key_alg == DST_ALG_RSASHA256 || |
|
+ key->key_alg == DST_ALG_RSASHA512); |
|
+ |
|
+ rsa = key->keydata.pkey; |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, |
|
+ rsa->reqlogon, NULL, |
|
+ pk11_get_best_token(OP_RSA)); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ for (attr = pk11_attribute_first(rsa); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(rsa, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_MODULUS: |
|
+ INSIST(keyTemplate[5].type == attr->type); |
|
+ keyTemplate[5].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[5].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[5].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[5].ulValueLen = attr->ulValueLen; |
|
+ break; |
|
+ case CKA_PUBLIC_EXPONENT: |
|
+ INSIST(keyTemplate[6].type == attr->type); |
|
+ keyTemplate[6].pValue = isc_mem_get(dctx->mctx, |
|
+ attr->ulValueLen); |
|
+ if (keyTemplate[6].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(keyTemplate[6].pValue, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ keyTemplate[6].ulValueLen = attr->ulValueLen; |
|
+ if (pk11_numbits(attr->pValue, |
|
+ attr->ulValueLen) > maxbits && |
|
+ maxbits != 0) |
|
+ DST_RET(DST_R_VERIFYFAILURE); |
|
+ break; |
|
+ } |
|
+ pk11_ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_ctx->ontoken = ISC_FALSE; |
|
+ PK11_RET(pkcs_C_CreateObject, |
|
+ (pk11_ctx->session, |
|
+ keyTemplate, (CK_ULONG) 7, |
|
+ &pk11_ctx->object), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ switch (dctx->key->key_alg) { |
|
+ case DST_ALG_RSAMD5: |
|
+ mech.mechanism = CKM_MD5_RSA_PKCS; |
|
+ break; |
|
+ case DST_ALG_RSASHA1: |
|
+ case DST_ALG_NSEC3RSASHA1: |
|
+ mech.mechanism = CKM_SHA1_RSA_PKCS; |
|
+ break; |
|
+ case DST_ALG_RSASHA256: |
|
+ mech.mechanism = CKM_SHA256_RSA_PKCS; |
|
+ break; |
|
+ case DST_ALG_RSASHA512: |
|
+ mech.mechanism = CKM_SHA512_RSA_PKCS; |
|
+ break; |
|
+ default: |
|
+ INSIST(0); |
|
+ } |
|
+ |
|
+ PK11_RET(pkcs_C_VerifyInit, |
|
+ (pk11_ctx->session, &mech, pk11_ctx->object), |
|
+ ISC_R_FAILURE); |
|
+ |
|
+ dctx->ctxdata.pk11_ctx = pk11_ctx; |
|
+ |
|
+ for (i = 5; i <= 6; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE)) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, |
|
+ pk11_ctx->object); |
|
+ for (i = 5; i <= 6; i++) |
|
+ if (keyTemplate[i].pValue != NULL) { |
|
+ memset(keyTemplate[i].pValue, 0, |
|
+ keyTemplate[i].ulValueLen); |
|
+ isc_mem_put(dctx->mctx, |
|
+ keyTemplate[i].pValue, |
|
+ keyTemplate[i].ulValueLen); |
|
+ } |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_createctx(dst_key_t *key, dst_context_t *dctx) { |
|
+ if (dctx->use == DO_SIGN) |
|
+ return (pkcs11rsa_createctx_sign(key, dctx)); |
|
+ else |
|
+ return (pkcs11rsa_createctx_verify(key, 0U, dctx)); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_createctx2(dst_key_t *key, int maxbits, dst_context_t *dctx) { |
|
+ if (dctx->use == DO_SIGN) |
|
+ return (pkcs11rsa_createctx_sign(key, dctx)); |
|
+ else |
|
+ return (pkcs11rsa_createctx_verify(key, |
|
+ (unsigned) maxbits, dctx)); |
|
+} |
|
+ |
|
+static void |
|
+pkcs11rsa_destroyctx(dst_context_t *dctx) { |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ |
|
+ if (pk11_ctx != NULL) { |
|
+ if (!pk11_ctx->ontoken && |
|
+ (pk11_ctx->object != CK_INVALID_HANDLE)) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, |
|
+ pk11_ctx->object); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ dctx->ctxdata.pk11_ctx = NULL; |
|
+ } |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_adddata(dst_context_t *dctx, const isc_region_t *data) { |
|
+ CK_RV rv; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ |
|
+ if (dctx->use == DO_SIGN) |
|
+ PK11_CALL(pkcs_C_SignUpdate, |
|
+ (pk11_ctx->session, |
|
+ (CK_BYTE_PTR) data->base, |
|
+ (CK_ULONG) data->length), |
|
+ ISC_R_FAILURE); |
|
+ else |
|
+ PK11_CALL(pkcs_C_VerifyUpdate, |
|
+ (pk11_ctx->session, |
|
+ (CK_BYTE_PTR) data->base, |
|
+ (CK_ULONG) data->length), |
|
+ ISC_R_FAILURE); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_sign(dst_context_t *dctx, isc_buffer_t *sig) { |
|
+ CK_RV rv; |
|
+ CK_ULONG siglen = 0; |
|
+ isc_region_t r; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ |
|
+ PK11_RET(pkcs_C_SignFinal, |
|
+ (pk11_ctx->session, NULL, &siglen), |
|
+ DST_R_SIGNFAILURE); |
|
+ |
|
+ isc_buffer_availableregion(sig, &r); |
|
+ |
|
+ if (r.length < (unsigned int) siglen) |
|
+ return (ISC_R_NOSPACE); |
|
+ |
|
+ PK11_RET(pkcs_C_SignFinal, |
|
+ (pk11_ctx->session, (CK_BYTE_PTR) r.base, &siglen), |
|
+ DST_R_SIGNFAILURE); |
|
+ |
|
+ isc_buffer_add(sig, (unsigned int) siglen); |
|
+ |
|
+ err: |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_verify(dst_context_t *dctx, const isc_region_t *sig) { |
|
+ CK_RV rv; |
|
+ pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ |
|
+ PK11_CALL(pkcs_C_VerifyFinal, |
|
+ (pk11_ctx->session, |
|
+ (CK_BYTE_PTR) sig->base, |
|
+ (CK_ULONG) sig->length), |
|
+ DST_R_VERIFYFAILURE); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_boolean_t |
|
+pkcs11rsa_compare(const dst_key_t *key1, const dst_key_t *key2) { |
|
+ pk11_object_t *rsa1, *rsa2; |
|
+ CK_ATTRIBUTE *attr1, *attr2; |
|
+ |
|
+ rsa1 = key1->keydata.pkey; |
|
+ rsa2 = key2->keydata.pkey; |
|
+ |
|
+ if ((rsa1 == NULL) && (rsa2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((rsa1 == NULL) || (rsa2 == NULL)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(rsa1, CKA_MODULUS); |
|
+ attr2 = pk11_attribute_bytype(rsa2, CKA_MODULUS); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(rsa1, CKA_PUBLIC_EXPONENT); |
|
+ attr2 = pk11_attribute_bytype(rsa2, CKA_PUBLIC_EXPONENT); |
|
+ if ((attr1 == NULL) && (attr2 == NULL)) |
|
+ return (ISC_TRUE); |
|
+ else if ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ attr1 = pk11_attribute_bytype(rsa1, CKA_PRIVATE_EXPONENT); |
|
+ attr2 = pk11_attribute_bytype(rsa2, CKA_PRIVATE_EXPONENT); |
|
+ if (((attr1 != NULL) || (attr2 != NULL)) && |
|
+ ((attr1 == NULL) || (attr2 == NULL) || |
|
+ (attr1->ulValueLen != attr2->ulValueLen) || |
|
+ memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ if (!rsa1->ontoken && !rsa2->ontoken) |
|
+ return (ISC_TRUE); |
|
+ else if (rsa1->ontoken || rsa2->ontoken || |
|
+ (rsa1->object != rsa2->object)) |
|
+ return (ISC_FALSE); |
|
+ |
|
+ return (ISC_TRUE); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_generate(dst_key_t *key, int exp, void (*callback)(int)) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0 }; |
|
+ CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; |
|
+ CK_ULONG bits = 0; |
|
+ CK_BYTE pubexp[5]; |
|
+ CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_RSA; |
|
+ CK_ATTRIBUTE pubTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_MODULUS_BITS, &bits, (CK_ULONG) sizeof(bits) }, |
|
+ { CKA_PUBLIC_EXPONENT, &pubexp, (CK_ULONG) sizeof(pubexp) } |
|
+ }; |
|
+ CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY; |
|
+ CK_ATTRIBUTE privTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ }; |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_object_t *rsa; |
|
+ pk11_context_t *pk11_ctx; |
|
+ isc_result_t ret; |
|
+ unsigned int i; |
|
+ |
|
+ UNUSED(callback); |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, pk11_get_best_token(OP_RSA)); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ bits = key->key_size; |
|
+ if (exp == 0) { |
|
+ /* RSA_F4 0x10001 */ |
|
+ pubexp[0] = 1; |
|
+ pubexp[1] = 0; |
|
+ pubexp[2] = 1; |
|
+ pubTemplate[6].ulValueLen = 3; |
|
+ } else { |
|
+ /* F5 0x100000001 */ |
|
+ pubexp[0] = 1; |
|
+ pubexp[1] = 0; |
|
+ pubexp[2] = 0; |
|
+ pubexp[3] = 0; |
|
+ pubexp[4] = 1; |
|
+ pubTemplate[6].ulValueLen = 5; |
|
+ } |
|
+ |
|
+ PK11_RET(pkcs_C_GenerateKeyPair, |
|
+ (pk11_ctx->session, &mech, |
|
+ pubTemplate, (CK_ULONG) 7, |
|
+ privTemplate, (CK_ULONG) 7, |
|
+ &pub, &priv), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); |
|
+ if (rsa == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(rsa, 0, sizeof(*rsa)); |
|
+ key->keydata.pkey = rsa; |
|
+ rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8); |
|
+ if (rsa->repr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(rsa->repr, 0, sizeof(*attr) * 8); |
|
+ rsa->attrcnt = 8; |
|
+ |
|
+ attr = rsa->repr; |
|
+ attr[0].type = CKA_MODULUS; |
|
+ attr[1].type = CKA_PUBLIC_EXPONENT; |
|
+ attr[2].type = CKA_PRIVATE_EXPONENT; |
|
+ attr[3].type = CKA_PRIME_1; |
|
+ attr[4].type = CKA_PRIME_2; |
|
+ attr[5].type = CKA_EXPONENT_1; |
|
+ attr[6].type = CKA_EXPONENT_2; |
|
+ attr[7].type = CKA_COEFFICIENT; |
|
+ |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, pub, attr, 2), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ for (i = 0; i <= 1; i++) { |
|
+ attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); |
|
+ if (attr[i].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr[i].pValue, 0, attr[i].ulValueLen); |
|
+ } |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, pub, attr, 2), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ attr += 2; |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, priv, attr, 6), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ for (i = 0; i <= 5; i++) { |
|
+ attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); |
|
+ if (attr[i].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr[i].pValue, 0, attr[i].ulValueLen); |
|
+ } |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, priv, attr, 6), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pkcs11rsa_destroy(key); |
|
+ if (priv != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, priv); |
|
+ if (pub != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(pk11_ctx->session, pub); |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_boolean_t |
|
+pkcs11rsa_isprivate(const dst_key_t *key) { |
|
+ pk11_object_t *rsa = key->keydata.pkey; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ if (rsa == NULL) |
|
+ return (ISC_FALSE); |
|
+ attr = pk11_attribute_bytype(rsa, CKA_PRIVATE_EXPONENT); |
|
+ return (ISC_TF((attr != NULL) || rsa->ontoken)); |
|
+} |
|
+ |
|
+static void |
|
+pkcs11rsa_destroy(dst_key_t *key) { |
|
+ pk11_object_t *rsa = key->keydata.pkey; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ if (rsa == NULL) |
|
+ return; |
|
+ |
|
+ INSIST((rsa->object == CK_INVALID_HANDLE) || rsa->ontoken); |
|
+ |
|
+ for (attr = pk11_attribute_first(rsa); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(rsa, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_LABEL: |
|
+ case CKA_ID: |
|
+ case CKA_MODULUS: |
|
+ case CKA_PUBLIC_EXPONENT: |
|
+ case CKA_PRIVATE_EXPONENT: |
|
+ case CKA_PRIME_1: |
|
+ case CKA_PRIME_2: |
|
+ case CKA_EXPONENT_1: |
|
+ case CKA_EXPONENT_2: |
|
+ case CKA_COEFFICIENT: |
|
+ if (attr->pValue != NULL) { |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ } |
|
+ break; |
|
+ } |
|
+ if (rsa->repr != NULL) { |
|
+ memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr)); |
|
+ isc_mem_put(key->mctx, |
|
+ rsa->repr, |
|
+ rsa->attrcnt * sizeof(*attr)); |
|
+ } |
|
+ memset(rsa, 0, sizeof(*rsa)); |
|
+ isc_mem_put(key->mctx, rsa, sizeof(*rsa)); |
|
+ key->keydata.pkey = NULL; |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_todns(const dst_key_t *key, isc_buffer_t *data) { |
|
+ pk11_object_t *rsa; |
|
+ CK_ATTRIBUTE *attr; |
|
+ isc_region_t r; |
|
+ unsigned int e_bytes = 0, mod_bytes = 0; |
|
+ CK_BYTE *exponent = NULL, *modulus = NULL; |
|
+ |
|
+ REQUIRE(key->keydata.pkey != NULL); |
|
+ |
|
+ rsa = key->keydata.pkey; |
|
+ |
|
+ for (attr = pk11_attribute_first(rsa); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(rsa, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_PUBLIC_EXPONENT: |
|
+ exponent = (CK_BYTE *) attr->pValue; |
|
+ e_bytes = (unsigned int) attr->ulValueLen; |
|
+ break; |
|
+ case CKA_MODULUS: |
|
+ modulus = (CK_BYTE *) attr->pValue; |
|
+ mod_bytes = (unsigned int) attr->ulValueLen; |
|
+ break; |
|
+ } |
|
+ REQUIRE((exponent != NULL) && (modulus != NULL)); |
|
+ |
|
+ isc_buffer_availableregion(data, &r); |
|
+ |
|
+ if (e_bytes < 256) { /*%< key exponent is <= 2040 bits */ |
|
+ if (r.length < 1) |
|
+ return (ISC_R_NOSPACE); |
|
+ isc_buffer_putuint8(data, (isc_uint8_t) e_bytes); |
|
+ isc_region_consume(&r, 1); |
|
+ } else { |
|
+ if (r.length < 3) |
|
+ return (ISC_R_NOSPACE); |
|
+ isc_buffer_putuint8(data, 0); |
|
+ isc_buffer_putuint16(data, (isc_uint16_t) e_bytes); |
|
+ isc_region_consume(&r, 3); |
|
+ } |
|
+ |
|
+ if (r.length < e_bytes + mod_bytes) |
|
+ return (ISC_R_NOSPACE); |
|
+ |
|
+ memcpy(r.base, exponent, e_bytes); |
|
+ isc_region_consume(&r, e_bytes); |
|
+ memcpy(r.base, modulus, mod_bytes); |
|
+ |
|
+ isc_buffer_add(data, e_bytes + mod_bytes); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_fromdns(dst_key_t *key, isc_buffer_t *data) { |
|
+ pk11_object_t *rsa; |
|
+ isc_region_t r; |
|
+ unsigned int e_bytes, mod_bytes; |
|
+ CK_BYTE *exponent = NULL, *modulus = NULL; |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ isc_buffer_remainingregion(data, &r); |
|
+ if (r.length == 0) |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); |
|
+ if (rsa == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ memset(rsa, 0, sizeof(*rsa)); |
|
+ |
|
+ if (r.length < 1) { |
|
+ memset(rsa, 0, sizeof(*rsa)); |
|
+ isc_mem_put(key->mctx, rsa, sizeof(*rsa)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ e_bytes = *r.base++; |
|
+ r.length--; |
|
+ |
|
+ if (e_bytes == 0) { |
|
+ if (r.length < 2) { |
|
+ memset(rsa, 0, sizeof(*rsa)); |
|
+ isc_mem_put(key->mctx, rsa, sizeof(*rsa)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ e_bytes = ((*r.base++) << 8); |
|
+ e_bytes += *r.base++; |
|
+ r.length -= 2; |
|
+ } |
|
+ |
|
+ if (r.length < e_bytes) { |
|
+ memset(rsa, 0, sizeof(*rsa)); |
|
+ isc_mem_put(key->mctx, rsa, sizeof(*rsa)); |
|
+ return (DST_R_INVALIDPUBLICKEY); |
|
+ } |
|
+ exponent = r.base; |
|
+ r.base += e_bytes; |
|
+ r.length -= e_bytes; |
|
+ modulus = r.base; |
|
+ mod_bytes = r.length; |
|
+ |
|
+ key->key_size = pk11_numbits(modulus, mod_bytes); |
|
+ |
|
+ isc_buffer_forward(data, r.length); |
|
+ |
|
+ rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); |
|
+ if (rsa->repr == NULL) |
|
+ goto nomemory; |
|
+ memset(rsa->repr, 0, sizeof(*attr) * 2); |
|
+ rsa->attrcnt = 2; |
|
+ attr = rsa->repr; |
|
+ attr[0].type = CKA_MODULUS; |
|
+ attr[0].pValue = isc_mem_get(key->mctx, mod_bytes); |
|
+ if (attr[0].pValue == NULL) |
|
+ goto nomemory; |
|
+ memcpy(attr[0].pValue, modulus, mod_bytes); |
|
+ attr[0].ulValueLen = (CK_ULONG) mod_bytes; |
|
+ attr[1].type = CKA_PUBLIC_EXPONENT; |
|
+ attr[1].pValue = isc_mem_get(key->mctx, e_bytes); |
|
+ if (attr[1].pValue == NULL) |
|
+ goto nomemory; |
|
+ memcpy(attr[1].pValue, exponent, e_bytes); |
|
+ attr[1].ulValueLen = (CK_ULONG) e_bytes; |
|
+ |
|
+ key->keydata.pkey = rsa; |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ nomemory: |
|
+ for (attr = pk11_attribute_first(rsa); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(rsa, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_MODULUS: |
|
+ case CKA_PUBLIC_EXPONENT: |
|
+ if (attr->pValue != NULL) { |
|
+ memset(attr->pValue, 0, attr->ulValueLen); |
|
+ isc_mem_put(key->mctx, |
|
+ attr->pValue, |
|
+ attr->ulValueLen); |
|
+ } |
|
+ break; |
|
+ } |
|
+ if (rsa->repr != NULL) { |
|
+ memset(rsa->repr, 0, rsa->attrcnt * sizeof(*attr)); |
|
+ isc_mem_put(key->mctx, |
|
+ rsa->repr, |
|
+ rsa->attrcnt * sizeof(*attr)); |
|
+ } |
|
+ memset(rsa, 0, sizeof(*rsa)); |
|
+ isc_mem_put(key->mctx, rsa, sizeof(*rsa)); |
|
+ return (ISC_R_NOMEMORY); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_tofile(const dst_key_t *key, const char *directory) { |
|
+ int i; |
|
+ pk11_object_t *rsa; |
|
+ CK_ATTRIBUTE *attr; |
|
+ CK_ATTRIBUTE *modulus = NULL, *exponent = NULL; |
|
+ CK_ATTRIBUTE *d = NULL, *p = NULL, *q = NULL; |
|
+ CK_ATTRIBUTE *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; |
|
+ dst_private_t priv; |
|
+ unsigned char *bufs[10]; |
|
+ isc_result_t result; |
|
+ |
|
+ if (key->keydata.pkey == NULL) |
|
+ return (DST_R_NULLKEY); |
|
+ |
|
+ if (key->external) { |
|
+ priv.nelements = 0; |
|
+ return (dst__privstruct_writefile(key, &priv, directory)); |
|
+ } |
|
+ |
|
+ rsa = key->keydata.pkey; |
|
+ |
|
+ for (attr = pk11_attribute_first(rsa); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(rsa, attr)) |
|
+ switch (attr->type) { |
|
+ case CKA_MODULUS: |
|
+ modulus = attr; |
|
+ break; |
|
+ case CKA_PUBLIC_EXPONENT: |
|
+ exponent = attr; |
|
+ break; |
|
+ case CKA_PRIVATE_EXPONENT: |
|
+ d = attr; |
|
+ break; |
|
+ case CKA_PRIME_1: |
|
+ p = attr; |
|
+ break; |
|
+ case CKA_PRIME_2: |
|
+ q = attr; |
|
+ break; |
|
+ case CKA_EXPONENT_1: |
|
+ dmp1 = attr; |
|
+ break; |
|
+ case CKA_EXPONENT_2: |
|
+ dmq1 = attr; |
|
+ break; |
|
+ case CKA_COEFFICIENT: |
|
+ iqmp = attr; |
|
+ break; |
|
+ } |
|
+ if ((modulus == NULL) || (exponent == NULL)) |
|
+ return (DST_R_NULLKEY); |
|
+ |
|
+ memset(bufs, 0, sizeof(bufs)); |
|
+ |
|
+ for (i = 0; i < 10; i++) { |
|
+ bufs[i] = isc_mem_get(key->mctx, modulus->ulValueLen); |
|
+ if (bufs[i] == NULL) { |
|
+ result = ISC_R_NOMEMORY; |
|
+ goto fail; |
|
+ } |
|
+ memset(bufs[i], 0, modulus->ulValueLen); |
|
+ } |
|
+ |
|
+ i = 0; |
|
+ |
|
+ priv.elements[i].tag = TAG_RSA_MODULUS; |
|
+ priv.elements[i].length = (unsigned short) modulus->ulValueLen; |
|
+ memcpy(bufs[i], modulus->pValue, modulus->ulValueLen); |
|
+ priv.elements[i].data = bufs[i]; |
|
+ i++; |
|
+ |
|
+ priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT; |
|
+ priv.elements[i].length = (unsigned short) exponent->ulValueLen; |
|
+ memcpy(bufs[i], exponent->pValue, exponent->ulValueLen); |
|
+ priv.elements[i].data = bufs[i]; |
|
+ i++; |
|
+ |
|
+ if (d != NULL) { |
|
+ priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT; |
|
+ priv.elements[i].length = (unsigned short) d->ulValueLen; |
|
+ memcpy(bufs[i], d->pValue, d->ulValueLen); |
|
+ priv.elements[i].data = bufs[i]; |
|
+ i++; |
|
+ } |
|
+ |
|
+ if (p != NULL) { |
|
+ priv.elements[i].tag = TAG_RSA_PRIME1; |
|
+ priv.elements[i].length = (unsigned short) p->ulValueLen; |
|
+ memcpy(bufs[i], p->pValue, p->ulValueLen); |
|
+ priv.elements[i].data = bufs[i]; |
|
+ i++; |
|
+ } |
|
+ |
|
+ if (q != NULL) { |
|
+ priv.elements[i].tag = TAG_RSA_PRIME2; |
|
+ priv.elements[i].length = (unsigned short) q->ulValueLen; |
|
+ memcpy(bufs[i], q->pValue, q->ulValueLen); |
|
+ priv.elements[i].data = bufs[i]; |
|
+ i++; |
|
+ } |
|
+ |
|
+ if (dmp1 != NULL) { |
|
+ priv.elements[i].tag = TAG_RSA_EXPONENT1; |
|
+ priv.elements[i].length = (unsigned short) dmp1->ulValueLen; |
|
+ memcpy(bufs[i], dmp1->pValue, dmp1->ulValueLen); |
|
+ priv.elements[i].data = bufs[i]; |
|
+ i++; |
|
+ } |
|
+ |
|
+ if (dmq1 != NULL) { |
|
+ priv.elements[i].tag = TAG_RSA_EXPONENT2; |
|
+ priv.elements[i].length = (unsigned short) dmq1->ulValueLen; |
|
+ memcpy(bufs[i], dmq1->pValue, dmq1->ulValueLen); |
|
+ priv.elements[i].data = bufs[i]; |
|
+ i++; |
|
+ } |
|
+ |
|
+ if (iqmp != NULL) { |
|
+ priv.elements[i].tag = TAG_RSA_COEFFICIENT; |
|
+ priv.elements[i].length = (unsigned short) iqmp->ulValueLen; |
|
+ memcpy(bufs[i], iqmp->pValue, iqmp->ulValueLen); |
|
+ priv.elements[i].data = bufs[i]; |
|
+ i++; |
|
+ } |
|
+ |
|
+ if (key->engine != NULL) { |
|
+ priv.elements[i].tag = TAG_RSA_ENGINE; |
|
+ priv.elements[i].length = strlen(key->engine) + 1; |
|
+ priv.elements[i].data = (unsigned char *)key->engine; |
|
+ i++; |
|
+ } |
|
+ |
|
+ if (key->label != NULL) { |
|
+ priv.elements[i].tag = TAG_RSA_LABEL; |
|
+ priv.elements[i].length = strlen(key->label) + 1; |
|
+ priv.elements[i].data = (unsigned char *)key->label; |
|
+ i++; |
|
+ } |
|
+ |
|
+ priv.nelements = i; |
|
+ result = dst__privstruct_writefile(key, &priv, directory); |
|
+ fail: |
|
+ for (i = 0; i < 10; i++) { |
|
+ if (bufs[i] == NULL) |
|
+ break; |
|
+ memset(bufs[i], 0, modulus->ulValueLen); |
|
+ isc_mem_put(key->mctx, bufs[i], modulus->ulValueLen); |
|
+ } |
|
+ return (result); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_fetch(dst_key_t *key, const char *engine, const char *label, |
|
+ dst_key_t *pub) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_RSA; |
|
+ CK_ATTRIBUTE searchTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_LABEL, NULL, 0 } |
|
+ }; |
|
+ CK_ULONG cnt; |
|
+ CK_ATTRIBUTE *attr; |
|
+ CK_ATTRIBUTE *pubattr; |
|
+ pk11_object_t *rsa; |
|
+ pk11_object_t *pubrsa; |
|
+ pk11_context_t *pk11_ctx = NULL; |
|
+ isc_result_t ret; |
|
+ |
|
+ if (label == NULL) |
|
+ return (DST_R_NOENGINE); |
|
+ |
|
+ rsa = key->keydata.pkey; |
|
+ pubrsa = pub->keydata.pkey; |
|
+ |
|
+ rsa->object = CK_INVALID_HANDLE; |
|
+ rsa->ontoken = ISC_TRUE; |
|
+ rsa->reqlogon = ISC_TRUE; |
|
+ rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); |
|
+ if (rsa->repr == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ memset(rsa->repr, 0, sizeof(*attr) * 2); |
|
+ rsa->attrcnt = 2; |
|
+ attr = rsa->repr; |
|
+ |
|
+ attr->type = CKA_MODULUS; |
|
+ pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS); |
|
+ attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(attr->pValue, pubattr->pValue, pubattr->ulValueLen); |
|
+ attr->ulValueLen = pubattr->ulValueLen; |
|
+ attr++; |
|
+ |
|
+ attr->type = CKA_PUBLIC_EXPONENT; |
|
+ pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT); |
|
+ attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); |
|
+ if (attr->pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(attr->pValue, pubattr->pValue, pubattr->ulValueLen); |
|
+ attr->ulValueLen = pubattr->ulValueLen; |
|
+ |
|
+ ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, |
|
+ rsa->reqlogon, NULL, rsa->slot); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ attr = pk11_attribute_bytype(rsa, CKA_LABEL); |
|
+ if (attr == NULL) { |
|
+ attr = pk11_attribute_bytype(rsa, CKA_ID); |
|
+ INSIST(attr != NULL); |
|
+ searchTemplate[3].type = CKA_ID; |
|
+ } |
|
+ searchTemplate[3].pValue = attr->pValue; |
|
+ searchTemplate[3].ulValueLen = attr->ulValueLen; |
|
+ |
|
+ PK11_RET(pkcs_C_FindObjectsInit, |
|
+ (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ PK11_RET(pkcs_C_FindObjects, |
|
+ (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); |
|
+ if (cnt == 0) |
|
+ DST_RET(ISC_R_NOTFOUND); |
|
+ if (cnt > 1) |
|
+ DST_RET(ISC_R_EXISTS); |
|
+ |
|
+ if (engine != NULL) { |
|
+ key->engine = isc_mem_strdup(key->mctx, engine); |
|
+ if (key->engine == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ } |
|
+ |
|
+ key->label = isc_mem_strdup(key->mctx, label); |
|
+ if (key->label == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ attr = pk11_attribute_bytype(rsa, CKA_MODULUS); |
|
+ INSIST(attr != NULL); |
|
+ key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ if (pk11_ctx != NULL) { |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ } |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+rsa_check(pk11_object_t *rsa, pk11_object_t *pubrsa) { |
|
+ CK_ATTRIBUTE *pubattr, *privattr; |
|
+ CK_BYTE *priv_exp = NULL, *priv_mod = NULL; |
|
+ CK_BYTE *pub_exp = NULL, *pub_mod = NULL; |
|
+ unsigned int priv_explen = 0, priv_modlen = 0; |
|
+ unsigned int pub_explen = 0, pub_modlen = 0; |
|
+ |
|
+ REQUIRE(rsa != NULL && pubrsa != NULL); |
|
+ |
|
+ privattr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); |
|
+ INSIST(privattr != NULL); |
|
+ priv_exp = privattr->pValue; |
|
+ priv_explen = privattr->ulValueLen; |
|
+ |
|
+ pubattr = pk11_attribute_bytype(pubrsa, CKA_PUBLIC_EXPONENT); |
|
+ INSIST(pubattr != NULL); |
|
+ pub_exp = pubattr->pValue; |
|
+ pub_explen = pubattr->ulValueLen; |
|
+ |
|
+ if (priv_exp != NULL) { |
|
+ if (priv_explen != pub_explen) |
|
+ return (DST_R_INVALIDPRIVATEKEY); |
|
+ if (memcmp(priv_exp, pub_exp, pub_explen) != 0) |
|
+ return (DST_R_INVALIDPRIVATEKEY); |
|
+ } else { |
|
+ privattr->pValue = pub_exp; |
|
+ privattr->ulValueLen = pub_explen; |
|
+ pubattr->pValue = NULL; |
|
+ pubattr->ulValueLen = 0; |
|
+ } |
|
+ |
|
+ if (privattr->pValue == NULL) |
|
+ return (DST_R_INVALIDPRIVATEKEY); |
|
+ |
|
+ privattr = pk11_attribute_bytype(rsa, CKA_MODULUS); |
|
+ INSIST(privattr != NULL); |
|
+ priv_mod = privattr->pValue; |
|
+ priv_modlen = privattr->ulValueLen; |
|
+ |
|
+ pubattr = pk11_attribute_bytype(pubrsa, CKA_MODULUS); |
|
+ INSIST(pubattr != NULL); |
|
+ pub_mod = pubattr->pValue; |
|
+ pub_modlen = pubattr->ulValueLen; |
|
+ |
|
+ if (priv_mod != NULL) { |
|
+ if (priv_modlen != pub_modlen) |
|
+ return (DST_R_INVALIDPRIVATEKEY); |
|
+ if (memcmp(priv_mod, pub_mod, pub_modlen) != 0) |
|
+ return (DST_R_INVALIDPRIVATEKEY); |
|
+ } else { |
|
+ privattr->pValue = pub_mod; |
|
+ privattr->ulValueLen = pub_modlen; |
|
+ pubattr->pValue = NULL; |
|
+ pubattr->ulValueLen = 0; |
|
+ } |
|
+ |
|
+ if (privattr->pValue == NULL) |
|
+ return (DST_R_INVALIDPRIVATEKEY); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { |
|
+ dst_private_t priv; |
|
+ isc_result_t ret; |
|
+ int i; |
|
+ pk11_object_t *rsa; |
|
+ CK_ATTRIBUTE *attr; |
|
+ isc_mem_t *mctx = key->mctx; |
|
+ const char *engine = NULL, *label = NULL; |
|
+ |
|
+ /* read private key file */ |
|
+ ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ return (ret); |
|
+ |
|
+ if (key->external) { |
|
+ if (priv.nelements != 0) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ if (pub == NULL) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ |
|
+ key->keydata.pkey = pub->keydata.pkey; |
|
+ pub->keydata.pkey = NULL; |
|
+ key->key_size = pub->key_size; |
|
+ |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ } |
|
+ |
|
+ for (i = 0; i < priv.nelements; i++) { |
|
+ switch (priv.elements[i].tag) { |
|
+ case TAG_RSA_ENGINE: |
|
+ engine = (char *)priv.elements[i].data; |
|
+ break; |
|
+ case TAG_RSA_LABEL: |
|
+ label = (char *)priv.elements[i].data; |
|
+ break; |
|
+ default: |
|
+ break; |
|
+ } |
|
+ } |
|
+ rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); |
|
+ if (rsa == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(rsa, 0, sizeof(*rsa)); |
|
+ key->keydata.pkey = rsa; |
|
+ |
|
+ /* Is this key is stored in a HSM? See if we can fetch it. */ |
|
+ if ((label != NULL) || (engine != NULL)) { |
|
+ ret = pkcs11rsa_fetch(key, engine, label, pub); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ return (ret); |
|
+ } |
|
+ |
|
+ rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 8); |
|
+ if (rsa->repr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(rsa->repr, 0, sizeof(*attr) * 8); |
|
+ rsa->attrcnt = 8; |
|
+ attr = rsa->repr; |
|
+ attr[0].type = CKA_MODULUS; |
|
+ attr[1].type = CKA_PUBLIC_EXPONENT; |
|
+ attr[2].type = CKA_PRIVATE_EXPONENT; |
|
+ attr[3].type = CKA_PRIME_1; |
|
+ attr[4].type = CKA_PRIME_2; |
|
+ attr[5].type = CKA_EXPONENT_1; |
|
+ attr[6].type = CKA_EXPONENT_2; |
|
+ attr[7].type = CKA_COEFFICIENT; |
|
+ |
|
+ for (i = 0; i < priv.nelements; i++) { |
|
+ CK_BYTE *bn; |
|
+ |
|
+ switch (priv.elements[i].tag) { |
|
+ case TAG_RSA_ENGINE: |
|
+ continue; |
|
+ case TAG_RSA_LABEL: |
|
+ continue; |
|
+ default: |
|
+ bn = isc_mem_get(key->mctx, priv.elements[i].length); |
|
+ if (bn == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memcpy(bn, |
|
+ priv.elements[i].data, |
|
+ priv.elements[i].length); |
|
+ } |
|
+ |
|
+ switch (priv.elements[i].tag) { |
|
+ case TAG_RSA_MODULUS: |
|
+ attr = pk11_attribute_bytype(rsa, CKA_MODULUS); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_RSA_PUBLICEXPONENT: |
|
+ attr = pk11_attribute_bytype(rsa, |
|
+ CKA_PUBLIC_EXPONENT); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_RSA_PRIVATEEXPONENT: |
|
+ attr = pk11_attribute_bytype(rsa, |
|
+ CKA_PRIVATE_EXPONENT); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_RSA_PRIME1: |
|
+ attr = pk11_attribute_bytype(rsa, CKA_PRIME_1); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_RSA_PRIME2: |
|
+ attr = pk11_attribute_bytype(rsa, CKA_PRIME_2); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_RSA_EXPONENT1: |
|
+ attr = pk11_attribute_bytype(rsa, |
|
+ CKA_EXPONENT_1); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_RSA_EXPONENT2: |
|
+ attr = pk11_attribute_bytype(rsa, |
|
+ CKA_EXPONENT_2); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ case TAG_RSA_COEFFICIENT: |
|
+ attr = pk11_attribute_bytype(rsa, |
|
+ CKA_COEFFICIENT); |
|
+ INSIST(attr != NULL); |
|
+ attr->pValue = bn; |
|
+ attr->ulValueLen = priv.elements[i].length; |
|
+ break; |
|
+ } |
|
+ } |
|
+ |
|
+ if (rsa_check(rsa, pub->keydata.pkey) != ISC_R_SUCCESS) |
|
+ DST_RET(DST_R_INVALIDPRIVATEKEY); |
|
+ |
|
+ attr = pk11_attribute_bytype(rsa, CKA_MODULUS); |
|
+ INSIST(attr != NULL); |
|
+ key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); |
|
+ |
|
+ attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); |
|
+ INSIST(attr != NULL); |
|
+ if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) |
|
+ DST_RET(ISC_R_RANGE); |
|
+ |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pkcs11rsa_destroy(key); |
|
+ dst__privstruct_free(&priv, mctx); |
|
+ memset(&priv, 0, sizeof(priv)); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+pkcs11rsa_fromlabel(dst_key_t *key, const char *engine, const char *label, |
|
+ const char *pin) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; |
|
+ CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_RSA; |
|
+ CK_ATTRIBUTE searchTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_LABEL, NULL, 0 } |
|
+ }; |
|
+ CK_ULONG cnt; |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_object_t *rsa; |
|
+ pk11_context_t *pk11_ctx = NULL; |
|
+ isc_result_t ret; |
|
+ unsigned int i; |
|
+ |
|
+ UNUSED(pin); |
|
+ |
|
+ rsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*rsa)); |
|
+ if (rsa == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ memset(rsa, 0, sizeof(*rsa)); |
|
+ rsa->object = CK_INVALID_HANDLE; |
|
+ rsa->ontoken = ISC_TRUE; |
|
+ rsa->reqlogon = ISC_TRUE; |
|
+ key->keydata.pkey = rsa; |
|
+ |
|
+ rsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 2); |
|
+ if (rsa->repr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(rsa->repr, 0, sizeof(*attr) * 2); |
|
+ rsa->attrcnt = 2; |
|
+ attr = rsa->repr; |
|
+ attr[0].type = CKA_MODULUS; |
|
+ attr[1].type = CKA_PUBLIC_EXPONENT; |
|
+ |
|
+ ret = pk11_parse_uri(rsa, label, key->mctx, OP_RSA); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx, |
|
+ sizeof(*pk11_ctx)); |
|
+ if (pk11_ctx == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ ret = pk11_get_session(pk11_ctx, OP_RSA, ISC_TRUE, ISC_FALSE, |
|
+ rsa->reqlogon, NULL, rsa->slot); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ |
|
+ attr = pk11_attribute_bytype(rsa, CKA_LABEL); |
|
+ if (attr == NULL) { |
|
+ attr = pk11_attribute_bytype(rsa, CKA_ID); |
|
+ INSIST(attr != NULL); |
|
+ searchTemplate[3].type = CKA_ID; |
|
+ } |
|
+ searchTemplate[3].pValue = attr->pValue; |
|
+ searchTemplate[3].ulValueLen = attr->ulValueLen; |
|
+ |
|
+ PK11_RET(pkcs_C_FindObjectsInit, |
|
+ (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ PK11_RET(pkcs_C_FindObjects, |
|
+ (pk11_ctx->session, &hKey, (CK_ULONG) 1, &cnt), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); |
|
+ if (cnt == 0) |
|
+ DST_RET(ISC_R_NOTFOUND); |
|
+ if (cnt > 1) |
|
+ DST_RET(ISC_R_EXISTS); |
|
+ |
|
+ attr = rsa->repr; |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, hKey, attr, 2), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ for (i = 0; i <= 1; i++) { |
|
+ attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen); |
|
+ if (attr[i].pValue == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ memset(attr[i].pValue, 0, attr[i].ulValueLen); |
|
+ } |
|
+ PK11_RET(pkcs_C_GetAttributeValue, |
|
+ (pk11_ctx->session, hKey, attr, 2), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ |
|
+ keyClass = CKO_PRIVATE_KEY; |
|
+ PK11_RET(pkcs_C_FindObjectsInit, |
|
+ (pk11_ctx->session, searchTemplate, (CK_ULONG) 4), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ PK11_RET(pkcs_C_FindObjects, |
|
+ (pk11_ctx->session, &rsa->object, (CK_ULONG) 1, &cnt), |
|
+ DST_R_CRYPTOFAILURE); |
|
+ (void) pkcs_C_FindObjectsFinal(pk11_ctx->session); |
|
+ if (cnt == 0) |
|
+ DST_RET(ISC_R_NOTFOUND); |
|
+ if (cnt > 1) |
|
+ DST_RET(ISC_R_EXISTS); |
|
+ |
|
+ if (engine != NULL) { |
|
+ key->engine = isc_mem_strdup(key->mctx, engine); |
|
+ if (key->engine == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ } |
|
+ |
|
+ key->label = isc_mem_strdup(key->mctx, label); |
|
+ if (key->label == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ |
|
+ attr = pk11_attribute_bytype(rsa, CKA_PUBLIC_EXPONENT); |
|
+ INSIST(attr != NULL); |
|
+ if (pk11_numbits(attr->pValue, attr->ulValueLen) > RSA_MAX_PUBEXP_BITS) |
|
+ DST_RET(ISC_R_RANGE); |
|
+ |
|
+ attr = pk11_attribute_bytype(rsa, CKA_MODULUS); |
|
+ INSIST(attr != NULL); |
|
+ key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen); |
|
+ |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ |
|
+ return (ISC_R_SUCCESS); |
|
+ |
|
+ err: |
|
+ pkcs11rsa_destroy(key); |
|
+ if (pk11_ctx != NULL) { |
|
+ pk11_return_session(pk11_ctx); |
|
+ memset(pk11_ctx, 0, sizeof(*pk11_ctx)); |
|
+ isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx)); |
|
+ } |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static dst_func_t pkcs11rsa_functions = { |
|
+ pkcs11rsa_createctx, |
|
+ pkcs11rsa_createctx2, |
|
+ pkcs11rsa_destroyctx, |
|
+ pkcs11rsa_adddata, |
|
+ pkcs11rsa_sign, |
|
+ pkcs11rsa_verify, |
|
+ NULL, /*%< verify2 */ |
|
+ NULL, /*%< computesecret */ |
|
+ pkcs11rsa_compare, |
|
+ NULL, /*%< paramcompare */ |
|
+ pkcs11rsa_generate, |
|
+ pkcs11rsa_isprivate, |
|
+ pkcs11rsa_destroy, |
|
+ pkcs11rsa_todns, |
|
+ pkcs11rsa_fromdns, |
|
+ pkcs11rsa_tofile, |
|
+ pkcs11rsa_parse, |
|
+ NULL, /*%< cleanup */ |
|
+ pkcs11rsa_fromlabel, |
|
+ NULL, /*%< dump */ |
|
+ NULL, /*%< restore */ |
|
+}; |
|
+ |
|
+isc_result_t |
|
+dst__pkcs11rsa_init(dst_func_t **funcp) { |
|
+ REQUIRE(funcp != NULL); |
|
+ |
|
+ if (*funcp == NULL) |
|
+ *funcp = &pkcs11rsa_functions; |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+#else /* PKCS11CRYPTO */ |
|
+ |
|
+#include <isc/util.h> |
|
+ |
|
+EMPTY_TRANSLATION_UNIT |
|
+ |
|
+#endif /* PKCS11CRYPTO */ |
|
+/*! \file */ |
|
diff --git a/lib/dns/rdata/generic/dlv_32769.c b/lib/dns/rdata/generic/dlv_32769.c |
|
index 5751ad8..732abdb 100644 |
|
--- a/lib/dns/rdata/generic/dlv_32769.c |
|
+++ b/lib/dns/rdata/generic/dlv_32769.c |
|
@@ -28,6 +28,7 @@ |
|
|
|
#include <dns/ds.h> |
|
|
|
+#include "dst_gost.h" |
|
|
|
static inline isc_result_t |
|
fromtext_dlv(ARGS_FROMTEXT) { |
|
@@ -81,9 +82,11 @@ fromtext_dlv(ARGS_FROMTEXT) { |
|
case DNS_DSDIGEST_SHA256: |
|
length = ISC_SHA256_DIGESTLENGTH; |
|
break; |
|
+#ifdef ISC_GOST_DIGESTLENGTH |
|
case DNS_DSDIGEST_GOST: |
|
length = ISC_GOST_DIGESTLENGTH; |
|
break; |
|
+#endif |
|
case DNS_DSDIGEST_SHA384: |
|
length = ISC_SHA384_DIGESTLENGTH; |
|
break; |
|
@@ -168,8 +171,10 @@ fromwire_dlv(ARGS_FROMWIRE) { |
|
sr.length < 4 + ISC_SHA1_DIGESTLENGTH) || |
|
(sr.base[3] == DNS_DSDIGEST_SHA256 && |
|
sr.length < 4 + ISC_SHA256_DIGESTLENGTH) || |
|
+#ifdef ISC_GOST_DIGESTLENGTH |
|
(sr.base[3] == DNS_DSDIGEST_GOST && |
|
sr.length < 4 + ISC_GOST_DIGESTLENGTH) || |
|
+#endif |
|
(sr.base[3] == DNS_DSDIGEST_SHA384 && |
|
sr.length < 4 + ISC_SHA384_DIGESTLENGTH)) |
|
return (ISC_R_UNEXPECTEDEND); |
|
@@ -183,8 +188,10 @@ fromwire_dlv(ARGS_FROMWIRE) { |
|
sr.length = 4 + ISC_SHA1_DIGESTLENGTH; |
|
else if (sr.base[3] == DNS_DSDIGEST_SHA256) |
|
sr.length = 4 + ISC_SHA256_DIGESTLENGTH; |
|
+#ifdef ISC_GOST_DIGESTLENGTH |
|
else if (sr.base[3] == DNS_DSDIGEST_GOST) |
|
sr.length = 4 + ISC_GOST_DIGESTLENGTH; |
|
+#endif |
|
else if (sr.base[3] == DNS_DSDIGEST_SHA384) |
|
sr.length = 4 + ISC_SHA384_DIGESTLENGTH; |
|
|
|
@@ -236,9 +243,11 @@ fromstruct_dlv(ARGS_FROMSTRUCT) { |
|
case DNS_DSDIGEST_SHA256: |
|
REQUIRE(dlv->length == ISC_SHA256_DIGESTLENGTH); |
|
break; |
|
+#ifdef ISC_GOST_DIGESTLENGTH |
|
case DNS_DSDIGEST_GOST: |
|
REQUIRE(dlv->length == ISC_GOST_DIGESTLENGTH); |
|
break; |
|
+#endif |
|
case DNS_DSDIGEST_SHA384: |
|
REQUIRE(dlv->length == ISC_SHA384_DIGESTLENGTH); |
|
break; |
|
diff --git a/lib/dns/rdata/generic/ds_43.c b/lib/dns/rdata/generic/ds_43.c |
|
index dd47c8d..fc7f126 100644 |
|
--- a/lib/dns/rdata/generic/ds_43.c |
|
+++ b/lib/dns/rdata/generic/ds_43.c |
|
@@ -30,6 +30,8 @@ |
|
|
|
#include <dns/ds.h> |
|
|
|
+#include "dst_gost.h" |
|
+ |
|
static inline isc_result_t |
|
fromtext_ds(ARGS_FROMTEXT) { |
|
isc_token_t token; |
|
@@ -81,9 +83,11 @@ fromtext_ds(ARGS_FROMTEXT) { |
|
case DNS_DSDIGEST_SHA256: |
|
length = ISC_SHA256_DIGESTLENGTH; |
|
break; |
|
+#ifdef ISC_GOST_DIGESTLENGTH |
|
case DNS_DSDIGEST_GOST: |
|
length = ISC_GOST_DIGESTLENGTH; |
|
break; |
|
+#endif |
|
case DNS_DSDIGEST_SHA384: |
|
length = ISC_SHA384_DIGESTLENGTH; |
|
break; |
|
@@ -168,8 +172,10 @@ fromwire_ds(ARGS_FROMWIRE) { |
|
sr.length < 4 + ISC_SHA1_DIGESTLENGTH) || |
|
(sr.base[3] == DNS_DSDIGEST_SHA256 && |
|
sr.length < 4 + ISC_SHA256_DIGESTLENGTH) || |
|
+#ifdef ISC_GOST_DIGESTLENGTH |
|
(sr.base[3] == DNS_DSDIGEST_GOST && |
|
sr.length < 4 + ISC_GOST_DIGESTLENGTH) || |
|
+#endif |
|
(sr.base[3] == DNS_DSDIGEST_SHA384 && |
|
sr.length < 4 + ISC_SHA384_DIGESTLENGTH)) |
|
return (ISC_R_UNEXPECTEDEND); |
|
@@ -183,8 +189,10 @@ fromwire_ds(ARGS_FROMWIRE) { |
|
sr.length = 4 + ISC_SHA1_DIGESTLENGTH; |
|
else if (sr.base[3] == DNS_DSDIGEST_SHA256) |
|
sr.length = 4 + ISC_SHA256_DIGESTLENGTH; |
|
+#ifdef ISC_GOST_DIGESTLENGTH |
|
else if (sr.base[3] == DNS_DSDIGEST_GOST) |
|
sr.length = 4 + ISC_GOST_DIGESTLENGTH; |
|
+#endif |
|
else if (sr.base[3] == DNS_DSDIGEST_SHA384) |
|
sr.length = 4 + ISC_SHA384_DIGESTLENGTH; |
|
|
|
@@ -236,9 +244,11 @@ fromstruct_ds(ARGS_FROMSTRUCT) { |
|
case DNS_DSDIGEST_SHA256: |
|
REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH); |
|
break; |
|
+#ifdef ISC_GOST_DIGESTLENGTH |
|
case DNS_DSDIGEST_GOST: |
|
REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH); |
|
break; |
|
+#endif |
|
case DNS_DSDIGEST_SHA384: |
|
REQUIRE(ds->length == ISC_SHA384_DIGESTLENGTH); |
|
break; |
|
diff --git a/lib/dns/tests/Makefile.in b/lib/dns/tests/Makefile.in |
|
index db47476..3b19784 100644 |
|
--- a/lib/dns/tests/Makefile.in |
|
+++ b/lib/dns/tests/Makefile.in |
|
@@ -26,8 +26,9 @@ top_srcdir = @top_srcdir@ |
|
|
|
@BIND9_MAKE_INCLUDES@ |
|
|
|
-CINCLUDES = -I. -Iinclude ${DNS_INCLUDES} ${ISC_INCLUDES} @DST_OPENSSL_INC@ |
|
-CDEFINES = @USE_OPENSSL@ -DTESTS="\"${top_builddir}/lib/dns/tests/\"" |
|
+CINCLUDES = -I. -Iinclude ${DNS_INCLUDES} ${ISC_INCLUDES} \ |
|
+ @DST_OPENSSL_INC@ |
|
+CDEFINES = @CRYPTO@ -DTESTS="\"${top_builddir}/lib/dns/tests/\"" |
|
|
|
ISCLIBS = ../../isc/libisc.@A@ |
|
ISCDEPLIBS = ../../isc/libisc.@A@ |
|
@@ -37,13 +38,13 @@ DNSDEPLIBS = ../libdns.@A@ |
|
LIBS = @LIBS@ @ATFLIBS@ |
|
|
|
OBJS = dnstest.@O@ |
|
-SRCS = dnstest.c master_test.c dbiterator_test.c time_test.c \ |
|
+SRCS = dnstest.c gost_test.c master_test.c dbiterator_test.c time_test.c \ |
|
private_test.c update_test.c zonemgr_test.c zt_test.c \ |
|
dbdiff_test.c dispatch_test.c nsec3_test.c \ |
|
rdataset_test.c rdata_test.c |
|
|
|
SUBDIRS = |
|
-TARGETS = master_test@EXEEXT@ dbiterator_test@EXEEXT@ time_test@EXEEXT@ \ |
|
+TARGETS = gost_test@EXEEXT@ master_test@EXEEXT@ dbiterator_test@EXEEXT@ time_test@EXEEXT@ \ |
|
private_test@EXEEXT@ update_test@EXEEXT@ zonemgr_test@EXEEXT@ \ |
|
zt_test@EXEEXT@ dbversion_test@EXEEXT@ dbdiff_test@EXEEXT@ \ |
|
dispatch_test@EXEEXT@ nsec3_test@EXEEXT@ \ |
|
@@ -123,6 +124,11 @@ dispatch_test@EXEEXT@: dispatch_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
dispatch_test.@O@ dnstest.@O@ ${DNSLIBS} \ |
|
${ISCLIBS} ${LIBS} |
|
|
|
+gost_test@EXEEXT@: gost_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS} |
|
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \ |
|
+ gost_test.@O@ dnstest.@O@ ${DNSLIBS} \ |
|
+ ${ISCLIBS} ${LIBS} |
|
+ |
|
unit:: |
|
sh ${top_srcdir}/unit/unittest.sh |
|
|
|
diff --git a/lib/dns/tests/gost_test.c b/lib/dns/tests/gost_test.c |
|
new file mode 100644 |
|
index 0000000..0dd9e55 |
|
--- /dev/null |
|
+++ b/lib/dns/tests/gost_test.c |
|
@@ -0,0 +1,232 @@ |
|
+/* |
|
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/* ! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <atf-c.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <string.h> |
|
+ |
|
+#include <isc/util.h> |
|
+#include <isc/string.h> |
|
+ |
|
+#include "dnstest.h" |
|
+ |
|
+#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) |
|
+ |
|
+#include "../dst_gost.h" |
|
+ |
|
+/* |
|
+ * Test data from Wikipedia GOST (hash function) |
|
+ */ |
|
+ |
|
+unsigned char digest[ISC_GOST_DIGESTLENGTH]; |
|
+unsigned char buffer[1024]; |
|
+const char *s; |
|
+char str[ISC_GOST_DIGESTLENGTH]; |
|
+int i = 0; |
|
+ |
|
+isc_result_t |
|
+tohexstr(unsigned char *d, unsigned int len, char *out); |
|
+/* |
|
+ * Precondition: a hexadecimal number in *d, the length of that number in len, |
|
+ * and a pointer to a character array to put the output (*out). |
|
+ * Postcondition: A String representation of the given hexadecimal number is |
|
+ * placed into the array *out |
|
+ * |
|
+ * 'out' MUST point to an array of at least len / 2 + 1 |
|
+ * |
|
+ * Return values: ISC_R_SUCCESS if the operation is sucessful |
|
+ */ |
|
+ |
|
+isc_result_t |
|
+tohexstr(unsigned char *d, unsigned int len, char *out) { |
|
+ |
|
+ out[0]='\0'; |
|
+ char c_ret[] = "AA"; |
|
+ unsigned int i; |
|
+ strcat(out, "0x"); |
|
+ for (i = 0; i < len; i++) { |
|
+ sprintf(c_ret, "%02X", d[i]); |
|
+ strcat(out, c_ret); |
|
+ } |
|
+ strcat(out, "\0"); |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+ |
|
+#define TEST_INPUT(x) (x), sizeof(x)-1 |
|
+ |
|
+typedef struct hash_testcase { |
|
+ const char *input; |
|
+ size_t input_len; |
|
+ const char *result; |
|
+ int repeats; |
|
+} hash_testcase_t; |
|
+ |
|
+ATF_TC(isc_gost); |
|
+ATF_TC_HEAD(isc_gost, tc) { |
|
+ atf_tc_set_md_var(tc, "descr", |
|
+ "GOST R 34.11-94 examples from Wikipedia"); |
|
+} |
|
+ATF_TC_BODY(isc_gost, tc) { |
|
+ isc_gost_t gost; |
|
+ isc_result_t result; |
|
+ |
|
+ UNUSED(tc); |
|
+ |
|
+ /* |
|
+ * These are the various test vectors. All of these are passed |
|
+ * through the hash function and the results are compared to the |
|
+ * result specified here. |
|
+ */ |
|
+ hash_testcase_t testcases[] = { |
|
+ /* Test 1 */ |
|
+ { |
|
+ TEST_INPUT(""), |
|
+ "0x981E5F3CA30C841487830F84FB433E1" |
|
+ "3AC1101569B9C13584AC483234CD656C0", |
|
+ 1 |
|
+ }, |
|
+ /* Test 2 */ |
|
+ { |
|
+ TEST_INPUT("a"), |
|
+ "0xE74C52DD282183BF37AF0079C9F7805" |
|
+ "5715A103F17E3133CEFF1AACF2F403011", |
|
+ 1 |
|
+ }, |
|
+ /* Test 3 */ |
|
+ { |
|
+ TEST_INPUT("abc"), |
|
+ "0xB285056DBF18D7392D7677369524DD1" |
|
+ "4747459ED8143997E163B2986F92FD42C", |
|
+ 1 |
|
+ }, |
|
+ /* Test 4 */ |
|
+ { |
|
+ TEST_INPUT("message digest"), |
|
+ "0xBC6041DD2AA401EBFA6E9886734174F" |
|
+ "EBDB4729AA972D60F549AC39B29721BA0", |
|
+ 1 |
|
+ }, |
|
+ /* Test 5 */ |
|
+ { |
|
+ TEST_INPUT("The quick brown fox jumps " |
|
+ "over the lazy dog"), |
|
+ "0x9004294A361A508C586FE53D1F1B027" |
|
+ "46765E71B765472786E4770D565830A76", |
|
+ 1 |
|
+ }, |
|
+ /* Test 6 */ |
|
+ { |
|
+ TEST_INPUT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcde" |
|
+ "fghijklmnopqrstuvwxyz0123456789"), |
|
+ "0x73B70A39497DE53A6E08C67B6D4DB85" |
|
+ "3540F03E9389299D9B0156EF7E85D0F61", |
|
+ 1 |
|
+ }, |
|
+ /* Test 7 */ |
|
+ { |
|
+ TEST_INPUT("1234567890123456789012345678901" |
|
+ "2345678901234567890123456789012" |
|
+ "345678901234567890"), |
|
+ "0x6BC7B38989B28CF93AE8842BF9D7529" |
|
+ "05910A7528A61E5BCE0782DE43E610C90", |
|
+ 1 |
|
+ }, |
|
+ /* Test 8 */ |
|
+ { |
|
+ TEST_INPUT("This is message, length=32 bytes"), |
|
+ "0x2CEFC2F7B7BDC514E18EA57FA74FF35" |
|
+ "7E7FA17D652C75F69CB1BE7893EDE48EB", |
|
+ 1 |
|
+ }, |
|
+ /* Test 9 */ |
|
+ { |
|
+ TEST_INPUT("Suppose the original message " |
|
+ "has length = 50 bytes"), |
|
+ "0xC3730C5CBCCACF915AC292676F21E8B" |
|
+ "D4EF75331D9405E5F1A61DC3130A65011", |
|
+ 1 |
|
+ }, |
|
+ /* Test 10 */ |
|
+ { |
|
+ TEST_INPUT("U") /* times 128 */, |
|
+ "0x1C4AC7614691BBF427FA2316216BE8F" |
|
+ "10D92EDFD37CD1027514C1008F649C4E8", |
|
+ 128 |
|
+ }, |
|
+ /* Test 11 */ |
|
+ { |
|
+ TEST_INPUT("a") /* times 1000000 */, |
|
+ "0x8693287AA62F9478F7CB312EC0866B6" |
|
+ "C4E4A0F11160441E8F4FFCD2715DD554F", |
|
+ 1000000 |
|
+ }, |
|
+ { NULL, 0, NULL, 1 } |
|
+ }; |
|
+ |
|
+ result = dns_test_begin(NULL, ISC_FALSE); |
|
+ ATF_REQUIRE(result == ISC_R_SUCCESS); |
|
+ |
|
+ hash_testcase_t *testcase = testcases; |
|
+ |
|
+ while (testcase->input != NULL && testcase->result != NULL) { |
|
+ result = isc_gost_init(&gost); |
|
+ ATF_REQUIRE(result == ISC_R_SUCCESS); |
|
+ for(i = 0; i < testcase->repeats; i++) { |
|
+ result = isc_gost_update(&gost, |
|
+ (const isc_uint8_t *) testcase->input, |
|
+ testcase->input_len); |
|
+ ATF_REQUIRE(result == ISC_R_SUCCESS); |
|
+ } |
|
+ result = isc_gost_final(&gost, digest); |
|
+ ATF_REQUIRE(result == ISC_R_SUCCESS); |
|
+ tohexstr(digest, ISC_GOST_DIGESTLENGTH, str); |
|
+ ATF_CHECK_STREQ(str, testcase->result); |
|
+ |
|
+ testcase++; |
|
+ } |
|
+ |
|
+ dns_test_end(); |
|
+} |
|
+#else |
|
+ATF_TC(untested); |
|
+ATF_TC_HEAD(untested, tc) { |
|
+ atf_tc_set_md_var(tc, "descr", "skipping gost test"); |
|
+} |
|
+ATF_TC_BODY(untested, tc) { |
|
+ UNUSED(tc); |
|
+ atf_tc_skip("GOST hash not available"); |
|
+} |
|
+#endif |
|
+/* |
|
+ * Main |
|
+ */ |
|
+ATF_TP_ADD_TCS(tp) { |
|
+#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST) |
|
+ ATF_TP_ADD_TC(tp, isc_gost); |
|
+#else |
|
+ ATF_TP_ADD_TC(tp, untested); |
|
+#endif |
|
+ return (atf_no_error()); |
|
+} |
|
+ |
|
diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c |
|
index 161c188..20c98e5 100644 |
|
--- a/lib/dns/tkey.c |
|
+++ b/lib/dns/tkey.c |
|
@@ -45,8 +45,14 @@ |
|
#include <dst/dst.h> |
|
#include <dst/gssapi.h> |
|
|
|
+#include "dst_internal.h" |
|
+ |
|
#define TKEY_RANDOM_AMOUNT 16 |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+#include <pk11/pk11.h> |
|
+#endif |
|
+ |
|
#define RETERR(x) do { \ |
|
result = (x); \ |
|
if (result != ISC_R_SUCCESS) \ |
|
@@ -382,8 +388,8 @@ process_dhtkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name, |
|
if (randomdata == NULL) |
|
goto failure; |
|
|
|
- result = isc_entropy_getdata(tctx->ectx, randomdata, |
|
- TKEY_RANDOM_AMOUNT, NULL, 0); |
|
+ result = dst__entropy_getdata(randomdata, TKEY_RANDOM_AMOUNT, |
|
+ ISC_FALSE); |
|
if (result != ISC_R_SUCCESS) { |
|
tkey_log("process_dhtkey: failed to obtain entropy: %s", |
|
isc_result_totext(result)); |
|
diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c |
|
index c7768f4..3239bff 100644 |
|
--- a/lib/dns/tsig.c |
|
+++ b/lib/dns/tsig.c |
|
@@ -946,8 +946,9 @@ dns_tsig_sign(dns_message_t *msg) { |
|
isc_buffer_t headerbuf; |
|
isc_uint16_t digestbits; |
|
|
|
- ret = dst_context_create2(key->key, mctx, |
|
- DNS_LOGCATEGORY_DNSSEC, &ctx); |
|
+ ret = dst_context_create3(key->key, mctx, |
|
+ DNS_LOGCATEGORY_DNSSEC, |
|
+ ISC_TRUE, &ctx); |
|
if (ret != ISC_R_SUCCESS) |
|
return (ret); |
|
|
|
@@ -1345,8 +1346,9 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, |
|
sig_r.base = tsig.signature; |
|
sig_r.length = tsig.siglen; |
|
|
|
- ret = dst_context_create2(key, mctx, |
|
- DNS_LOGCATEGORY_DNSSEC, &ctx); |
|
+ ret = dst_context_create3(key, mctx, |
|
+ DNS_LOGCATEGORY_DNSSEC, |
|
+ ISC_FALSE, &ctx); |
|
if (ret != ISC_R_SUCCESS) |
|
return (ret); |
|
|
|
@@ -1577,9 +1579,9 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) { |
|
key = tsigkey->key; |
|
|
|
if (msg->tsigctx == NULL) { |
|
- ret = dst_context_create2(key, mctx, |
|
+ ret = dst_context_create3(key, mctx, |
|
DNS_LOGCATEGORY_DNSSEC, |
|
- &msg->tsigctx); |
|
+ ISC_FALSE, &msg->tsigctx); |
|
if (ret != ISC_R_SUCCESS) |
|
goto cleanup_querystruct; |
|
|
|
diff --git a/lib/export/dns/Makefile.in b/lib/export/dns/Makefile.in |
|
index 1e4540f..e10bf59 100644 |
|
--- a/lib/export/dns/Makefile.in |
|
+++ b/lib/export/dns/Makefile.in |
|
@@ -28,10 +28,10 @@ export_srcdir = @top_srcdir@/lib/export |
|
|
|
@BIND9_MAKE_INCLUDES@ |
|
|
|
-CINCLUDES = -I. -Iinclude ${DNS_INCLUDES} -I${export_srcdir}/isc/include \ |
|
+CINCLUDES = -I. -I${top_srcdir}/lib/dns -Iinclude ${DNS_INCLUDES} -I${export_srcdir}/isc/include \ |
|
${ISC_INCLUDES} @DST_OPENSSL_INC@ @DST_GSSAPI_INC@ |
|
|
|
-CDEFINES = -DUSE_MD5 @USE_OPENSSL@ @USE_GSSAPI@ |
|
+CDEFINES = -DUSE_MD5 @CRYPTO@ @USE_GSSAPI@ |
|
|
|
CWARNINGS = |
|
|
|
diff --git a/lib/export/isc/Makefile.in b/lib/export/isc/Makefile.in |
|
index 62e5acd..a5f8bd0 100644 |
|
--- a/lib/export/isc/Makefile.in |
|
+++ b/lib/export/isc/Makefile.in |
|
@@ -27,7 +27,7 @@ CINCLUDES = -I${srcdir}/unix/include \ |
|
-I${srcdir}/@ISC_ARCH_DIR@/include \ |
|
-I${export_srcdir}/isc/include -I${srcdir}/include \ |
|
@ISC_OPENSSL_INC@ |
|
-CDEFINES = @USE_OPENSSL@ -DUSE_APPIMPREGISTER -DUSE_MEMIMPREGISTER \ |
|
+CDEFINES = @CRYPTO@ -DUSE_APPIMPREGISTER -DUSE_MEMIMPREGISTER \ |
|
-DUSE_SOCKETIMPREGISTER -DUSE_TASKIMPREGISTER \ |
|
-DUSE_TIMERIMPREGISTER |
|
CWARNINGS = |
|
@@ -48,7 +48,8 @@ UNIXOBJS = @ISC_ISCIPV6_O@ \ |
|
unix/file.@O@ \ |
|
unix/fsaccess.@O@ \ |
|
unix/stdio.@O@ \ |
|
- unix/stdtime.@O@ unix/strerror.@O@ unix/time.@O@ |
|
+ unix/stdtime.@O@ unix/strerror.@O@ unix/time.@O@ unix/entropy.@O@ \ |
|
+ unix/keyboard.@O@ |
|
|
|
NLSOBJS = nls/msgcat.@O@ |
|
|
|
diff --git a/lib/export/isc/unix/Makefile.in b/lib/export/isc/unix/Makefile.in |
|
index 1873202..a904615 100644 |
|
--- a/lib/export/isc/unix/Makefile.in |
|
+++ b/lib/export/isc/unix/Makefile.in |
|
@@ -40,6 +40,8 @@ OBJS = @ISC_IPV6_O@ \ |
|
file.@O@ fsaccess.@O@ \ |
|
stdio.@O@ stdtime.@O@ strerror.@O@ \ |
|
time.@O@ \ |
|
+ entropy.@O@ \ |
|
+ keyboard.@O@ \ |
|
${ISCDRIVEROBJS} |
|
|
|
# Alphabetically |
|
@@ -51,6 +53,8 @@ SRCS = @ISC_IPV6_C@ \ |
|
file.c fsaccess.c \ |
|
stdio.c stdtime.c strerror.c \ |
|
time.c \ |
|
+ entropy.c \ |
|
+ keyboard.c \ |
|
${ISCDRIVERSRCS} |
|
|
|
SUBDIRS = include |
|
diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in |
|
index eb718fd..df62ec9 100644 |
|
--- a/lib/isc/Makefile.in |
|
+++ b/lib/isc/Makefile.in |
|
@@ -23,16 +23,20 @@ top_srcdir = @top_srcdir@ |
|
|
|
@LIBISC_API@ |
|
|
|
+@BIND9_MAKE_INCLUDES@ |
|
+ |
|
+PROVIDER = @PKCS11_PROVIDER@ |
|
+ |
|
CINCLUDES = -I${srcdir}/unix/include \ |
|
-I${srcdir}/@ISC_THREAD_DIR@/include \ |
|
-I${srcdir}/@ISC_ARCH_DIR@/include \ |
|
-I./include \ |
|
- -I${srcdir}/include @ISC_OPENSSL_INC@ |
|
-CDEFINES = @USE_OPENSSL@ |
|
+ -I${srcdir}/include @ISC_OPENSSL_INC@ ${DNS_INCLUDES} |
|
+CDEFINES = @CRYPTO@ -DPK11_LIB_LOCATION=\"${PROVIDER}\" |
|
CWARNINGS = |
|
|
|
# Alphabetically |
|
-UNIXOBJS = @ISC_ISCIPV6_O@ \ |
|
+UNIXOBJS = @ISC_ISCIPV6_O@ @ISC_ISCPK11_API_O@ \ |
|
unix/app.@O@ unix/dir.@O@ unix/entropy.@O@ \ |
|
unix/errno2result.@O@ unix/file.@O@ unix/fsaccess.@O@ \ |
|
unix/interfaceiter.@O@ unix/keyboard.@O@ unix/net.@O@ \ |
|
@@ -50,7 +54,7 @@ WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/file.@O@ \ |
|
win32/thread.@O@ win32/time.@O@ |
|
|
|
# Alphabetically |
|
-OBJS = @ISC_EXTRA_OBJS@ \ |
|
+OBJS = @ISC_EXTRA_OBJS@ @ISC_PK11_O@ @ISC_PK11_RESULT_O@ \ |
|
assertions.@O@ backtrace.@O@ base32.@O@ base64.@O@ \ |
|
bitstring.@O@ buffer.@O@ bufferlist.@O@ commandline.@O@ \ |
|
counter.@O@ error.@O@ event.@O@ \ |
|
@@ -68,7 +72,7 @@ OBJS = @ISC_EXTRA_OBJS@ \ |
|
SYMTBLOBJS = backtrace-emptytbl.@O@ |
|
|
|
# Alphabetically |
|
-SRCS = @ISC_EXTRA_SRCS@ \ |
|
+SRCS = @ISC_EXTRA_SRCS@ @ISC_PK11_C@ @ISC_PK11_RESULT_C@ \ |
|
assertions.c backtrace.c base32.c base64.c bitstring.c \ |
|
buffer.c bufferlist.c commandline.c counter.c \ |
|
error.c event.c heap.c hex.c hmacmd5.c hmacsha.c \ |
|
diff --git a/lib/isc/entropy.c b/lib/isc/entropy.c |
|
index da9e81f..ae882d8 100644 |
|
--- a/lib/isc/entropy.c |
|
+++ b/lib/isc/entropy.c |
|
@@ -46,6 +46,9 @@ |
|
#include <isc/time.h> |
|
#include <isc/util.h> |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+#include <pk11/pk11.h> |
|
+#endif |
|
|
|
#define ENTROPY_MAGIC ISC_MAGIC('E', 'n', 't', 'e') |
|
#define SOURCE_MAGIC ISC_MAGIC('E', 'n', 't', 's') |
|
@@ -1236,6 +1239,11 @@ isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source, |
|
use_keyboard == ISC_ENTROPY_KEYBOARDNO || |
|
use_keyboard == ISC_ENTROPY_KEYBOARDMAYBE); |
|
|
|
+#ifdef PKCS11CRYPTO |
|
+ if (randomfile != NULL) |
|
+ pk11_rand_seed_fromfile(randomfile); |
|
+#endif |
|
+ |
|
#ifdef PATH_RANDOMDEV |
|
if (randomfile == NULL) { |
|
randomfile = PATH_RANDOMDEV; |
|
diff --git a/lib/isc/hmacmd5.c b/lib/isc/hmacmd5.c |
|
index 4c4046d..79ec24a 100644 |
|
--- a/lib/isc/hmacmd5.c |
|
+++ b/lib/isc/hmacmd5.c |
|
@@ -33,6 +33,11 @@ |
|
#include <isc/types.h> |
|
#include <isc/util.h> |
|
|
|
+#if PKCS11CRYPTO || PKCS11CRYPTOWITHHMAC |
|
+#include <pk11/internal.h> |
|
+#include <pk11/pk11.h> |
|
+#endif |
|
+ |
|
#ifdef ISC_PLATFORM_OPENSSLHASH |
|
|
|
void |
|
@@ -60,6 +65,167 @@ isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) { |
|
HMAC_CTX_cleanup(ctx); |
|
} |
|
|
|
+#elif PKCS11CRYPTOWITHHMAC |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+void |
|
+isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_MD5_HMAC, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_MD5_HMAC; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_VALUE, NULL, (CK_ULONG) len } |
|
+ }; |
|
+ |
|
+ DE_CONST(key, keyTemplate[5].pValue); |
|
+ RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ PK11_FATALCHECK(pkcs_C_CreateObject, |
|
+ (ctx->session, keyTemplate, |
|
+ (CK_ULONG) 6, &ctx->object)); |
|
+ INSIST(ctx->object != CK_INVALID_HANDLE); |
|
+ PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) { |
|
+ CK_BYTE garbage[ISC_MD5_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_MD5_DIGESTLENGTH; |
|
+ |
|
+ if (ctx->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_SignFinal(ctx->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ if (ctx->object != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx->session, ctx->object); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ DE_CONST(buf, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_SignUpdate, |
|
+ (ctx->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) { |
|
+ CK_RV rv; |
|
+ CK_ULONG len = ISC_MD5_DIGESTLENGTH; |
|
+ |
|
+ PK11_FATALCHECK(pkcs_C_SignFinal, |
|
+ (ctx->session, (CK_BYTE_PTR) digest, &len)); |
|
+ if (ctx->object != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx->session, ctx->object); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
+#elif PKCS11CRYPTO |
|
+ |
|
+#define PADLEN 64 |
|
+#define IPAD 0x36 |
|
+#define OPAD 0x5C |
|
+ |
|
+void |
|
+isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_MD5, NULL, 0 }; |
|
+ unsigned char ipad[PADLEN]; |
|
+ unsigned int i; |
|
+ |
|
+ RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ RUNTIME_CHECK((ctx->key = pk11_mem_get(PADLEN)) != NULL); |
|
+ if (len > PADLEN) { |
|
+ CK_BYTE_PTR kPart; |
|
+ CK_ULONG kl; |
|
+ |
|
+ PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech)); |
|
+ DE_CONST(key, kPart); |
|
+ PK11_FATALCHECK(pkcs_C_DigestUpdate, |
|
+ (ctx->session, kPart, (CK_ULONG) len)); |
|
+ kl = ISC_MD5_DIGESTLENGTH; |
|
+ PK11_FATALCHECK(pkcs_C_DigestFinal, |
|
+ (ctx->session, (CK_BYTE_PTR) ctx->key, &kl)); |
|
+ } else |
|
+ memcpy(ctx->key, key, len); |
|
+ PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech)); |
|
+ memset(ipad, IPAD, PADLEN); |
|
+ for (i = 0; i < PADLEN; i++) |
|
+ ipad[i] ^= ctx->key[i]; |
|
+ PK11_FATALCHECK(pkcs_C_DigestUpdate, |
|
+ (ctx->session, ipad, (CK_ULONG) PADLEN)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) { |
|
+ if (ctx->key != NULL) |
|
+ pk11_mem_put(ctx->key, PADLEN); |
|
+ ctx->key = NULL; |
|
+ isc_md5_invalidate(ctx); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ DE_CONST(buf, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_DigestUpdate, |
|
+ (ctx->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_MD5, NULL, 0 }; |
|
+ CK_ULONG len = ISC_MD5_DIGESTLENGTH; |
|
+ CK_BYTE opad[PADLEN]; |
|
+ unsigned int i; |
|
+ |
|
+ PK11_FATALCHECK(pkcs_C_DigestFinal, |
|
+ (ctx->session, (CK_BYTE_PTR) digest, |
|
+ (CK_ULONG_PTR) &len)); |
|
+ memset(opad, OPAD, PADLEN); |
|
+ for (i = 0; i < PADLEN; i++) |
|
+ opad[i] ^= ctx->key[i]; |
|
+ pk11_mem_put(ctx->key, PADLEN); |
|
+ ctx->key = NULL; |
|
+ PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech)); |
|
+ PK11_FATALCHECK(pkcs_C_DigestUpdate, |
|
+ (ctx->session, opad, (CK_ULONG) PADLEN)); |
|
+ PK11_FATALCHECK(pkcs_C_DigestUpdate, |
|
+ (ctx->session, (CK_BYTE_PTR) digest, len)); |
|
+ PK11_FATALCHECK(pkcs_C_DigestFinal, |
|
+ (ctx->session, |
|
+ (CK_BYTE_PTR) digest, |
|
+ (CK_ULONG_PTR) &len)); |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
#else |
|
|
|
#define PADLEN 64 |
|
diff --git a/lib/isc/hmacsha.c b/lib/isc/hmacsha.c |
|
index 3870963..9b79bc7 100644 |
|
--- a/lib/isc/hmacsha.c |
|
+++ b/lib/isc/hmacsha.c |
|
@@ -34,6 +34,11 @@ |
|
#include <isc/types.h> |
|
#include <isc/util.h> |
|
|
|
+#if PKCS11CRYPTO |
|
+#include <pk11/internal.h> |
|
+#include <pk11/pk11.h> |
|
+#endif |
|
+ |
|
#ifdef ISC_PLATFORM_OPENSSLHASH |
|
|
|
void |
|
@@ -191,6 +196,376 @@ isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { |
|
memset(newdigest, 0, sizeof(newdigest)); |
|
} |
|
|
|
+#elif PKCS11CRYPTO |
|
+ |
|
+static CK_BBOOL truevalue = TRUE; |
|
+static CK_BBOOL falsevalue = FALSE; |
|
+ |
|
+void |
|
+isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_SHA_1_HMAC, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_SHA_1_HMAC; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_VALUE, NULL, (CK_ULONG) len } |
|
+ }; |
|
+ |
|
+ DE_CONST(key, keyTemplate[5].pValue); |
|
+ RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ PK11_FATALCHECK(pkcs_C_CreateObject, |
|
+ (ctx->session, keyTemplate, |
|
+ (CK_ULONG) 6, &ctx->object)); |
|
+ INSIST(ctx->object != CK_INVALID_HANDLE); |
|
+ PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) { |
|
+ CK_BYTE garbage[ISC_SHA1_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_SHA1_DIGESTLENGTH; |
|
+ |
|
+ if (ctx->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_SignFinal(ctx->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ if (ctx->object != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx->session, ctx->object); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ DE_CONST(buf, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_SignUpdate, |
|
+ (ctx->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) { |
|
+ CK_RV rv; |
|
+ CK_BYTE newdigest[ISC_SHA1_DIGESTLENGTH]; |
|
+ CK_ULONG psl = ISC_SHA1_DIGESTLENGTH; |
|
+ |
|
+ REQUIRE(len <= ISC_SHA1_DIGESTLENGTH); |
|
+ |
|
+ PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl)); |
|
+ if (ctx->object != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx->session, ctx->object); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_return_session(ctx); |
|
+ memcpy(digest, newdigest, len); |
|
+ memset(newdigest, 0, sizeof(newdigest)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_SHA224_HMAC, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_SHA224_HMAC; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_VALUE, NULL, (CK_ULONG) len } |
|
+ }; |
|
+ |
|
+ DE_CONST(key, keyTemplate[5].pValue); |
|
+ RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ PK11_FATALCHECK(pkcs_C_CreateObject, |
|
+ (ctx->session, keyTemplate, |
|
+ (CK_ULONG) 6, &ctx->object)); |
|
+ INSIST(ctx->object != CK_INVALID_HANDLE); |
|
+ PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) { |
|
+ CK_BYTE garbage[ISC_SHA224_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_SHA224_DIGESTLENGTH; |
|
+ |
|
+ if (ctx->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_SignFinal(ctx->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ if (ctx->object != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx->session, ctx->object); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ DE_CONST(buf, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_SignUpdate, |
|
+ (ctx->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) { |
|
+ CK_RV rv; |
|
+ CK_BYTE newdigest[ISC_SHA224_DIGESTLENGTH]; |
|
+ CK_ULONG psl = ISC_SHA224_DIGESTLENGTH; |
|
+ |
|
+ REQUIRE(len <= ISC_SHA224_DIGESTLENGTH); |
|
+ |
|
+ PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl)); |
|
+ if (ctx->object != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx->session, ctx->object); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_return_session(ctx); |
|
+ memcpy(digest, newdigest, len); |
|
+ memset(newdigest, 0, sizeof(newdigest)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_SHA256_HMAC, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_SHA256_HMAC; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_VALUE, NULL, (CK_ULONG) len } |
|
+ }; |
|
+ |
|
+ DE_CONST(key, keyTemplate[5].pValue); |
|
+ RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ PK11_FATALCHECK(pkcs_C_CreateObject, |
|
+ (ctx->session, keyTemplate, |
|
+ (CK_ULONG) 6, &ctx->object)); |
|
+ INSIST(ctx->object != CK_INVALID_HANDLE); |
|
+ PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) { |
|
+ CK_BYTE garbage[ISC_SHA256_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_SHA256_DIGESTLENGTH; |
|
+ |
|
+ if (ctx->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_SignFinal(ctx->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ if (ctx->object != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx->session, ctx->object); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ DE_CONST(buf, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_SignUpdate, |
|
+ (ctx->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) { |
|
+ CK_RV rv; |
|
+ CK_BYTE newdigest[ISC_SHA256_DIGESTLENGTH]; |
|
+ CK_ULONG psl = ISC_SHA256_DIGESTLENGTH; |
|
+ |
|
+ REQUIRE(len <= ISC_SHA256_DIGESTLENGTH); |
|
+ |
|
+ PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl)); |
|
+ if (ctx->object != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx->session, ctx->object); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_return_session(ctx); |
|
+ memcpy(digest, newdigest, len); |
|
+ memset(newdigest, 0, sizeof(newdigest)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_SHA384_HMAC, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_SHA384_HMAC; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_VALUE, NULL, (CK_ULONG) len } |
|
+ }; |
|
+ |
|
+ DE_CONST(key, keyTemplate[5].pValue); |
|
+ RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ PK11_FATALCHECK(pkcs_C_CreateObject, |
|
+ (ctx->session, keyTemplate, |
|
+ (CK_ULONG) 6, &ctx->object)); |
|
+ INSIST(ctx->object != CK_INVALID_HANDLE); |
|
+ PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) { |
|
+ CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_SHA384_DIGESTLENGTH; |
|
+ |
|
+ if (ctx->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_SignFinal(ctx->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ if (ctx->object != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx->session, ctx->object); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ DE_CONST(buf, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_SignUpdate, |
|
+ (ctx->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) { |
|
+ CK_RV rv; |
|
+ CK_BYTE newdigest[ISC_SHA384_DIGESTLENGTH]; |
|
+ CK_ULONG psl = ISC_SHA384_DIGESTLENGTH; |
|
+ |
|
+ REQUIRE(len <= ISC_SHA384_DIGESTLENGTH); |
|
+ |
|
+ PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl)); |
|
+ if (ctx->object != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx->session, ctx->object); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_return_session(ctx); |
|
+ memcpy(digest, newdigest, len); |
|
+ memset(newdigest, 0, sizeof(newdigest)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_SHA512_HMAC, NULL, 0 }; |
|
+ CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; |
|
+ CK_KEY_TYPE keyType = CKK_SHA512_HMAC; |
|
+ CK_ATTRIBUTE keyTemplate[] = |
|
+ { |
|
+ { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) }, |
|
+ { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) }, |
|
+ { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) }, |
|
+ { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) }, |
|
+ { CKA_VALUE, NULL, (CK_ULONG) len } |
|
+ }; |
|
+ |
|
+ DE_CONST(key, keyTemplate[5].pValue); |
|
+ RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ PK11_FATALCHECK(pkcs_C_CreateObject, |
|
+ (ctx->session, keyTemplate, |
|
+ (CK_ULONG) 6, &ctx->object)); |
|
+ INSIST(ctx->object != CK_INVALID_HANDLE); |
|
+ PK11_FATALCHECK(pkcs_C_SignInit, (ctx->session, &mech, ctx->object)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) { |
|
+ CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_SHA512_DIGESTLENGTH; |
|
+ |
|
+ if (ctx->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_SignFinal(ctx->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ if (ctx->object != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx->session, ctx->object); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf, |
|
+ unsigned int len) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ DE_CONST(buf, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_SignUpdate, |
|
+ (ctx->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) { |
|
+ CK_RV rv; |
|
+ CK_BYTE newdigest[ISC_SHA512_DIGESTLENGTH]; |
|
+ CK_ULONG psl = ISC_SHA512_DIGESTLENGTH; |
|
+ |
|
+ REQUIRE(len <= ISC_SHA512_DIGESTLENGTH); |
|
+ |
|
+ PK11_FATALCHECK(pkcs_C_SignFinal, (ctx->session, newdigest, &psl)); |
|
+ if (ctx->object != CK_INVALID_HANDLE) |
|
+ (void) pkcs_C_DestroyObject(ctx->session, ctx->object); |
|
+ ctx->object = CK_INVALID_HANDLE; |
|
+ pk11_return_session(ctx); |
|
+ memcpy(digest, newdigest, len); |
|
+ memset(newdigest, 0, sizeof(newdigest)); |
|
+} |
|
+ |
|
#else |
|
|
|
#define IPAD 0x36 |
|
diff --git a/lib/isc/include/Makefile.in b/lib/isc/include/Makefile.in |
|
index 70c165e..c92ad45 100644 |
|
--- a/lib/isc/include/Makefile.in |
|
+++ b/lib/isc/include/Makefile.in |
|
@@ -19,7 +19,7 @@ srcdir = @srcdir@ |
|
VPATH = @srcdir@ |
|
top_srcdir = @top_srcdir@ |
|
|
|
-SUBDIRS = isc |
|
+SUBDIRS = isc pk11 pkcs11 |
|
TARGETS = |
|
|
|
@BIND9_MAKE_RULES@ |
|
diff --git a/lib/isc/include/isc/hmacmd5.h b/lib/isc/include/isc/hmacmd5.h |
|
index 9ecad45..e008328 100644 |
|
--- a/lib/isc/include/isc/hmacmd5.h |
|
+++ b/lib/isc/include/isc/hmacmd5.h |
|
@@ -37,6 +37,11 @@ |
|
|
|
typedef HMAC_CTX isc_hmacmd5_t; |
|
|
|
+#elif PKCS11CRYPTO |
|
+#include <pk11/pk11.h> |
|
+ |
|
+typedef pk11_context_t isc_hmacmd5_t; |
|
+ |
|
#else |
|
|
|
typedef struct { |
|
diff --git a/lib/isc/include/isc/hmacsha.h b/lib/isc/include/isc/hmacsha.h |
|
index 1d0e184..c223897 100644 |
|
--- a/lib/isc/include/isc/hmacsha.h |
|
+++ b/lib/isc/include/isc/hmacsha.h |
|
@@ -45,6 +45,15 @@ typedef HMAC_CTX isc_hmacsha256_t; |
|
typedef HMAC_CTX isc_hmacsha384_t; |
|
typedef HMAC_CTX isc_hmacsha512_t; |
|
|
|
+#elif PKCS11CRYPTO |
|
+#include <pk11/pk11.h> |
|
+ |
|
+typedef pk11_context_t isc_hmacsha1_t; |
|
+typedef pk11_context_t isc_hmacsha224_t; |
|
+typedef pk11_context_t isc_hmacsha256_t; |
|
+typedef pk11_context_t isc_hmacsha384_t; |
|
+typedef pk11_context_t isc_hmacsha512_t; |
|
+ |
|
#else |
|
|
|
typedef struct { |
|
diff --git a/lib/isc/include/isc/md5.h b/lib/isc/include/isc/md5.h |
|
index dfa586d..a2e00b3 100644 |
|
--- a/lib/isc/include/isc/md5.h |
|
+++ b/lib/isc/include/isc/md5.h |
|
@@ -55,6 +55,11 @@ |
|
|
|
typedef EVP_MD_CTX isc_md5_t; |
|
|
|
+#elif PKCS11CRYPTO |
|
+#include <pk11/pk11.h> |
|
+ |
|
+typedef pk11_context_t isc_md5_t; |
|
+ |
|
#else |
|
|
|
typedef struct { |
|
diff --git a/lib/isc/include/isc/resultclass.h b/lib/isc/include/isc/resultclass.h |
|
index d91e800..44b0eb4 100644 |
|
--- a/lib/isc/include/isc/resultclass.h |
|
+++ b/lib/isc/include/isc/resultclass.h |
|
@@ -46,6 +46,6 @@ |
|
#define ISC_RESULTCLASS_OMAPI ISC_RESULTCLASS_FROMNUM(4) |
|
#define ISC_RESULTCLASS_ISCCC ISC_RESULTCLASS_FROMNUM(5) |
|
#define ISC_RESULTCLASS_DHCP ISC_RESULTCLASS_FROMNUM(6) |
|
- |
|
+#define ISC_RESULTCLASS_PK11 ISC_RESULTCLASS_FROMNUM(7) |
|
|
|
#endif /* ISC_RESULTCLASS_H */ |
|
diff --git a/lib/isc/include/isc/sha1.h b/lib/isc/include/isc/sha1.h |
|
index 313ff96..f11a783 100644 |
|
--- a/lib/isc/include/isc/sha1.h |
|
+++ b/lib/isc/include/isc/sha1.h |
|
@@ -40,6 +40,11 @@ |
|
|
|
typedef EVP_MD_CTX isc_sha1_t; |
|
|
|
+#elif PKCS11CRYPTO |
|
+#include <pk11/pk11.h> |
|
+ |
|
+typedef pk11_context_t isc_sha1_t; |
|
+ |
|
#else |
|
|
|
typedef struct { |
|
diff --git a/lib/isc/include/isc/sha2.h b/lib/isc/include/isc/sha2.h |
|
index 439bbb9..14faa6e 100644 |
|
--- a/lib/isc/include/isc/sha2.h |
|
+++ b/lib/isc/include/isc/sha2.h |
|
@@ -84,6 +84,12 @@ |
|
typedef EVP_MD_CTX isc_sha256_t; |
|
typedef EVP_MD_CTX isc_sha512_t; |
|
|
|
+#elif PKCS11CRYPTO |
|
+#include <pk11/pk11.h> |
|
+ |
|
+typedef pk11_context_t isc_sha256_t; |
|
+typedef pk11_context_t isc_sha512_t; |
|
+ |
|
#else |
|
|
|
/* |
|
diff --git a/lib/isc/include/pk11/Makefile.in b/lib/isc/include/pk11/Makefile.in |
|
new file mode 100644 |
|
index 0000000..744c40e |
|
--- /dev/null |
|
+++ b/lib/isc/include/pk11/Makefile.in |
|
@@ -0,0 +1,38 @@ |
|
+# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") |
|
+# |
|
+# Permission to use, copy, modify, and/or distribute this software for any |
|
+# purpose with or without fee is hereby granted, provided that the above |
|
+# copyright notice and this permission notice appear in all copies. |
|
+# |
|
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+# PERFORMANCE OF THIS SOFTWARE. |
|
+ |
|
+srcdir = @srcdir@ |
|
+VPATH = @srcdir@ |
|
+top_srcdir = @top_srcdir@ |
|
+ |
|
+@BIND9_VERSION@ |
|
+ |
|
+# |
|
+# Only list headers that are to be installed and are not |
|
+# machine generated. The latter are handled specially in the |
|
+# install target below. |
|
+# |
|
+HEADERS = constants.h internal.h pk11.h result.h |
|
+SUBDIRS = |
|
+TARGETS = |
|
+ |
|
+@BIND9_MAKE_RULES@ |
|
+ |
|
+installdirs: |
|
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/pk11 |
|
+ |
|
+install:: installdirs |
|
+ for i in ${HEADERS}; do \ |
|
+ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/pk11 ; \ |
|
+ done |
|
diff --git a/lib/isc/include/pk11/constants.h b/lib/isc/include/pk11/constants.h |
|
new file mode 100644 |
|
index 0000000..e1e0581 |
|
--- /dev/null |
|
+++ b/lib/isc/include/pk11/constants.h |
|
@@ -0,0 +1,107 @@ |
|
+/* |
|
+ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+#ifndef PK11_CONSTANTS_H |
|
+#define PK11_CONSTANTS_H 1 |
|
+ |
|
+/*! \file pk11/constants.h */ |
|
+ |
|
+/*% |
|
+ * Static arrays of data used for key template initalization |
|
+ */ |
|
+#ifdef WANT_ECC_CURVES |
|
+static CK_BYTE pk11_ecc_prime256v1[] = { |
|
+ 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 |
|
+}; |
|
+static CK_BYTE pk11_ecc_secp384r1[] = { |
|
+ 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 |
|
+}; |
|
+#endif |
|
+ |
|
+#ifdef WANT_DH_PRIMES |
|
+static CK_BYTE pk11_dh_bn2[] = { 2 }; |
|
+static CK_BYTE pk11_dh_bn768[] = { |
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
|
+ 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, |
|
+ 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, |
|
+ 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, |
|
+ 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, |
|
+ 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, |
|
+ 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, |
|
+ 0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, |
|
+ 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, |
|
+ 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, |
|
+ 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x3a, 0x36, 0x20, |
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff |
|
+}; |
|
+static CK_BYTE pk11_dh_bn1024[] = { |
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
|
+ 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, |
|
+ 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, |
|
+ 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, |
|
+ 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, |
|
+ 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, |
|
+ 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, |
|
+ 0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, |
|
+ 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, |
|
+ 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, |
|
+ 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, |
|
+ 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed, |
|
+ 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, |
|
+ 0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6, |
|
+ 0x49, 0x28, 0x66, 0x51, 0xec, 0xe6, 0x53, 0x81, |
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff |
|
+}; |
|
+static CK_BYTE pk11_dh_bn1536[] = { |
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
|
+ 0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, |
|
+ 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, |
|
+ 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, |
|
+ 0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, |
|
+ 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, |
|
+ 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, |
|
+ 0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, |
|
+ 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, |
|
+ 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, |
|
+ 0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, |
|
+ 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed, |
|
+ 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, |
|
+ 0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6, |
|
+ 0x49, 0x28, 0x66, 0x51, 0xec, 0xe4, 0x5b, 0x3d, |
|
+ 0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05, |
|
+ 0x98, 0xda, 0x48, 0x36, 0x1c, 0x55, 0xd3, 0x9a, |
|
+ 0x69, 0x16, 0x3f, 0xa8, 0xfd, 0x24, 0xcf, 0x5f, |
|
+ 0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96, |
|
+ 0x1c, 0x62, 0xf3, 0x56, 0x20, 0x85, 0x52, 0xbb, |
|
+ 0x9e, 0xd5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6d, |
|
+ 0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04, |
|
+ 0xf1, 0x74, 0x6c, 0x08, 0xca, 0x23, 0x73, 0x27, |
|
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff |
|
+}; |
|
+#endif |
|
+ |
|
+#ifdef WANT_GOST_PARAMS |
|
+static CK_BYTE pk11_gost_a_paramset[] = { |
|
+ 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 |
|
+}; |
|
+static CK_BYTE pk11_gost_paramset[] = { |
|
+ 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 |
|
+}; |
|
+#endif |
|
+ |
|
+#endif /* PK11_CONSTANTS_H */ |
|
diff --git a/lib/isc/include/pk11/internal.h b/lib/isc/include/pk11/internal.h |
|
new file mode 100644 |
|
index 0000000..14bef3c |
|
--- /dev/null |
|
+++ b/lib/isc/include/pk11/internal.h |
|
@@ -0,0 +1,46 @@ |
|
+/* |
|
+ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+#ifndef PK11_INTERNAL_H |
|
+#define PK11_INTERNAL_H 1 |
|
+ |
|
+/*! \file pk11/internal.h */ |
|
+ |
|
+ISC_LANG_BEGINDECLS |
|
+ |
|
+const char *pk11_get_lib_name(void); |
|
+ |
|
+void *pk11_mem_get(size_t size); |
|
+ |
|
+void pk11_mem_put(void *ptr, size_t size); |
|
+ |
|
+CK_SLOT_ID pk11_get_best_token(pk11_optype_t optype); |
|
+ |
|
+unsigned int pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt); |
|
+ |
|
+CK_ATTRIBUTE *pk11_attribute_first(const pk11_object_t *obj); |
|
+ |
|
+CK_ATTRIBUTE *pk11_attribute_next(const pk11_object_t *obj, |
|
+ CK_ATTRIBUTE *attr); |
|
+ |
|
+CK_ATTRIBUTE *pk11_attribute_bytype(const pk11_object_t *obj, |
|
+ CK_ATTRIBUTE_TYPE type); |
|
+ |
|
+ISC_LANG_ENDDECLS |
|
+ |
|
+#endif /* PK11_INTERNAL_H */ |
|
diff --git a/lib/isc/include/pk11/pk11.h b/lib/isc/include/pk11/pk11.h |
|
new file mode 100644 |
|
index 0000000..964a2a7 |
|
--- /dev/null |
|
+++ b/lib/isc/include/pk11/pk11.h |
|
@@ -0,0 +1,295 @@ |
|
+/* |
|
+ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+#ifndef PK11_PK11_H |
|
+#define PK11_PK11_H 1 |
|
+ |
|
+/*! \file pk11/pk11.h */ |
|
+ |
|
+#include <isc/lang.h> |
|
+#include <isc/magic.h> |
|
+#include <isc/types.h> |
|
+ |
|
+#define PK11_FATALCHECK(func, args) \ |
|
+ ((void) (((rv = (func) args) == CKR_OK) || \ |
|
+ ((pk11_error_fatalcheck)(__FILE__, __LINE__, #func, rv), 0))) |
|
+ |
|
+#include <pkcs11/cryptoki.h> |
|
+ |
|
+ISC_LANG_BEGINDECLS |
|
+ |
|
+#define SES_MAGIC ISC_MAGIC('P','K','S','S') |
|
+#define TOK_MAGIC ISC_MAGIC('P','K','T','K') |
|
+ |
|
+#define VALID_SES(x) ISC_MAGIC_VALID(x, SES_MAGIC) |
|
+#define VALID_TOK(x) ISC_MAGIC_VALID(x, TOK_MAGIC) |
|
+ |
|
+typedef struct pk11_context pk11_context_t; |
|
+ |
|
+struct pk11_object { |
|
+ CK_OBJECT_HANDLE object; |
|
+ CK_SLOT_ID slot; |
|
+ CK_BBOOL ontoken; |
|
+ CK_BBOOL reqlogon; |
|
+ CK_BYTE attrcnt; |
|
+ CK_ATTRIBUTE *repr; |
|
+}; |
|
+ |
|
+struct pk11_context { |
|
+ void *handle; |
|
+ CK_SESSION_HANDLE session; |
|
+ CK_BBOOL ontoken; |
|
+ CK_OBJECT_HANDLE object; |
|
+#ifndef PKCS11CRYPTOWITHHMAC |
|
+ unsigned char *key; |
|
+#endif |
|
+}; |
|
+ |
|
+typedef struct pk11_object pk11_object_t; |
|
+ |
|
+typedef enum { |
|
+ OP_ANY = 0, |
|
+ OP_RAND = 1, |
|
+ OP_RSA = 2, |
|
+ OP_DSA = 3, |
|
+ OP_DH = 4, |
|
+ OP_DIGEST = 5, |
|
+ OP_EC = 6, |
|
+ OP_GOST = 7, |
|
+ OP_AES = 8, |
|
+ OP_MAX = 9 |
|
+} pk11_optype_t; |
|
+ |
|
+/*% |
|
+ * Function prototypes |
|
+ */ |
|
+ |
|
+void pk11_set_lib_name(const char *lib_name); |
|
+/*%< |
|
+ * Set the PKCS#11 provider (aka library) path/name. |
|
+ */ |
|
+ |
|
+isc_result_t pk11_initialize(isc_mem_t *mctx, const char *engine); |
|
+/*%< |
|
+ * Initialize PKCS#11 device |
|
+ * |
|
+ * mctx: memory context to attach to pk11_mctx. |
|
+ * engine: PKCS#11 provider (aka library) path/name. |
|
+ * |
|
+ * returns: |
|
+ * ISC_R_SUCCESS |
|
+ * PK11_R_NOPROVIDER: can't load the provider |
|
+ * PK11_R_INITFAILED: C_Initialize() failed |
|
+ * PK11_R_NORANDOMSERVICE: can't find required random service |
|
+ * PK11_R_NODIGESTSERVICE: can't find required digest service |
|
+ * PK11_R_NOAESSERVICE: can't find required AES service |
|
+ */ |
|
+ |
|
+isc_result_t pk11_get_session(pk11_context_t *ctx, |
|
+ pk11_optype_t optype, |
|
+ isc_boolean_t need_services, |
|
+ isc_boolean_t rw, |
|
+ isc_boolean_t logon, |
|
+ const char *pin, |
|
+ CK_SLOT_ID slot); |
|
+/*%< |
|
+ * Initialize PKCS#11 device and acquire a session. |
|
+ * |
|
+ * need_services: |
|
+ * if ISC_TRUE, this session requires full PKCS#11 API |
|
+ * support including random and digest services, and |
|
+ * the lack of these services will cause the session not |
|
+ * to be initialized. If ISC_FALSE, the function will return |
|
+ * an error code indicating the missing service, but the |
|
+ * session will be usable for other purposes. |
|
+ * rw: if ISC_TRUE, session will be read/write (useful for |
|
+ * generating or destroying keys); otherwise read-only. |
|
+ * login: indicates whether to log in to the device |
|
+ * pin: optional PIN, overriding any PIN currently associated |
|
+ * with the |
|
+ * slot: device slot ID |
|
+ */ |
|
+ |
|
+void pk11_return_session(pk11_context_t *ctx); |
|
+/*%< |
|
+ * Release an active PKCS#11 session for reuse. |
|
+ */ |
|
+ |
|
+isc_result_t pk11_finalize(void); |
|
+/*%< |
|
+ * Shut down PKCS#11 device and free all sessions. |
|
+ */ |
|
+ |
|
+isc_result_t pk11_rand_bytes(unsigned char *buf, int num); |
|
+ |
|
+void pk11_rand_seed_fromfile(const char *randomfile); |
|
+ |
|
+isc_result_t pk11_parse_uri(pk11_object_t *obj, const char *label, |
|
+ isc_mem_t *mctx, pk11_optype_t optype); |
|
+ |
|
+ISC_PLATFORM_NORETURN_PRE void |
|
+pk11_error_fatalcheck(const char *file, int line, |
|
+ const char *funcname, CK_RV rv) |
|
+ISC_PLATFORM_NORETURN_POST; |
|
+ |
|
+void pk11_dump_tokens(void); |
|
+ |
|
+CK_RV |
|
+pkcs_C_Initialize(CK_VOID_PTR pReserved); |
|
+ |
|
+CK_RV |
|
+pkcs_C_Finalize(CK_VOID_PTR pReserved); |
|
+ |
|
+CK_RV |
|
+pkcs_C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, |
|
+ CK_ULONG_PTR pulCount); |
|
+ |
|
+CK_RV |
|
+pkcs_C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo); |
|
+ |
|
+CK_RV |
|
+pkcs_C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, |
|
+ CK_MECHANISM_INFO_PTR pInfo); |
|
+ |
|
+CK_RV |
|
+pkcs_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, |
|
+ CK_VOID_PTR pApplication, |
|
+ CK_RV (*Notify) (CK_SESSION_HANDLE hSession, |
|
+ CK_NOTIFICATION event, |
|
+ CK_VOID_PTR pApplication), |
|
+ CK_SESSION_HANDLE_PTR phSession); |
|
+ |
|
+CK_RV |
|
+pkcs_C_CloseSession(CK_SESSION_HANDLE hSession); |
|
+ |
|
+CK_RV |
|
+pkcs_C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, |
|
+ CK_CHAR_PTR pPin, CK_ULONG usPinLen); |
|
+ |
|
+CK_RV |
|
+pkcs_C_Logout(CK_SESSION_HANDLE hSession); |
|
+ |
|
+CK_RV |
|
+pkcs_C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, |
|
+ CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject); |
|
+ |
|
+CK_RV |
|
+pkcs_C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject); |
|
+ |
|
+CK_RV |
|
+pkcs_C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, |
|
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); |
|
+ |
|
+CK_RV |
|
+pkcs_C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, |
|
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount); |
|
+ |
|
+CK_RV |
|
+pkcs_C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, |
|
+ CK_ULONG usCount); |
|
+ |
|
+CK_RV |
|
+pkcs_C_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, |
|
+ CK_ULONG usMaxObjectCount, CK_ULONG_PTR pusObjectCount); |
|
+ |
|
+CK_RV |
|
+pkcs_C_FindObjectsFinal(CK_SESSION_HANDLE hSession); |
|
+ |
|
+CK_RV |
|
+pkcs_C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
|
+ CK_OBJECT_HANDLE hKey); |
|
+ |
|
+CK_RV |
|
+pkcs_C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, |
|
+ CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, |
|
+ CK_ULONG_PTR pulEncryptedDataLen); |
|
+ |
|
+CK_RV |
|
+pkcs_C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism); |
|
+ |
|
+CK_RV |
|
+pkcs_C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, |
|
+ CK_ULONG ulPartLen); |
|
+ |
|
+CK_RV |
|
+pkcs_C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, |
|
+ CK_ULONG_PTR pulDigestLen); |
|
+ |
|
+CK_RV |
|
+pkcs_C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
|
+ CK_OBJECT_HANDLE hKey); |
|
+ |
|
+CK_RV |
|
+pkcs_C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, |
|
+ CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, |
|
+ CK_ULONG_PTR pulSignatureLen); |
|
+ |
|
+CK_RV |
|
+pkcs_C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, |
|
+ CK_ULONG ulPartLen); |
|
+ |
|
+CK_RV |
|
+pkcs_C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, |
|
+ CK_ULONG_PTR pulSignatureLen); |
|
+ |
|
+CK_RV |
|
+pkcs_C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
|
+ CK_OBJECT_HANDLE hKey); |
|
+ |
|
+CK_RV |
|
+pkcs_C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, |
|
+ CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, |
|
+ CK_ULONG ulSignatureLen); |
|
+ |
|
+CK_RV |
|
+pkcs_C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, |
|
+ CK_ULONG ulPartLen); |
|
+ |
|
+CK_RV |
|
+pkcs_C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, |
|
+ CK_ULONG ulSignatureLen); |
|
+ |
|
+CK_RV |
|
+pkcs_C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
|
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, |
|
+ CK_OBJECT_HANDLE_PTR phKey); |
|
+ |
|
+CK_RV |
|
+pkcs_C_GenerateKeyPair(CK_SESSION_HANDLE hSession, |
|
+ CK_MECHANISM_PTR pMechanism, |
|
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, |
|
+ CK_ULONG usPublicKeyAttributeCount, |
|
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, |
|
+ CK_ULONG usPrivateKeyAttributeCount, |
|
+ CK_OBJECT_HANDLE_PTR phPrivateKey, |
|
+ CK_OBJECT_HANDLE_PTR phPublicKey); |
|
+ |
|
+CK_RV |
|
+pkcs_C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
|
+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, |
|
+ CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey); |
|
+ |
|
+CK_RV |
|
+pkcs_C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, |
|
+ CK_ULONG ulSeedLen); |
|
+ |
|
+CK_RV |
|
+pkcs_C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, |
|
+ CK_ULONG ulRandomLen); |
|
+ |
|
+ISC_LANG_ENDDECLS |
|
+ |
|
+#endif /* PK11_PK11_H */ |
|
diff --git a/lib/isc/include/pk11/result.h b/lib/isc/include/pk11/result.h |
|
new file mode 100644 |
|
index 0000000..f624140 |
|
--- /dev/null |
|
+++ b/lib/isc/include/pk11/result.h |
|
@@ -0,0 +1,56 @@ |
|
+/* |
|
+ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+#ifndef PK11_RESULT_H |
|
+#define PK11_RESULT_H 1 |
|
+ |
|
+/*! \file pk11/result.h */ |
|
+ |
|
+#include <isc/lang.h> |
|
+#include <isc/resultclass.h> |
|
+ |
|
+/* |
|
+ * Nothing in this file truly depends on <isc/result.h>, but the |
|
+ * PK11 result codes are considered to be publicly derived from |
|
+ * the ISC result codes, so including this file buys you the ISC_R_ |
|
+ * namespace too. |
|
+ */ |
|
+#include <isc/result.h> /* Contractual promise. */ |
|
+ |
|
+#define PK11_R_INITFAILED (ISC_RESULTCLASS_PK11 + 0) |
|
+#define PK11_R_NOPROVIDER (ISC_RESULTCLASS_PK11 + 1) |
|
+#define PK11_R_NORANDOMSERVICE (ISC_RESULTCLASS_PK11 + 2) |
|
+#define PK11_R_NODIGESTSERVICE (ISC_RESULTCLASS_PK11 + 3) |
|
+#define PK11_R_NOAESSERVICE (ISC_RESULTCLASS_PK11 + 4) |
|
+ |
|
+#define PK11_R_NRESULTS 5 /* Number of results */ |
|
+ |
|
+ISC_LANG_BEGINDECLS |
|
+ |
|
+LIBISC_EXTERNAL_DATA extern isc_msgcat_t *pk11_msgcat; |
|
+ |
|
+void |
|
+pk11_initmsgcat(void); |
|
+ |
|
+const char * |
|
+pk11_result_totext(isc_result_t); |
|
+ |
|
+void |
|
+pk11_result_register(void); |
|
+ |
|
+ISC_LANG_ENDDECLS |
|
+ |
|
+#endif /* PK11_RESULT_H */ |
|
diff --git a/lib/isc/include/pkcs11/Makefile.in b/lib/isc/include/pkcs11/Makefile.in |
|
new file mode 100644 |
|
index 0000000..6e98688 |
|
--- /dev/null |
|
+++ b/lib/isc/include/pkcs11/Makefile.in |
|
@@ -0,0 +1,40 @@ |
|
+# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") |
|
+# |
|
+# Permission to use, copy, modify, and/or distribute this software for any |
|
+# purpose with or without fee is hereby granted, provided that the above |
|
+# copyright notice and this permission notice appear in all copies. |
|
+# |
|
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+# PERFORMANCE OF THIS SOFTWARE. |
|
+ |
|
+# $Id: Makefile.in,v 1.7 2007/06/19 23:47:22 tbox Exp $ |
|
+ |
|
+srcdir = @srcdir@ |
|
+VPATH = @srcdir@ |
|
+top_srcdir = @top_srcdir@ |
|
+ |
|
+@BIND9_VERSION@ |
|
+ |
|
+# |
|
+# Only list headers that are to be installed and are not |
|
+# machine generated. The latter are handled specially in the |
|
+# install target below. |
|
+# |
|
+HEADERS = pkcs11f.h pkcs11.h pkcs11t.h |
|
+SUBDIRS = |
|
+TARGETS = |
|
+ |
|
+@BIND9_MAKE_RULES@ |
|
+ |
|
+installdirs: |
|
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/pkcs11 |
|
+ |
|
+install:: installdirs |
|
+ for i in ${HEADERS}; do \ |
|
+ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/pkcs11 ; \ |
|
+ done |
|
diff --git a/lib/isc/include/pkcs11/pkcs11.h b/lib/isc/include/pkcs11/pkcs11.h |
|
new file mode 100644 |
|
index 0000000..9261e1e |
|
--- /dev/null |
|
+++ b/lib/isc/include/pkcs11/pkcs11.h |
|
@@ -0,0 +1,299 @@ |
|
+/* pkcs11.h include file for PKCS #11. */ |
|
+/* $Revision: 1.2 $ */ |
|
+ |
|
+/* License to copy and use this software is granted provided that it is |
|
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface |
|
+ * (Cryptoki)" in all material mentioning or referencing this software. |
|
+ |
|
+ * License is also granted to make and use derivative works provided that |
|
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11 |
|
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or |
|
+ * referencing the derived work. |
|
+ |
|
+ * RSA Security Inc. makes no representations concerning either the |
|
+ * merchantability of this software or the suitability of this software for |
|
+ * any particular purpose. It is provided "as is" without express or implied |
|
+ * warranty of any kind. |
|
+ */ |
|
+ |
|
+#ifndef _PKCS11_H_ |
|
+#define _PKCS11_H_ 1 |
|
+ |
|
+#ifdef __cplusplus |
|
+extern "C" { |
|
+#endif |
|
+ |
|
+/* Before including this file (pkcs11.h) (or pkcs11t.h by |
|
+ * itself), 6 platform-specific macros must be defined. These |
|
+ * macros are described below, and typical definitions for them |
|
+ * are also given. Be advised that these definitions can depend |
|
+ * on both the platform and the compiler used (and possibly also |
|
+ * on whether a Cryptoki library is linked statically or |
|
+ * dynamically). |
|
+ * |
|
+ * In addition to defining these 6 macros, the packing convention |
|
+ * for Cryptoki structures should be set. The Cryptoki |
|
+ * convention on packing is that structures should be 1-byte |
|
+ * aligned. |
|
+ * |
|
+ * If you're using Microsoft Developer Studio 5.0 to produce |
|
+ * Win32 stuff, this might be done by using the following |
|
+ * preprocessor directive before including pkcs11.h or pkcs11t.h: |
|
+ * |
|
+ * #pragma pack(push, cryptoki, 1) |
|
+ * |
|
+ * and using the following preprocessor directive after including |
|
+ * pkcs11.h or pkcs11t.h: |
|
+ * |
|
+ * #pragma pack(pop, cryptoki) |
|
+ * |
|
+ * If you're using an earlier version of Microsoft Developer |
|
+ * Studio to produce Win16 stuff, this might be done by using |
|
+ * the following preprocessor directive before including |
|
+ * pkcs11.h or pkcs11t.h: |
|
+ * |
|
+ * #pragma pack(1) |
|
+ * |
|
+ * In a UNIX environment, you're on your own for this. You might |
|
+ * not need to do (or be able to do!) anything. |
|
+ * |
|
+ * |
|
+ * Now for the macros: |
|
+ * |
|
+ * |
|
+ * 1. CK_PTR: The indirection string for making a pointer to an |
|
+ * object. It can be used like this: |
|
+ * |
|
+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR; |
|
+ * |
|
+ * If you're using Microsoft Developer Studio 5.0 to produce |
|
+ * Win32 stuff, it might be defined by: |
|
+ * |
|
+ * #define CK_PTR * |
|
+ * |
|
+ * If you're using an earlier version of Microsoft Developer |
|
+ * Studio to produce Win16 stuff, it might be defined by: |
|
+ * |
|
+ * #define CK_PTR far * |
|
+ * |
|
+ * In a typical UNIX environment, it might be defined by: |
|
+ * |
|
+ * #define CK_PTR * |
|
+ * |
|
+ * |
|
+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes |
|
+ * an exportable Cryptoki library function definition out of a |
|
+ * return type and a function name. It should be used in the |
|
+ * following fashion to define the exposed Cryptoki functions in |
|
+ * a Cryptoki library: |
|
+ * |
|
+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)( |
|
+ * CK_VOID_PTR pReserved |
|
+ * ) |
|
+ * { |
|
+ * ... |
|
+ * } |
|
+ * |
|
+ * If you're using Microsoft Developer Studio 5.0 to define a |
|
+ * function in a Win32 Cryptoki .dll, it might be defined by: |
|
+ * |
|
+ * #define CK_DEFINE_FUNCTION(returnType, name) \ |
|
+ * returnType __declspec(dllexport) name |
|
+ * |
|
+ * If you're using an earlier version of Microsoft Developer |
|
+ * Studio to define a function in a Win16 Cryptoki .dll, it |
|
+ * might be defined by: |
|
+ * |
|
+ * #define CK_DEFINE_FUNCTION(returnType, name) \ |
|
+ * returnType __export _far _pascal name |
|
+ * |
|
+ * In a UNIX environment, it might be defined by: |
|
+ * |
|
+ * #define CK_DEFINE_FUNCTION(returnType, name) \ |
|
+ * returnType name |
|
+ * |
|
+ * |
|
+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes |
|
+ * an importable Cryptoki library function declaration out of a |
|
+ * return type and a function name. It should be used in the |
|
+ * following fashion: |
|
+ * |
|
+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)( |
|
+ * CK_VOID_PTR pReserved |
|
+ * ); |
|
+ * |
|
+ * If you're using Microsoft Developer Studio 5.0 to declare a |
|
+ * function in a Win32 Cryptoki .dll, it might be defined by: |
|
+ * |
|
+ * #define CK_DECLARE_FUNCTION(returnType, name) \ |
|
+ * returnType __declspec(dllimport) name |
|
+ * |
|
+ * If you're using an earlier version of Microsoft Developer |
|
+ * Studio to declare a function in a Win16 Cryptoki .dll, it |
|
+ * might be defined by: |
|
+ * |
|
+ * #define CK_DECLARE_FUNCTION(returnType, name) \ |
|
+ * returnType __export _far _pascal name |
|
+ * |
|
+ * In a UNIX environment, it might be defined by: |
|
+ * |
|
+ * #define CK_DECLARE_FUNCTION(returnType, name) \ |
|
+ * returnType name |
|
+ * |
|
+ * |
|
+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro |
|
+ * which makes a Cryptoki API function pointer declaration or |
|
+ * function pointer type declaration out of a return type and a |
|
+ * function name. It should be used in the following fashion: |
|
+ * |
|
+ * // Define funcPtr to be a pointer to a Cryptoki API function |
|
+ * // taking arguments args and returning CK_RV. |
|
+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args); |
|
+ * |
|
+ * or |
|
+ * |
|
+ * // Define funcPtrType to be the type of a pointer to a |
|
+ * // Cryptoki API function taking arguments args and returning |
|
+ * // CK_RV, and then define funcPtr to be a variable of type |
|
+ * // funcPtrType. |
|
+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args); |
|
+ * funcPtrType funcPtr; |
|
+ * |
|
+ * If you're using Microsoft Developer Studio 5.0 to access |
|
+ * functions in a Win32 Cryptoki .dll, in might be defined by: |
|
+ * |
|
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ |
|
+ * returnType __declspec(dllimport) (* name) |
|
+ * |
|
+ * If you're using an earlier version of Microsoft Developer |
|
+ * Studio to access functions in a Win16 Cryptoki .dll, it might |
|
+ * be defined by: |
|
+ * |
|
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ |
|
+ * returnType __export _far _pascal (* name) |
|
+ * |
|
+ * In a UNIX environment, it might be defined by: |
|
+ * |
|
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ |
|
+ * returnType (* name) |
|
+ * |
|
+ * |
|
+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes |
|
+ * a function pointer type for an application callback out of |
|
+ * a return type for the callback and a name for the callback. |
|
+ * It should be used in the following fashion: |
|
+ * |
|
+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args); |
|
+ * |
|
+ * to declare a function pointer, myCallback, to a callback |
|
+ * which takes arguments args and returns a CK_RV. It can also |
|
+ * be used like this: |
|
+ * |
|
+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args); |
|
+ * myCallbackType myCallback; |
|
+ * |
|
+ * If you're using Microsoft Developer Studio 5.0 to do Win32 |
|
+ * Cryptoki development, it might be defined by: |
|
+ * |
|
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \ |
|
+ * returnType (* name) |
|
+ * |
|
+ * If you're using an earlier version of Microsoft Developer |
|
+ * Studio to do Win16 development, it might be defined by: |
|
+ * |
|
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \ |
|
+ * returnType _far _pascal (* name) |
|
+ * |
|
+ * In a UNIX environment, it might be defined by: |
|
+ * |
|
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \ |
|
+ * returnType (* name) |
|
+ * |
|
+ * |
|
+ * 6. NULL_PTR: This macro is the value of a NULL pointer. |
|
+ * |
|
+ * In any ANSI/ISO C environment (and in many others as well), |
|
+ * this should best be defined by |
|
+ * |
|
+ * #ifndef NULL_PTR |
|
+ * #define NULL_PTR 0 |
|
+ * #endif |
|
+ */ |
|
+ |
|
+ |
|
+/* All the various Cryptoki types and #define'd values are in the |
|
+ * file pkcs11t.h. */ |
|
+#include "pkcs11t.h" |
|
+ |
|
+#define __PASTE(x,y) x##y |
|
+ |
|
+ |
|
+/* ============================================================== |
|
+ * Define the "extern" form of all the entry points. |
|
+ * ============================================================== |
|
+ */ |
|
+ |
|
+#define CK_NEED_ARG_LIST 1 |
|
+#define CK_PKCS11_FUNCTION_INFO(name) \ |
|
+ extern CK_DECLARE_FUNCTION(CK_RV, name) |
|
+ |
|
+/* pkcs11f.h has all the information about the Cryptoki |
|
+ * function prototypes. */ |
|
+#include "pkcs11f.h" |
|
+ |
|
+#undef CK_NEED_ARG_LIST |
|
+#undef CK_PKCS11_FUNCTION_INFO |
|
+ |
|
+ |
|
+/* ============================================================== |
|
+ * Define the typedef form of all the entry points. That is, for |
|
+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is |
|
+ * a pointer to that kind of function. |
|
+ * ============================================================== |
|
+ */ |
|
+ |
|
+#define CK_NEED_ARG_LIST 1 |
|
+#define CK_PKCS11_FUNCTION_INFO(name) \ |
|
+ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name)) |
|
+ |
|
+/* pkcs11f.h has all the information about the Cryptoki |
|
+ * function prototypes. */ |
|
+#include "pkcs11f.h" |
|
+ |
|
+#undef CK_NEED_ARG_LIST |
|
+#undef CK_PKCS11_FUNCTION_INFO |
|
+ |
|
+ |
|
+/* ============================================================== |
|
+ * Define structed vector of entry points. A CK_FUNCTION_LIST |
|
+ * contains a CK_VERSION indicating a library's Cryptoki version |
|
+ * and then a whole slew of function pointers to the routines in |
|
+ * the library. This type was declared, but not defined, in |
|
+ * pkcs11t.h. |
|
+ * ============================================================== |
|
+ */ |
|
+ |
|
+#define CK_PKCS11_FUNCTION_INFO(name) \ |
|
+ __PASTE(CK_,name) name; |
|
+ |
|
+struct CK_FUNCTION_LIST { |
|
+ |
|
+ CK_VERSION version; /* Cryptoki version */ |
|
+ |
|
+/* Pile all the function pointers into the CK_FUNCTION_LIST. */ |
|
+/* pkcs11f.h has all the information about the Cryptoki |
|
+ * function prototypes. */ |
|
+#include "pkcs11f.h" |
|
+ |
|
+}; |
|
+ |
|
+#undef CK_PKCS11_FUNCTION_INFO |
|
+ |
|
+ |
|
+#undef __PASTE |
|
+ |
|
+#ifdef __cplusplus |
|
+} |
|
+#endif |
|
+ |
|
+#endif |
|
diff --git a/lib/isc/include/pkcs11/pkcs11f.h b/lib/isc/include/pkcs11/pkcs11f.h |
|
new file mode 100644 |
|
index 0000000..dec6315 |
|
--- /dev/null |
|
+++ b/lib/isc/include/pkcs11/pkcs11f.h |
|
@@ -0,0 +1,912 @@ |
|
+/* pkcs11f.h include file for PKCS #11. */ |
|
+/* $Revision: 1.2 $ */ |
|
+ |
|
+/* License to copy and use this software is granted provided that it is |
|
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface |
|
+ * (Cryptoki)" in all material mentioning or referencing this software. |
|
+ |
|
+ * License is also granted to make and use derivative works provided that |
|
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11 |
|
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or |
|
+ * referencing the derived work. |
|
+ |
|
+ * RSA Security Inc. makes no representations concerning either the |
|
+ * merchantability of this software or the suitability of this software for |
|
+ * any particular purpose. It is provided "as is" without express or implied |
|
+ * warranty of any kind. |
|
+ */ |
|
+ |
|
+/* This header file contains pretty much everything about all the */ |
|
+/* Cryptoki function prototypes. Because this information is */ |
|
+/* used for more than just declaring function prototypes, the */ |
|
+/* order of the functions appearing herein is important, and */ |
|
+/* should not be altered. */ |
|
+ |
|
+/* General-purpose */ |
|
+ |
|
+/* C_Initialize initializes the Cryptoki library. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_Initialize) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets |
|
+ * cast to CK_C_INITIALIZE_ARGS_PTR |
|
+ * and dereferenced */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_Finalize indicates that an application is done with the |
|
+ * Cryptoki library. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_Finalize) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_GetInfo returns general information about Cryptoki. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GetInfo) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_INFO_PTR pInfo /* location that receives information */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_GetFunctionList returns the function list. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to |
|
+ * function list */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+ |
|
+/* Slot and token management */ |
|
+ |
|
+/* C_GetSlotList obtains a list of slots in the system. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GetSlotList) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_BBOOL tokenPresent, /* only slots with tokens? */ |
|
+ CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */ |
|
+ CK_ULONG_PTR pulCount /* receives number of slots */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_GetSlotInfo obtains information about a particular slot in |
|
+ * the system. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SLOT_ID slotID, /* the ID of the slot */ |
|
+ CK_SLOT_INFO_PTR pInfo /* receives the slot information */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_GetTokenInfo obtains information about a particular token |
|
+ * in the system. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SLOT_ID slotID, /* ID of the token's slot */ |
|
+ CK_TOKEN_INFO_PTR pInfo /* receives the token information */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_GetMechanismList obtains a list of mechanism types |
|
+ * supported by a token. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SLOT_ID slotID, /* ID of token's slot */ |
|
+ CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */ |
|
+ CK_ULONG_PTR pulCount /* gets # of mechs. */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_GetMechanismInfo obtains information about a particular |
|
+ * mechanism possibly supported by a token. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SLOT_ID slotID, /* ID of the token's slot */ |
|
+ CK_MECHANISM_TYPE type, /* type of mechanism */ |
|
+ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_InitToken initializes a token. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_InitToken) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */ |
|
+( |
|
+ CK_SLOT_ID slotID, /* ID of the token's slot */ |
|
+ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */ |
|
+ CK_ULONG ulPinLen, /* length in bytes of the PIN */ |
|
+ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_InitPIN initializes the normal user's PIN. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_InitPIN) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */ |
|
+ CK_ULONG ulPinLen /* length in bytes of the PIN */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_SetPIN modifies the PIN of the user who is logged in. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_SetPIN) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */ |
|
+ CK_ULONG ulOldLen, /* length of the old PIN */ |
|
+ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */ |
|
+ CK_ULONG ulNewLen /* length of the new PIN */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+ |
|
+/* Session management */ |
|
+ |
|
+/* C_OpenSession opens a session between an application and a |
|
+ * token. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_OpenSession) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SLOT_ID slotID, /* the slot's ID */ |
|
+ CK_FLAGS flags, /* from CK_SESSION_INFO */ |
|
+ CK_VOID_PTR pApplication, /* passed to callback */ |
|
+ CK_NOTIFY Notify, /* callback function */ |
|
+ CK_SESSION_HANDLE_PTR phSession /* gets session handle */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_CloseSession closes a session between an application and a |
|
+ * token. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_CloseSession) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession /* the session's handle */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_CloseAllSessions closes all sessions with a token. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SLOT_ID slotID /* the token's slot */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_GetSessionInfo obtains information about the session. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_SESSION_INFO_PTR pInfo /* receives session info */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_GetOperationState obtains the state of the cryptographic operation |
|
+ * in a session. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GetOperationState) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_BYTE_PTR pOperationState, /* gets state */ |
|
+ CK_ULONG_PTR pulOperationStateLen /* gets state length */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_SetOperationState restores the state of the cryptographic |
|
+ * operation in a session. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_SetOperationState) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_BYTE_PTR pOperationState, /* holds state */ |
|
+ CK_ULONG ulOperationStateLen, /* holds state length */ |
|
+ CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */ |
|
+ CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_Login logs a user into a token. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_Login) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_USER_TYPE userType, /* the user type */ |
|
+ CK_UTF8CHAR_PTR pPin, /* the user's PIN */ |
|
+ CK_ULONG ulPinLen /* the length of the PIN */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_Logout logs a user out from a token. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_Logout) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession /* the session's handle */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+ |
|
+/* Object management */ |
|
+ |
|
+/* C_CreateObject creates a new object. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_CreateObject) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ |
|
+ CK_ULONG ulCount, /* attributes in template */ |
|
+ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_CopyObject copies an object, creating a new object for the |
|
+ * copy. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_CopyObject) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_OBJECT_HANDLE hObject, /* the object's handle */ |
|
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */ |
|
+ CK_ULONG ulCount, /* attributes in template */ |
|
+ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_DestroyObject destroys an object. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_DestroyObject) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_OBJECT_HANDLE hObject /* the object's handle */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_GetObjectSize gets the size of an object in bytes. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_OBJECT_HANDLE hObject, /* the object's handle */ |
|
+ CK_ULONG_PTR pulSize /* receives size of object */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_GetAttributeValue obtains the value of one or more object |
|
+ * attributes. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_OBJECT_HANDLE hObject, /* the object's handle */ |
|
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */ |
|
+ CK_ULONG ulCount /* attributes in template */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_SetAttributeValue modifies the value of one or more object |
|
+ * attributes */ |
|
+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_OBJECT_HANDLE hObject, /* the object's handle */ |
|
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */ |
|
+ CK_ULONG ulCount /* attributes in template */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_FindObjectsInit initializes a search for token and session |
|
+ * objects that match a template. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */ |
|
+ CK_ULONG ulCount /* attrs in search template */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_FindObjects continues a search for token and session |
|
+ * objects that match a template, obtaining additional object |
|
+ * handles. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_FindObjects) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */ |
|
+ CK_ULONG ulMaxObjectCount, /* max handles to get */ |
|
+ CK_ULONG_PTR pulObjectCount /* actual # returned */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_FindObjectsFinal finishes a search for token and session |
|
+ * objects. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession /* the session's handle */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+ |
|
+/* Encryption and decryption */ |
|
+ |
|
+/* C_EncryptInit initializes an encryption operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_EncryptInit) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */ |
|
+ CK_OBJECT_HANDLE hKey /* handle of encryption key */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_Encrypt encrypts single-part data. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_Encrypt) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_BYTE_PTR pData, /* the plaintext data */ |
|
+ CK_ULONG ulDataLen, /* bytes of plaintext */ |
|
+ CK_BYTE_PTR pEncryptedData, /* gets ciphertext */ |
|
+ CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_EncryptUpdate continues a multiple-part encryption |
|
+ * operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_BYTE_PTR pPart, /* the plaintext data */ |
|
+ CK_ULONG ulPartLen, /* plaintext data len */ |
|
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ |
|
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_EncryptFinal finishes a multiple-part encryption |
|
+ * operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session handle */ |
|
+ CK_BYTE_PTR pLastEncryptedPart, /* last c-text */ |
|
+ CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_DecryptInit initializes a decryption operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_DecryptInit) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */ |
|
+ CK_OBJECT_HANDLE hKey /* handle of decryption key */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_Decrypt decrypts encrypted data in a single part. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_Decrypt) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_BYTE_PTR pEncryptedData, /* ciphertext */ |
|
+ CK_ULONG ulEncryptedDataLen, /* ciphertext length */ |
|
+ CK_BYTE_PTR pData, /* gets plaintext */ |
|
+ CK_ULONG_PTR pulDataLen /* gets p-text size */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_DecryptUpdate continues a multiple-part decryption |
|
+ * operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_BYTE_PTR pEncryptedPart, /* encrypted data */ |
|
+ CK_ULONG ulEncryptedPartLen, /* input length */ |
|
+ CK_BYTE_PTR pPart, /* gets plaintext */ |
|
+ CK_ULONG_PTR pulPartLen /* p-text size */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_DecryptFinal finishes a multiple-part decryption |
|
+ * operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pLastPart, /* gets plaintext */ |
|
+ CK_ULONG_PTR pulLastPartLen /* p-text size */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+ |
|
+/* Message digesting */ |
|
+ |
|
+/* C_DigestInit initializes a message-digesting operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_DigestInit) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_Digest digests data in a single part. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_Digest) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pData, /* data to be digested */ |
|
+ CK_ULONG ulDataLen, /* bytes of data to digest */ |
|
+ CK_BYTE_PTR pDigest, /* gets the message digest */ |
|
+ CK_ULONG_PTR pulDigestLen /* gets digest length */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_DigestUpdate continues a multiple-part message-digesting |
|
+ * operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pPart, /* data to be digested */ |
|
+ CK_ULONG ulPartLen /* bytes of data to be digested */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_DigestKey continues a multi-part message-digesting |
|
+ * operation, by digesting the value of a secret key as part of |
|
+ * the data already digested. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_DigestKey) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_OBJECT_HANDLE hKey /* secret key to digest */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_DigestFinal finishes a multiple-part message-digesting |
|
+ * operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_DigestFinal) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pDigest, /* gets the message digest */ |
|
+ CK_ULONG_PTR pulDigestLen /* gets byte count of digest */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+ |
|
+/* Signing and MACing */ |
|
+ |
|
+/* C_SignInit initializes a signature (private key encryption) |
|
+ * operation, where the signature is (will be) an appendix to |
|
+ * the data, and plaintext cannot be recovered from the |
|
+ *signature. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_SignInit) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ |
|
+ CK_OBJECT_HANDLE hKey /* handle of signature key */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_Sign signs (encrypts with private key) data in a single |
|
+ * part, where the signature is (will be) an appendix to the |
|
+ * data, and plaintext cannot be recovered from the signature. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_Sign) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pData, /* the data to sign */ |
|
+ CK_ULONG ulDataLen, /* count of bytes to sign */ |
|
+ CK_BYTE_PTR pSignature, /* gets the signature */ |
|
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_SignUpdate continues a multiple-part signature operation, |
|
+ * where the signature is (will be) an appendix to the data, |
|
+ * and plaintext cannot be recovered from the signature. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_SignUpdate) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pPart, /* the data to sign */ |
|
+ CK_ULONG ulPartLen /* count of bytes to sign */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_SignFinal finishes a multiple-part signature operation, |
|
+ * returning the signature. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_SignFinal) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pSignature, /* gets the signature */ |
|
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_SignRecoverInit initializes a signature operation, where |
|
+ * the data can be recovered from the signature. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */ |
|
+ CK_OBJECT_HANDLE hKey /* handle of the signature key */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_SignRecover signs data in a single operation, where the |
|
+ * data can be recovered from the signature. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_SignRecover) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pData, /* the data to sign */ |
|
+ CK_ULONG ulDataLen, /* count of bytes to sign */ |
|
+ CK_BYTE_PTR pSignature, /* gets the signature */ |
|
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+ |
|
+/* Verifying signatures and MACs */ |
|
+ |
|
+/* C_VerifyInit initializes a verification operation, where the |
|
+ * signature is an appendix to the data, and plaintext cannot |
|
+ * cannot be recovered from the signature (e.g. DSA). */ |
|
+CK_PKCS11_FUNCTION_INFO(C_VerifyInit) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ |
|
+ CK_OBJECT_HANDLE hKey /* verification key */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_Verify verifies a signature in a single-part operation, |
|
+ * where the signature is an appendix to the data, and plaintext |
|
+ * cannot be recovered from the signature. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_Verify) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pData, /* signed data */ |
|
+ CK_ULONG ulDataLen, /* length of signed data */ |
|
+ CK_BYTE_PTR pSignature, /* signature */ |
|
+ CK_ULONG ulSignatureLen /* signature length*/ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_VerifyUpdate continues a multiple-part verification |
|
+ * operation, where the signature is an appendix to the data, |
|
+ * and plaintext cannot be recovered from the signature. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pPart, /* signed data */ |
|
+ CK_ULONG ulPartLen /* length of signed data */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_VerifyFinal finishes a multiple-part verification |
|
+ * operation, checking the signature. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pSignature, /* signature to verify */ |
|
+ CK_ULONG ulSignatureLen /* signature length */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_VerifyRecoverInit initializes a signature verification |
|
+ * operation, where the data is recovered from the signature. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */ |
|
+ CK_OBJECT_HANDLE hKey /* verification key */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_VerifyRecover verifies a signature in a single-part |
|
+ * operation, where the data is recovered from the signature. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pSignature, /* signature to verify */ |
|
+ CK_ULONG ulSignatureLen, /* signature length */ |
|
+ CK_BYTE_PTR pData, /* gets signed data */ |
|
+ CK_ULONG_PTR pulDataLen /* gets signed data len */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+ |
|
+/* Dual-function cryptographic operations */ |
|
+ |
|
+/* C_DigestEncryptUpdate continues a multiple-part digesting |
|
+ * and encryption operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_BYTE_PTR pPart, /* the plaintext data */ |
|
+ CK_ULONG ulPartLen, /* plaintext length */ |
|
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ |
|
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_DecryptDigestUpdate continues a multiple-part decryption and |
|
+ * digesting operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */ |
|
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */ |
|
+ CK_BYTE_PTR pPart, /* gets plaintext */ |
|
+ CK_ULONG_PTR pulPartLen /* gets plaintext len */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_SignEncryptUpdate continues a multiple-part signing and |
|
+ * encryption operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_BYTE_PTR pPart, /* the plaintext data */ |
|
+ CK_ULONG ulPartLen, /* plaintext length */ |
|
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */ |
|
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_DecryptVerifyUpdate continues a multiple-part decryption and |
|
+ * verify operation. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */ |
|
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */ |
|
+ CK_BYTE_PTR pPart, /* gets plaintext */ |
|
+ CK_ULONG_PTR pulPartLen /* gets p-text length */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+ |
|
+/* Key management */ |
|
+ |
|
+/* C_GenerateKey generates a secret key, creating a new key |
|
+ * object. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GenerateKey) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_MECHANISM_PTR pMechanism, /* key generation mech. */ |
|
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new key */ |
|
+ CK_ULONG ulCount, /* # of attrs in template */ |
|
+ CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_GenerateKeyPair generates a public-key/private-key pair, |
|
+ * creating new key objects. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session |
|
+ * handle */ |
|
+ CK_MECHANISM_PTR pMechanism, /* key-gen |
|
+ * mech. */ |
|
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template |
|
+ * for pub. |
|
+ * key */ |
|
+ CK_ULONG ulPublicKeyAttributeCount, /* # pub. |
|
+ * attrs. */ |
|
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template |
|
+ * for priv. |
|
+ * key */ |
|
+ CK_ULONG ulPrivateKeyAttributeCount, /* # priv. |
|
+ * attrs. */ |
|
+ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub. |
|
+ * key |
|
+ * handle */ |
|
+ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets |
|
+ * priv. key |
|
+ * handle */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_WrapKey wraps (i.e., encrypts) a key. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_WrapKey) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */ |
|
+ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */ |
|
+ CK_OBJECT_HANDLE hKey, /* key to be wrapped */ |
|
+ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */ |
|
+ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new |
|
+ * key object. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */ |
|
+ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */ |
|
+ CK_BYTE_PTR pWrappedKey, /* the wrapped key */ |
|
+ CK_ULONG ulWrappedKeyLen, /* wrapped key len */ |
|
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */ |
|
+ CK_ULONG ulAttributeCount, /* template length */ |
|
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_DeriveKey derives a key from a base key, creating a new key |
|
+ * object. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_DeriveKey) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* session's handle */ |
|
+ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */ |
|
+ CK_OBJECT_HANDLE hBaseKey, /* base key */ |
|
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */ |
|
+ CK_ULONG ulAttributeCount, /* template length */ |
|
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+ |
|
+/* Random number generation */ |
|
+ |
|
+/* C_SeedRandom mixes additional seed material into the token's |
|
+ * random number generator. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_SeedRandom) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR pSeed, /* the seed material */ |
|
+ CK_ULONG ulSeedLen /* length of seed material */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_GenerateRandom generates random data. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_BYTE_PTR RandomData, /* receives the random data */ |
|
+ CK_ULONG ulRandomLen /* # of bytes to generate */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+ |
|
+/* Parallel function management */ |
|
+ |
|
+/* C_GetFunctionStatus is a legacy function; it obtains an |
|
+ * updated status of a function running in parallel with an |
|
+ * application. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession /* the session's handle */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+/* C_CancelFunction is a legacy function; it cancels a function |
|
+ * running in parallel. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_CancelFunction) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_SESSION_HANDLE hSession /* the session's handle */ |
|
+); |
|
+#endif |
|
+ |
|
+ |
|
+ |
|
+/* Functions added in for Cryptoki Version 2.01 or later */ |
|
+ |
|
+/* C_WaitForSlotEvent waits for a slot event (token insertion, |
|
+ * removal, etc.) to occur. */ |
|
+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent) |
|
+#ifdef CK_NEED_ARG_LIST |
|
+( |
|
+ CK_FLAGS flags, /* blocking/nonblocking flag */ |
|
+ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */ |
|
+ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */ |
|
+); |
|
+#endif |
|
diff --git a/lib/isc/include/pkcs11/pkcs11t.h b/lib/isc/include/pkcs11/pkcs11t.h |
|
new file mode 100644 |
|
index 0000000..92a80bb |
|
--- /dev/null |
|
+++ b/lib/isc/include/pkcs11/pkcs11t.h |
|
@@ -0,0 +1,1977 @@ |
|
+/* pkcs11t.h include file for PKCS #11. */ |
|
+/* $Revision: 1.2 $ */ |
|
+ |
|
+/* License to copy and use this software is granted provided that it is |
|
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface |
|
+ * (Cryptoki)" in all material mentioning or referencing this software. |
|
+ |
|
+ * License is also granted to make and use derivative works provided that |
|
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11 |
|
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or |
|
+ * referencing the derived work. |
|
+ |
|
+ * RSA Security Inc. makes no representations concerning either the |
|
+ * merchantability of this software or the suitability of this software for |
|
+ * any particular purpose. It is provided "as is" without express or implied |
|
+ * warranty of any kind. |
|
+ */ |
|
+ |
|
+/* See top of pkcs11.h for information about the macros that |
|
+ * must be defined and the structure-packing conventions that |
|
+ * must be set before including this file. */ |
|
+ |
|
+#ifndef _PKCS11T_H_ |
|
+#define _PKCS11T_H_ 1 |
|
+ |
|
+#define CRYPTOKI_VERSION_MAJOR 2 |
|
+#define CRYPTOKI_VERSION_MINOR 30 |
|
+#define CRYPTOKI_VERSION_REVISION 0 |
|
+#define CRYPTOKI_VERSION_AMENDMENT 0 |
|
+ |
|
+#define CK_TRUE 1 |
|
+#define CK_FALSE 0 |
|
+ |
|
+#ifndef CK_DISABLE_TRUE_FALSE |
|
+#ifndef FALSE |
|
+#define FALSE CK_FALSE |
|
+#endif |
|
+ |
|
+#ifndef TRUE |
|
+#define TRUE CK_TRUE |
|
+#endif |
|
+#endif |
|
+ |
|
+/* an unsigned 8-bit value */ |
|
+typedef unsigned char CK_BYTE; |
|
+ |
|
+/* an unsigned 8-bit character */ |
|
+typedef CK_BYTE CK_CHAR; |
|
+ |
|
+/* an 8-bit UTF-8 character */ |
|
+typedef CK_BYTE CK_UTF8CHAR; |
|
+ |
|
+/* a BYTE-sized Boolean flag */ |
|
+typedef CK_BYTE CK_BBOOL; |
|
+ |
|
+/* an unsigned value, at least 32 bits long */ |
|
+typedef unsigned long int CK_ULONG; |
|
+ |
|
+/* a signed value, the same size as a CK_ULONG */ |
|
+/* CK_LONG is new for v2.0 */ |
|
+typedef long int CK_LONG; |
|
+ |
|
+/* at least 32 bits; each bit is a Boolean flag */ |
|
+typedef CK_ULONG CK_FLAGS; |
|
+ |
|
+ |
|
+/* some special values for certain CK_ULONG variables */ |
|
+#define CK_UNAVAILABLE_INFORMATION (~0UL) |
|
+#define CK_EFFECTIVELY_INFINITE 0 |
|
+ |
|
+ |
|
+typedef CK_BYTE CK_PTR CK_BYTE_PTR; |
|
+typedef CK_CHAR CK_PTR CK_CHAR_PTR; |
|
+typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR; |
|
+typedef CK_ULONG CK_PTR CK_ULONG_PTR; |
|
+typedef void CK_PTR CK_VOID_PTR; |
|
+ |
|
+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */ |
|
+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR; |
|
+ |
|
+ |
|
+/* The following value is always invalid if used as a session */ |
|
+/* handle or object handle */ |
|
+#define CK_INVALID_HANDLE 0 |
|
+ |
|
+ |
|
+typedef struct CK_VERSION { |
|
+ CK_BYTE major; /* integer portion of version number */ |
|
+ CK_BYTE minor; /* 1/100ths portion of version number */ |
|
+} CK_VERSION; |
|
+ |
|
+typedef CK_VERSION CK_PTR CK_VERSION_PTR; |
|
+ |
|
+ |
|
+typedef struct CK_INFO { |
|
+ /* manufacturerID and libraryDecription have been changed from |
|
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */ |
|
+ CK_VERSION cryptokiVersion; /* Cryptoki interface ver */ |
|
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */ |
|
+ CK_FLAGS flags; /* must be zero */ |
|
+ |
|
+ /* libraryDescription and libraryVersion are new for v2.0 */ |
|
+ CK_UTF8CHAR libraryDescription[32]; /* blank padded */ |
|
+ CK_VERSION libraryVersion; /* version of library */ |
|
+} CK_INFO; |
|
+ |
|
+typedef CK_INFO CK_PTR CK_INFO_PTR; |
|
+ |
|
+ |
|
+/* CK_NOTIFICATION enumerates the types of notifications that |
|
+ * Cryptoki provides to an application */ |
|
+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG |
|
+ * for v2.0 */ |
|
+typedef CK_ULONG CK_NOTIFICATION; |
|
+#define CKN_SURRENDER 0 |
|
+ |
|
+/* The following notification is new for PKCS #11 v2.20 amendment 3 */ |
|
+#define CKN_OTP_CHANGED 1 |
|
+ |
|
+ |
|
+typedef CK_ULONG CK_SLOT_ID; |
|
+ |
|
+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR; |
|
+ |
|
+ |
|
+/* CK_SLOT_INFO provides information about a slot */ |
|
+typedef struct CK_SLOT_INFO { |
|
+ /* slotDescription and manufacturerID have been changed from |
|
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */ |
|
+ CK_UTF8CHAR slotDescription[64]; /* blank padded */ |
|
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */ |
|
+ CK_FLAGS flags; |
|
+ |
|
+ /* hardwareVersion and firmwareVersion are new for v2.0 */ |
|
+ CK_VERSION hardwareVersion; /* version of hardware */ |
|
+ CK_VERSION firmwareVersion; /* version of firmware */ |
|
+} CK_SLOT_INFO; |
|
+ |
|
+/* flags: bit flags that provide capabilities of the slot |
|
+ * Bit Flag Mask Meaning |
|
+ */ |
|
+#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */ |
|
+#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/ |
|
+#define CKF_HW_SLOT 0x00000004 /* hardware slot */ |
|
+ |
|
+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR; |
|
+ |
|
+ |
|
+/* CK_TOKEN_INFO provides information about a token */ |
|
+typedef struct CK_TOKEN_INFO { |
|
+ /* label, manufacturerID, and model have been changed from |
|
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */ |
|
+ CK_UTF8CHAR label[32]; /* blank padded */ |
|
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */ |
|
+ CK_UTF8CHAR model[16]; /* blank padded */ |
|
+ CK_CHAR serialNumber[16]; /* blank padded */ |
|
+ CK_FLAGS flags; /* see below */ |
|
+ |
|
+ /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount, |
|
+ * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been |
|
+ * changed from CK_USHORT to CK_ULONG for v2.0 */ |
|
+ CK_ULONG ulMaxSessionCount; /* max open sessions */ |
|
+ CK_ULONG ulSessionCount; /* sess. now open */ |
|
+ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */ |
|
+ CK_ULONG ulRwSessionCount; /* R/W sess. now open */ |
|
+ CK_ULONG ulMaxPinLen; /* in bytes */ |
|
+ CK_ULONG ulMinPinLen; /* in bytes */ |
|
+ CK_ULONG ulTotalPublicMemory; /* in bytes */ |
|
+ CK_ULONG ulFreePublicMemory; /* in bytes */ |
|
+ CK_ULONG ulTotalPrivateMemory; /* in bytes */ |
|
+ CK_ULONG ulFreePrivateMemory; /* in bytes */ |
|
+ |
|
+ /* hardwareVersion, firmwareVersion, and time are new for |
|
+ * v2.0 */ |
|
+ CK_VERSION hardwareVersion; /* version of hardware */ |
|
+ CK_VERSION firmwareVersion; /* version of firmware */ |
|
+ CK_CHAR utcTime[16]; /* time */ |
|
+} CK_TOKEN_INFO; |
|
+ |
|
+/* The flags parameter is defined as follows: |
|
+ * Bit Flag Mask Meaning |
|
+ */ |
|
+#define CKF_RNG 0x00000001 /* has random # |
|
+ * generator */ |
|
+#define CKF_WRITE_PROTECTED 0x00000002 /* token is |
|
+ * write- |
|
+ * protected */ |
|
+#define CKF_LOGIN_REQUIRED 0x00000004 /* user must |
|
+ * login */ |
|
+#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's |
|
+ * PIN is set */ |
|
+ |
|
+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set, |
|
+ * that means that *every* time the state of cryptographic |
|
+ * operations of a session is successfully saved, all keys |
|
+ * needed to continue those operations are stored in the state */ |
|
+#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020 |
|
+ |
|
+/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means |
|
+ * that the token has some sort of clock. The time on that |
|
+ * clock is returned in the token info structure */ |
|
+#define CKF_CLOCK_ON_TOKEN 0x00000040 |
|
+ |
|
+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is |
|
+ * set, that means that there is some way for the user to login |
|
+ * without sending a PIN through the Cryptoki library itself */ |
|
+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100 |
|
+ |
|
+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true, |
|
+ * that means that a single session with the token can perform |
|
+ * dual simultaneous cryptographic operations (digest and |
|
+ * encrypt; decrypt and digest; sign and encrypt; and decrypt |
|
+ * and sign) */ |
|
+#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200 |
|
+ |
|
+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the |
|
+ * token has been initialized using C_InitializeToken or an |
|
+ * equivalent mechanism outside the scope of PKCS #11. |
|
+ * Calling C_InitializeToken when this flag is set will cause |
|
+ * the token to be reinitialized. */ |
|
+#define CKF_TOKEN_INITIALIZED 0x00000400 |
|
+ |
|
+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is |
|
+ * true, the token supports secondary authentication for |
|
+ * private key objects. This flag is deprecated in v2.11 and |
|
+ onwards. */ |
|
+#define CKF_SECONDARY_AUTHENTICATION 0x00000800 |
|
+ |
|
+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an |
|
+ * incorrect user login PIN has been entered at least once |
|
+ * since the last successful authentication. */ |
|
+#define CKF_USER_PIN_COUNT_LOW 0x00010000 |
|
+ |
|
+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true, |
|
+ * supplying an incorrect user PIN will it to become locked. */ |
|
+#define CKF_USER_PIN_FINAL_TRY 0x00020000 |
|
+ |
|
+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the |
|
+ * user PIN has been locked. User login to the token is not |
|
+ * possible. */ |
|
+#define CKF_USER_PIN_LOCKED 0x00040000 |
|
+ |
|
+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true, |
|
+ * the user PIN value is the default value set by token |
|
+ * initialization or manufacturing, or the PIN has been |
|
+ * expired by the card. */ |
|
+#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000 |
|
+ |
|
+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an |
|
+ * incorrect SO login PIN has been entered at least once since |
|
+ * the last successful authentication. */ |
|
+#define CKF_SO_PIN_COUNT_LOW 0x00100000 |
|
+ |
|
+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true, |
|
+ * supplying an incorrect SO PIN will it to become locked. */ |
|
+#define CKF_SO_PIN_FINAL_TRY 0x00200000 |
|
+ |
|
+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO |
|
+ * PIN has been locked. SO login to the token is not possible. |
|
+ */ |
|
+#define CKF_SO_PIN_LOCKED 0x00400000 |
|
+ |
|
+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true, |
|
+ * the SO PIN value is the default value set by token |
|
+ * initialization or manufacturing, or the PIN has been |
|
+ * expired by the card. */ |
|
+#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000 |
|
+ |
|
+/* CKF_ERROR_STATE if new for v2.30. If it is true, |
|
+ * the token failed a FIPS 140-2 self-test and |
|
+ * entered an error state. */ |
|
+#define CKF_ERROR_STATE 0x01000000 |
|
+ |
|
+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR; |
|
+ |
|
+ |
|
+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that |
|
+ * identifies a session */ |
|
+typedef CK_ULONG CK_SESSION_HANDLE; |
|
+ |
|
+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR; |
|
+ |
|
+ |
|
+/* CK_USER_TYPE enumerates the types of Cryptoki users */ |
|
+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for |
|
+ * v2.0 */ |
|
+typedef CK_ULONG CK_USER_TYPE; |
|
+/* Security Officer */ |
|
+#define CKU_SO 0 |
|
+/* Normal user */ |
|
+#define CKU_USER 1 |
|
+/* Context specific (added in v2.20) */ |
|
+#define CKU_CONTEXT_SPECIFIC 2 |
|
+ |
|
+/* CK_STATE enumerates the session states */ |
|
+/* CK_STATE has been changed from an enum to a CK_ULONG for |
|
+ * v2.0 */ |
|
+typedef CK_ULONG CK_STATE; |
|
+#define CKS_RO_PUBLIC_SESSION 0 |
|
+#define CKS_RO_USER_FUNCTIONS 1 |
|
+#define CKS_RW_PUBLIC_SESSION 2 |
|
+#define CKS_RW_USER_FUNCTIONS 3 |
|
+#define CKS_RW_SO_FUNCTIONS 4 |
|
+ |
|
+ |
|
+/* CK_SESSION_INFO provides information about a session */ |
|
+typedef struct CK_SESSION_INFO { |
|
+ CK_SLOT_ID slotID; |
|
+ CK_STATE state; |
|
+ CK_FLAGS flags; /* see below */ |
|
+ |
|
+ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for |
|
+ * v2.0 */ |
|
+ CK_ULONG ulDeviceError; /* device-dependent error code */ |
|
+} CK_SESSION_INFO; |
|
+ |
|
+/* The flags are defined in the following table: |
|
+ * Bit Flag Mask Meaning |
|
+ */ |
|
+#define CKF_RW_SESSION 0x00000002 /* session is r/w */ |
|
+#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */ |
|
+ |
|
+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR; |
|
+ |
|
+ |
|
+/* CK_OBJECT_HANDLE is a token-specific identifier for an |
|
+ * object */ |
|
+typedef CK_ULONG CK_OBJECT_HANDLE; |
|
+ |
|
+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR; |
|
+ |
|
+ |
|
+/* CK_OBJECT_CLASS is a value that identifies the classes (or |
|
+ * types) of objects that Cryptoki recognizes. It is defined |
|
+ * as follows: */ |
|
+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for |
|
+ * v2.0 */ |
|
+typedef CK_ULONG CK_OBJECT_CLASS; |
|
+ |
|
+/* The following classes of objects are defined: */ |
|
+/* CKO_HW_FEATURE is new for v2.10 */ |
|
+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */ |
|
+/* CKO_MECHANISM is new for v2.20 */ |
|
+#define CKO_DATA 0x00000000 |
|
+#define CKO_CERTIFICATE 0x00000001 |
|
+#define CKO_PUBLIC_KEY 0x00000002 |
|
+#define CKO_PRIVATE_KEY 0x00000003 |
|
+#define CKO_SECRET_KEY 0x00000004 |
|
+#define CKO_HW_FEATURE 0x00000005 |
|
+#define CKO_DOMAIN_PARAMETERS 0x00000006 |
|
+#define CKO_MECHANISM 0x00000007 |
|
+ |
|
+/* CKO_OTP_KEY is new for PKCS #11 v2.20 amendment 1 */ |
|
+#define CKO_OTP_KEY 0x00000008 |
|
+ |
|
+#define CKO_VENDOR_DEFINED 0x80000000 |
|
+ |
|
+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR; |
|
+ |
|
+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a |
|
+ * value that identifies the hardware feature type of an object |
|
+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */ |
|
+typedef CK_ULONG CK_HW_FEATURE_TYPE; |
|
+ |
|
+/* The following hardware feature types are defined */ |
|
+/* CKH_USER_INTERFACE is new for v2.20 */ |
|
+#define CKH_MONOTONIC_COUNTER 0x00000001 |
|
+#define CKH_CLOCK 0x00000002 |
|
+#define CKH_USER_INTERFACE 0x00000003 |
|
+#define CKH_VENDOR_DEFINED 0x80000000 |
|
+ |
|
+/* CK_KEY_TYPE is a value that identifies a key type */ |
|
+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */ |
|
+typedef CK_ULONG CK_KEY_TYPE; |
|
+ |
|
+/* the following key types are defined: */ |
|
+#define CKK_RSA 0x00000000 |
|
+#define CKK_DSA 0x00000001 |
|
+#define CKK_DH 0x00000002 |
|
+ |
|
+/* CKK_ECDSA and CKK_KEA are new for v2.0 */ |
|
+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */ |
|
+#define CKK_ECDSA 0x00000003 |
|
+#define CKK_EC 0x00000003 |
|
+#define CKK_X9_42_DH 0x00000004 |
|
+#define CKK_KEA 0x00000005 |
|
+ |
|
+#define CKK_GENERIC_SECRET 0x00000010 |
|
+#define CKK_RC2 0x00000011 |
|
+#define CKK_RC4 0x00000012 |
|
+#define CKK_DES 0x00000013 |
|
+#define CKK_DES2 0x00000014 |
|
+#define CKK_DES3 0x00000015 |
|
+ |
|
+/* all these key types are new for v2.0 */ |
|
+#define CKK_CAST 0x00000016 |
|
+#define CKK_CAST3 0x00000017 |
|
+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */ |
|
+#define CKK_CAST5 0x00000018 |
|
+#define CKK_CAST128 0x00000018 |
|
+#define CKK_RC5 0x00000019 |
|
+#define CKK_IDEA 0x0000001A |
|
+#define CKK_SKIPJACK 0x0000001B |
|
+#define CKK_BATON 0x0000001C |
|
+#define CKK_JUNIPER 0x0000001D |
|
+#define CKK_CDMF 0x0000001E |
|
+#define CKK_AES 0x0000001F |
|
+ |
|
+/* BlowFish and TwoFish are new for v2.20 */ |
|
+#define CKK_BLOWFISH 0x00000020 |
|
+#define CKK_TWOFISH 0x00000021 |
|
+ |
|
+/* SecurID, HOTP, and ACTI are new for PKCS #11 v2.20 amendment 1 */ |
|
+#define CKK_SECURID 0x00000022 |
|
+#define CKK_HOTP 0x00000023 |
|
+#define CKK_ACTI 0x00000024 |
|
+ |
|
+/* Camellia is new for PKCS #11 v2.20 amendment 3 */ |
|
+#define CKK_CAMELLIA 0x00000025 |
|
+/* ARIA is new for PKCS #11 v2.20 amendment 3 */ |
|
+#define CKK_ARIA 0x00000026 |
|
+ |
|
+/* From PKCS #11 v2.20 amendment 4 draft 2 */ |
|
+#define CKK_MD5_HMAC 0x00000027 |
|
+#define CKK_SHA_1_HMAC 0x00000028 |
|
+#define CKK_RIPEMD128_HMAC 0x00000029 |
|
+#define CKK_RIPEMD160_HMAC 0x0000002A |
|
+#define CKK_SHA256_HMAC 0x0000002B |
|
+#define CKK_SHA384_HMAC 0x0000002C |
|
+#define CKK_SHA512_HMAC 0x0000002D |
|
+#define CKK_SHA224_HMAC 0x0000002E |
|
+ |
|
+/* From PKCS #11 v2.30 */ |
|
+#define CKK_SEED 0x0000002F |
|
+#define CKK_GOSTR3410 0x00000030 |
|
+#define CKK_GOSTR3411 0x00000031 |
|
+#define CKK_GOST28147 0x00000032 |
|
+ |
|
+#define CKK_VENDOR_DEFINED 0x80000000 |
|
+ |
|
+ |
|
+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate |
|
+ * type */ |
|
+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG |
|
+ * for v2.0 */ |
|
+typedef CK_ULONG CK_CERTIFICATE_TYPE; |
|
+ |
|
+/* The following certificate types are defined: */ |
|
+/* CKC_X_509_ATTR_CERT is new for v2.10 */ |
|
+/* CKC_WTLS is new for v2.20 */ |
|
+#define CKC_X_509 0x00000000 |
|
+#define CKC_X_509_ATTR_CERT 0x00000001 |
|
+#define CKC_WTLS 0x00000002 |
|
+#define CKC_VENDOR_DEFINED 0x80000000 |
|
+ |
|
+ |
|
+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute |
|
+ * type */ |
|
+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for |
|
+ * v2.0 */ |
|
+typedef CK_ULONG CK_ATTRIBUTE_TYPE; |
|
+ |
|
+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which |
|
+ consists of an array of values. */ |
|
+#define CKF_ARRAY_ATTRIBUTE 0x40000000 |
|
+ |
|
+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 |
|
+ and relates to the CKA_OTP_FORMAT attribute */ |
|
+#define CK_OTP_FORMAT_DECIMAL 0 |
|
+#define CK_OTP_FORMAT_HEXADECIMAL 1 |
|
+#define CK_OTP_FORMAT_ALPHANUMERIC 2 |
|
+#define CK_OTP_FORMAT_BINARY 3 |
|
+ |
|
+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 |
|
+ and relates to the CKA_OTP_..._REQUIREMENT attributes */ |
|
+#define CK_OTP_PARAM_IGNORED 0 |
|
+#define CK_OTP_PARAM_OPTIONAL 1 |
|
+#define CK_OTP_PARAM_MANDATORY 2 |
|
+ |
|
+/* The following attribute types are defined: */ |
|
+#define CKA_CLASS 0x00000000 |
|
+#define CKA_TOKEN 0x00000001 |
|
+#define CKA_PRIVATE 0x00000002 |
|
+#define CKA_LABEL 0x00000003 |
|
+#define CKA_APPLICATION 0x00000010 |
|
+#define CKA_VALUE 0x00000011 |
|
+ |
|
+/* CKA_OBJECT_ID is new for v2.10 */ |
|
+#define CKA_OBJECT_ID 0x00000012 |
|
+ |
|
+#define CKA_CERTIFICATE_TYPE 0x00000080 |
|
+#define CKA_ISSUER 0x00000081 |
|
+#define CKA_SERIAL_NUMBER 0x00000082 |
|
+ |
|
+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new |
|
+ * for v2.10 */ |
|
+#define CKA_AC_ISSUER 0x00000083 |
|
+#define CKA_OWNER 0x00000084 |
|
+#define CKA_ATTR_TYPES 0x00000085 |
|
+ |
|
+/* CKA_TRUSTED is new for v2.11 */ |
|
+#define CKA_TRUSTED 0x00000086 |
|
+ |
|
+/* CKA_CERTIFICATE_CATEGORY ... |
|
+ * CKA_CHECK_VALUE are new for v2.20 */ |
|
+#define CKA_CERTIFICATE_CATEGORY 0x00000087 |
|
+#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088 |
|
+#define CKA_URL 0x00000089 |
|
+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008A |
|
+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008B |
|
+/* One from v2.30? */ |
|
+#define CKA_NAME_HASH_ALGORITH 0x0000008C |
|
+#define CKA_CHECK_VALUE 0x00000090 |
|
+ |
|
+#define CKA_KEY_TYPE 0x00000100 |
|
+#define CKA_SUBJECT 0x00000101 |
|
+#define CKA_ID 0x00000102 |
|
+#define CKA_SENSITIVE 0x00000103 |
|
+#define CKA_ENCRYPT 0x00000104 |
|
+#define CKA_DECRYPT 0x00000105 |
|
+#define CKA_WRAP 0x00000106 |
|
+#define CKA_UNWRAP 0x00000107 |
|
+#define CKA_SIGN 0x00000108 |
|
+#define CKA_SIGN_RECOVER 0x00000109 |
|
+#define CKA_VERIFY 0x0000010A |
|
+#define CKA_VERIFY_RECOVER 0x0000010B |
|
+#define CKA_DERIVE 0x0000010C |
|
+#define CKA_START_DATE 0x00000110 |
|
+#define CKA_END_DATE 0x00000111 |
|
+#define CKA_MODULUS 0x00000120 |
|
+#define CKA_MODULUS_BITS 0x00000121 |
|
+#define CKA_PUBLIC_EXPONENT 0x00000122 |
|
+#define CKA_PRIVATE_EXPONENT 0x00000123 |
|
+#define CKA_PRIME_1 0x00000124 |
|
+#define CKA_PRIME_2 0x00000125 |
|
+#define CKA_EXPONENT_1 0x00000126 |
|
+#define CKA_EXPONENT_2 0x00000127 |
|
+#define CKA_COEFFICIENT 0x00000128 |
|
+#define CKA_PRIME 0x00000130 |
|
+#define CKA_SUBPRIME 0x00000131 |
|
+#define CKA_BASE 0x00000132 |
|
+ |
|
+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */ |
|
+#define CKA_PRIME_BITS 0x00000133 |
|
+#define CKA_SUBPRIME_BITS 0x00000134 |
|
+#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS |
|
+/* (To retain backwards-compatibility) */ |
|
+ |
|
+#define CKA_VALUE_BITS 0x00000160 |
|
+#define CKA_VALUE_LEN 0x00000161 |
|
+ |
|
+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE, |
|
+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS, |
|
+ * and CKA_EC_POINT are new for v2.0 */ |
|
+#define CKA_EXTRACTABLE 0x00000162 |
|
+#define CKA_LOCAL 0x00000163 |
|
+#define CKA_NEVER_EXTRACTABLE 0x00000164 |
|
+#define CKA_ALWAYS_SENSITIVE 0x00000165 |
|
+ |
|
+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */ |
|
+#define CKA_KEY_GEN_MECHANISM 0x00000166 |
|
+ |
|
+#define CKA_MODIFIABLE 0x00000170 |
|
+ |
|
+/* From v2.30? */ |
|
+#define CKA_COPYABLE 0x00000171 |
|
+ |
|
+/* CKA_ECDSA_PARAMS is deprecated in v2.11, |
|
+ * CKA_EC_PARAMS is preferred. */ |
|
+#define CKA_ECDSA_PARAMS 0x00000180 |
|
+#define CKA_EC_PARAMS 0x00000180 |
|
+ |
|
+#define CKA_EC_POINT 0x00000181 |
|
+ |
|
+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS, |
|
+ * are new for v2.10. Deprecated in v2.11 and onwards. */ |
|
+#define CKA_SECONDARY_AUTH 0x00000200 |
|
+#define CKA_AUTH_PIN_FLAGS 0x00000201 |
|
+ |
|
+/* CKA_ALWAYS_AUTHENTICATE ... |
|
+ * CKA_UNWRAP_TEMPLATE are new for v2.20 */ |
|
+#define CKA_ALWAYS_AUTHENTICATE 0x00000202 |
|
+ |
|
+#define CKA_WRAP_WITH_TRUSTED 0x00000210 |
|
+#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211) |
|
+#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212) |
|
+ |
|
+/* CKA_OTP... atttributes are new for PKCS #11 v2.20 amendment 3. */ |
|
+#define CKA_OTP_FORMAT 0x00000220 |
|
+#define CKA_OTP_LENGTH 0x00000221 |
|
+#define CKA_OTP_TIME_INTERVAL 0x00000222 |
|
+#define CKA_OTP_USER_FRIENDLY_MODE 0x00000223 |
|
+#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224 |
|
+#define CKA_OTP_TIME_REQUIREMENT 0x00000225 |
|
+#define CKA_OTP_COUNTER_REQUIREMENT 0x00000226 |
|
+#define CKA_OTP_PIN_REQUIREMENT 0x00000227 |
|
+#define CKA_OTP_COUNTER 0x0000022E |
|
+#define CKA_OTP_TIME 0x0000022F |
|
+#define CKA_OTP_USER_IDENTIFIER 0x0000022A |
|
+#define CKA_OTP_SERVICE_IDENTIFIER 0x0000022B |
|
+#define CKA_OTP_SERVICE_LOGO 0x0000022C |
|
+#define CKA_OTP_SERVICE_LOGO_TYPE 0x0000022D |
|
+ |
|
+/* CKA_GOST... */ |
|
+#define CKA_GOSTR3410_PARAMS 0x00000250 |
|
+#define CKA_GOSTR3411_PARAMS 0x00000251 |
|
+#define CKA_GOST28147_PARAMS 0x00000252 |
|
+ |
|
+/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET |
|
+ * are new for v2.10 */ |
|
+#define CKA_HW_FEATURE_TYPE 0x00000300 |
|
+#define CKA_RESET_ON_INIT 0x00000301 |
|
+#define CKA_HAS_RESET 0x00000302 |
|
+ |
|
+/* The following attributes are new for v2.20 */ |
|
+#define CKA_PIXEL_X 0x00000400 |
|
+#define CKA_PIXEL_Y 0x00000401 |
|
+#define CKA_RESOLUTION 0x00000402 |
|
+#define CKA_CHAR_ROWS 0x00000403 |
|
+#define CKA_CHAR_COLUMNS 0x00000404 |
|
+#define CKA_COLOR 0x00000405 |
|
+#define CKA_BITS_PER_PIXEL 0x00000406 |
|
+#define CKA_CHAR_SETS 0x00000480 |
|
+#define CKA_ENCODING_METHODS 0x00000481 |
|
+#define CKA_MIME_TYPES 0x00000482 |
|
+#define CKA_MECHANISM_TYPE 0x00000500 |
|
+#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501 |
|
+#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502 |
|
+#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503 |
|
+#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600) |
|
+/* From v2.30? */ |
|
+#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211) |
|
+#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212) |
|
+#define CKA_DERIVE_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000213) |
|
+ |
|
+#define CKA_VENDOR_DEFINED 0x80000000 |
|
+ |
|
+/* CK_ATTRIBUTE is a structure that includes the type, length |
|
+ * and value of an attribute */ |
|
+typedef struct CK_ATTRIBUTE { |
|
+ CK_ATTRIBUTE_TYPE type; |
|
+ CK_VOID_PTR pValue; |
|
+ |
|
+ /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */ |
|
+ CK_ULONG ulValueLen; /* in bytes */ |
|
+} CK_ATTRIBUTE; |
|
+ |
|
+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR; |
|
+ |
|
+ |
|
+/* CK_DATE is a structure that defines a date */ |
|
+typedef struct CK_DATE{ |
|
+ CK_CHAR year[4]; /* the year ("1900" - "9999") */ |
|
+ CK_CHAR month[2]; /* the month ("01" - "12") */ |
|
+ CK_CHAR day[2]; /* the day ("01" - "31") */ |
|
+} CK_DATE; |
|
+ |
|
+ |
|
+/* CK_MECHANISM_TYPE is a value that identifies a mechanism |
|
+ * type */ |
|
+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for |
|
+ * v2.0 */ |
|
+typedef CK_ULONG CK_MECHANISM_TYPE; |
|
+ |
|
+/* the following mechanism types are defined: */ |
|
+#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000 |
|
+#define CKM_RSA_PKCS 0x00000001 |
|
+#define CKM_RSA_9796 0x00000002 |
|
+#define CKM_RSA_X_509 0x00000003 |
|
+ |
|
+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS |
|
+ * are new for v2.0. They are mechanisms which hash and sign */ |
|
+#define CKM_MD2_RSA_PKCS 0x00000004 |
|
+#define CKM_MD5_RSA_PKCS 0x00000005 |
|
+#define CKM_SHA1_RSA_PKCS 0x00000006 |
|
+ |
|
+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and |
|
+ * CKM_RSA_PKCS_OAEP are new for v2.10 */ |
|
+#define CKM_RIPEMD128_RSA_PKCS 0x00000007 |
|
+#define CKM_RIPEMD160_RSA_PKCS 0x00000008 |
|
+#define CKM_RSA_PKCS_OAEP 0x00000009 |
|
+ |
|
+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31, |
|
+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */ |
|
+#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A |
|
+#define CKM_RSA_X9_31 0x0000000B |
|
+#define CKM_SHA1_RSA_X9_31 0x0000000C |
|
+#define CKM_RSA_PKCS_PSS 0x0000000D |
|
+#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E |
|
+ |
|
+#define CKM_DSA_KEY_PAIR_GEN 0x00000010 |
|
+#define CKM_DSA 0x00000011 |
|
+#define CKM_DSA_SHA1 0x00000012 |
|
+/* Other DSAs */ |
|
+#define CKM_DSA_SHA224 0x00000013 |
|
+#define CKM_DSA_SHA256 0x00000014 |
|
+#define CKM_DSA_SHA384 0x00000015 |
|
+#define CKM_DSA_SHA512 0x00000016 |
|
+ |
|
+#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020 |
|
+#define CKM_DH_PKCS_DERIVE 0x00000021 |
|
+ |
|
+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE, |
|
+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for |
|
+ * v2.11 */ |
|
+#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030 |
|
+#define CKM_X9_42_DH_DERIVE 0x00000031 |
|
+#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032 |
|
+#define CKM_X9_42_MQV_DERIVE 0x00000033 |
|
+ |
|
+/* CKM_SHA256/384/512 are new for v2.20 */ |
|
+#define CKM_SHA256_RSA_PKCS 0x00000040 |
|
+#define CKM_SHA384_RSA_PKCS 0x00000041 |
|
+#define CKM_SHA512_RSA_PKCS 0x00000042 |
|
+#define CKM_SHA256_RSA_PKCS_PSS 0x00000043 |
|
+#define CKM_SHA384_RSA_PKCS_PSS 0x00000044 |
|
+#define CKM_SHA512_RSA_PKCS_PSS 0x00000045 |
|
+ |
|
+/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */ |
|
+#define CKM_SHA224_RSA_PKCS 0x00000046 |
|
+#define CKM_SHA224_RSA_PKCS_PSS 0x00000047 |
|
+ |
|
+#define CKM_RC2_KEY_GEN 0x00000100 |
|
+#define CKM_RC2_ECB 0x00000101 |
|
+#define CKM_RC2_CBC 0x00000102 |
|
+#define CKM_RC2_MAC 0x00000103 |
|
+ |
|
+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */ |
|
+#define CKM_RC2_MAC_GENERAL 0x00000104 |
|
+#define CKM_RC2_CBC_PAD 0x00000105 |
|
+ |
|
+#define CKM_RC4_KEY_GEN 0x00000110 |
|
+#define CKM_RC4 0x00000111 |
|
+#define CKM_DES_KEY_GEN 0x00000120 |
|
+#define CKM_DES_ECB 0x00000121 |
|
+#define CKM_DES_CBC 0x00000122 |
|
+#define CKM_DES_MAC 0x00000123 |
|
+ |
|
+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */ |
|
+#define CKM_DES_MAC_GENERAL 0x00000124 |
|
+#define CKM_DES_CBC_PAD 0x00000125 |
|
+ |
|
+#define CKM_DES2_KEY_GEN 0x00000130 |
|
+#define CKM_DES3_KEY_GEN 0x00000131 |
|
+#define CKM_DES3_ECB 0x00000132 |
|
+#define CKM_DES3_CBC 0x00000133 |
|
+#define CKM_DES3_MAC 0x00000134 |
|
+ |
|
+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN, |
|
+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC, |
|
+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0, |
|
+ * CKM_DES3_CMAC_GENERAL and CKM_DES3_CMAC are from v2.30? */ |
|
+#define CKM_DES3_MAC_GENERAL 0x00000135 |
|
+#define CKM_DES3_CBC_PAD 0x00000136 |
|
+#define CKM_DES3_CMAC_GENERAL 0x00000137 |
|
+#define CKM_DES3_CMAC 0x00000138 |
|
+#define CKM_CDMF_KEY_GEN 0x00000140 |
|
+#define CKM_CDMF_ECB 0x00000141 |
|
+#define CKM_CDMF_CBC 0x00000142 |
|
+#define CKM_CDMF_MAC 0x00000143 |
|
+#define CKM_CDMF_MAC_GENERAL 0x00000144 |
|
+#define CKM_CDMF_CBC_PAD 0x00000145 |
|
+ |
|
+/* the following four DES mechanisms are new for v2.20 */ |
|
+#define CKM_DES_OFB64 0x00000150 |
|
+#define CKM_DES_OFB8 0x00000151 |
|
+#define CKM_DES_CFB64 0x00000152 |
|
+#define CKM_DES_CFB8 0x00000153 |
|
+ |
|
+#define CKM_MD2 0x00000200 |
|
+ |
|
+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */ |
|
+#define CKM_MD2_HMAC 0x00000201 |
|
+#define CKM_MD2_HMAC_GENERAL 0x00000202 |
|
+ |
|
+#define CKM_MD5 0x00000210 |
|
+ |
|
+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */ |
|
+#define CKM_MD5_HMAC 0x00000211 |
|
+#define CKM_MD5_HMAC_GENERAL 0x00000212 |
|
+ |
|
+#define CKM_SHA_1 0x00000220 |
|
+ |
|
+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */ |
|
+#define CKM_SHA_1_HMAC 0x00000221 |
|
+#define CKM_SHA_1_HMAC_GENERAL 0x00000222 |
|
+ |
|
+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC, |
|
+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC, |
|
+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */ |
|
+#define CKM_RIPEMD128 0x00000230 |
|
+#define CKM_RIPEMD128_HMAC 0x00000231 |
|
+#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232 |
|
+#define CKM_RIPEMD160 0x00000240 |
|
+#define CKM_RIPEMD160_HMAC 0x00000241 |
|
+#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242 |
|
+ |
|
+/* CKM_SHA256/384/512 are new for v2.20 */ |
|
+#define CKM_SHA256 0x00000250 |
|
+#define CKM_SHA256_HMAC 0x00000251 |
|
+#define CKM_SHA256_HMAC_GENERAL 0x00000252 |
|
+ |
|
+/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */ |
|
+#define CKM_SHA224 0x00000255 |
|
+#define CKM_SHA224_HMAC 0x00000256 |
|
+#define CKM_SHA224_HMAC_GENERAL 0x00000257 |
|
+ |
|
+#define CKM_SHA384 0x00000260 |
|
+#define CKM_SHA384_HMAC 0x00000261 |
|
+#define CKM_SHA384_HMAC_GENERAL 0x00000262 |
|
+#define CKM_SHA512 0x00000270 |
|
+#define CKM_SHA512_HMAC 0x00000271 |
|
+#define CKM_SHA512_HMAC_GENERAL 0x00000272 |
|
+ |
|
+/* SecurID is new for PKCS #11 v2.20 amendment 1 */ |
|
+#define CKM_SECURID_KEY_GEN 0x00000280 |
|
+#define CKM_SECURID 0x00000282 |
|
+ |
|
+/* HOTP is new for PKCS #11 v2.20 amendment 1 */ |
|
+#define CKM_HOTP_KEY_GEN 0x00000290 |
|
+#define CKM_HOTP 0x00000291 |
|
+ |
|
+/* ACTI is new for PKCS #11 v2.20 amendment 1 */ |
|
+#define CKM_ACTI 0x000002A0 |
|
+#define CKM_ACTI_KEY_GEN 0x000002A1 |
|
+ |
|
+/* All of the following mechanisms are new for v2.0 */ |
|
+/* Note that CAST128 and CAST5 are the same algorithm */ |
|
+#define CKM_CAST_KEY_GEN 0x00000300 |
|
+#define CKM_CAST_ECB 0x00000301 |
|
+#define CKM_CAST_CBC 0x00000302 |
|
+#define CKM_CAST_MAC 0x00000303 |
|
+#define CKM_CAST_MAC_GENERAL 0x00000304 |
|
+#define CKM_CAST_CBC_PAD 0x00000305 |
|
+#define CKM_CAST3_KEY_GEN 0x00000310 |
|
+#define CKM_CAST3_ECB 0x00000311 |
|
+#define CKM_CAST3_CBC 0x00000312 |
|
+#define CKM_CAST3_MAC 0x00000313 |
|
+#define CKM_CAST3_MAC_GENERAL 0x00000314 |
|
+#define CKM_CAST3_CBC_PAD 0x00000315 |
|
+#define CKM_CAST5_KEY_GEN 0x00000320 |
|
+#define CKM_CAST128_KEY_GEN 0x00000320 |
|
+#define CKM_CAST5_ECB 0x00000321 |
|
+#define CKM_CAST128_ECB 0x00000321 |
|
+#define CKM_CAST5_CBC 0x00000322 |
|
+#define CKM_CAST128_CBC 0x00000322 |
|
+#define CKM_CAST5_MAC 0x00000323 |
|
+#define CKM_CAST128_MAC 0x00000323 |
|
+#define CKM_CAST5_MAC_GENERAL 0x00000324 |
|
+#define CKM_CAST128_MAC_GENERAL 0x00000324 |
|
+#define CKM_CAST5_CBC_PAD 0x00000325 |
|
+#define CKM_CAST128_CBC_PAD 0x00000325 |
|
+#define CKM_RC5_KEY_GEN 0x00000330 |
|
+#define CKM_RC5_ECB 0x00000331 |
|
+#define CKM_RC5_CBC 0x00000332 |
|
+#define CKM_RC5_MAC 0x00000333 |
|
+#define CKM_RC5_MAC_GENERAL 0x00000334 |
|
+#define CKM_RC5_CBC_PAD 0x00000335 |
|
+#define CKM_IDEA_KEY_GEN 0x00000340 |
|
+#define CKM_IDEA_ECB 0x00000341 |
|
+#define CKM_IDEA_CBC 0x00000342 |
|
+#define CKM_IDEA_MAC 0x00000343 |
|
+#define CKM_IDEA_MAC_GENERAL 0x00000344 |
|
+#define CKM_IDEA_CBC_PAD 0x00000345 |
|
+#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350 |
|
+#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360 |
|
+#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362 |
|
+#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363 |
|
+#define CKM_XOR_BASE_AND_DATA 0x00000364 |
|
+#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365 |
|
+#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370 |
|
+#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371 |
|
+#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372 |
|
+ |
|
+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN, |
|
+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and |
|
+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */ |
|
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373 |
|
+#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374 |
|
+#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375 |
|
+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376 |
|
+#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377 |
|
+ |
|
+/* CKM_TLS_PRF is new for v2.20 */ |
|
+#define CKM_TLS_PRF 0x00000378 |
|
+ |
|
+#define CKM_SSL3_MD5_MAC 0x00000380 |
|
+#define CKM_SSL3_SHA1_MAC 0x00000381 |
|
+#define CKM_MD5_KEY_DERIVATION 0x00000390 |
|
+#define CKM_MD2_KEY_DERIVATION 0x00000391 |
|
+#define CKM_SHA1_KEY_DERIVATION 0x00000392 |
|
+ |
|
+/* CKM_SHA256/384/512 are new for v2.20 */ |
|
+#define CKM_SHA256_KEY_DERIVATION 0x00000393 |
|
+#define CKM_SHA384_KEY_DERIVATION 0x00000394 |
|
+#define CKM_SHA512_KEY_DERIVATION 0x00000395 |
|
+ |
|
+/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */ |
|
+#define CKM_SHA224_KEY_DERIVATION 0x00000396 |
|
+ |
|
+#define CKM_PBE_MD2_DES_CBC 0x000003A0 |
|
+#define CKM_PBE_MD5_DES_CBC 0x000003A1 |
|
+#define CKM_PBE_MD5_CAST_CBC 0x000003A2 |
|
+#define CKM_PBE_MD5_CAST3_CBC 0x000003A3 |
|
+#define CKM_PBE_MD5_CAST5_CBC 0x000003A4 |
|
+#define CKM_PBE_MD5_CAST128_CBC 0x000003A4 |
|
+#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5 |
|
+#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5 |
|
+#define CKM_PBE_SHA1_RC4_128 0x000003A6 |
|
+#define CKM_PBE_SHA1_RC4_40 0x000003A7 |
|
+#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8 |
|
+#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9 |
|
+#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA |
|
+#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB |
|
+ |
|
+/* CKM_PKCS5_PBKD2 is new for v2.10 */ |
|
+#define CKM_PKCS5_PBKD2 0x000003B0 |
|
+ |
|
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0 |
|
+ |
|
+/* WTLS mechanisms are new for v2.20 */ |
|
+#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0 |
|
+#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1 |
|
+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2 |
|
+#define CKM_WTLS_PRF 0x000003D3 |
|
+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4 |
|
+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5 |
|
+ |
|
+#define CKM_KEY_WRAP_LYNKS 0x00000400 |
|
+#define CKM_KEY_WRAP_SET_OAEP 0x00000401 |
|
+ |
|
+/* CKM_CMS_SIG is new for v2.20 */ |
|
+#define CKM_CMS_SIG 0x00000500 |
|
+ |
|
+/* CKM_KIP mechanisms are new for PKCS #11 v2.20 amendment 2 */ |
|
+#define CKM_KIP_DERIVE 0x00000510 |
|
+#define CKM_KIP_WRAP 0x00000511 |
|
+#define CKM_KIP_MAC 0x00000512 |
|
+ |
|
+/* Camellia is new for PKCS #11 v2.20 amendment 3 */ |
|
+#define CKM_CAMELLIA_KEY_GEN 0x00000550 |
|
+#define CKM_CAMELLIA_ECB 0x00000551 |
|
+#define CKM_CAMELLIA_CBC 0x00000552 |
|
+#define CKM_CAMELLIA_MAC 0x00000553 |
|
+#define CKM_CAMELLIA_MAC_GENERAL 0x00000554 |
|
+#define CKM_CAMELLIA_CBC_PAD 0x00000555 |
|
+#define CKM_CAMELLIA_ECB_ENCRYPT_DATA 0x00000556 |
|
+#define CKM_CAMELLIA_CBC_ENCRYPT_DATA 0x00000557 |
|
+#define CKM_CAMELLIA_CTR 0x00000558 |
|
+ |
|
+/* ARIA is new for PKCS #11 v2.20 amendment 3 */ |
|
+#define CKM_ARIA_KEY_GEN 0x00000560 |
|
+#define CKM_ARIA_ECB 0x00000561 |
|
+#define CKM_ARIA_CBC 0x00000562 |
|
+#define CKM_ARIA_MAC 0x00000563 |
|
+#define CKM_ARIA_MAC_GENERAL 0x00000564 |
|
+#define CKM_ARIA_CBC_PAD 0x00000565 |
|
+#define CKM_ARIA_ECB_ENCRYPT_DATA 0x00000566 |
|
+#define CKM_ARIA_CBC_ENCRYPT_DATA 0x00000567 |
|
+ |
|
+/* SEED is new from PKCS #11 v2.30? */ |
|
+#define CKM_SEED_KEY_GEN 0x00000650 |
|
+#define CKM_SEED_ECB 0x00000651 |
|
+#define CKM_SEED_CBC 0x00000652 |
|
+#define CKM_SEED_MAC 0x00000653 |
|
+#define CKM_SEED_MAC_GENERAL 0x00000654 |
|
+#define CKM_SEED_CBC_PAD 0x00000655 |
|
+#define CKM_SEED_ECB_ENCRYPT_DATA 0x00000656 |
|
+#define CKM_SEED_CBC_ENCRYPT_DATA 0x00000657 |
|
+ |
|
+/* Fortezza mechanisms */ |
|
+#define CKM_SKIPJACK_KEY_GEN 0x00001000 |
|
+#define CKM_SKIPJACK_ECB64 0x00001001 |
|
+#define CKM_SKIPJACK_CBC64 0x00001002 |
|
+#define CKM_SKIPJACK_OFB64 0x00001003 |
|
+#define CKM_SKIPJACK_CFB64 0x00001004 |
|
+#define CKM_SKIPJACK_CFB32 0x00001005 |
|
+#define CKM_SKIPJACK_CFB16 0x00001006 |
|
+#define CKM_SKIPJACK_CFB8 0x00001007 |
|
+#define CKM_SKIPJACK_WRAP 0x00001008 |
|
+#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009 |
|
+#define CKM_SKIPJACK_RELAYX 0x0000100a |
|
+#define CKM_KEA_KEY_PAIR_GEN 0x00001010 |
|
+#define CKM_KEA_KEY_DERIVE 0x00001011 |
|
+#define CKM_FORTEZZA_TIMESTAMP 0x00001020 |
|
+#define CKM_BATON_KEY_GEN 0x00001030 |
|
+#define CKM_BATON_ECB128 0x00001031 |
|
+#define CKM_BATON_ECB96 0x00001032 |
|
+#define CKM_BATON_CBC128 0x00001033 |
|
+#define CKM_BATON_COUNTER 0x00001034 |
|
+#define CKM_BATON_SHUFFLE 0x00001035 |
|
+#define CKM_BATON_WRAP 0x00001036 |
|
+ |
|
+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11, |
|
+ * CKM_EC_KEY_PAIR_GEN is preferred */ |
|
+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040 |
|
+#define CKM_EC_KEY_PAIR_GEN 0x00001040 |
|
+ |
|
+#define CKM_ECDSA 0x00001041 |
|
+#define CKM_ECDSA_SHA1 0x00001042 |
|
+ |
|
+/* From v2.30? */ |
|
+#define CKM_ECDSA_SHA224 0x00001043 |
|
+#define CKM_ECDSA_SHA256 0x00001044 |
|
+#define CKM_ECDSA_SHA384 0x00001045 |
|
+#define CKM_ECDSA_SHA512 0x00001046 |
|
+ |
|
+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE |
|
+ * are new for v2.11 */ |
|
+#define CKM_ECDH1_DERIVE 0x00001050 |
|
+#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051 |
|
+#define CKM_ECMQV_DERIVE 0x00001052 |
|
+ |
|
+#define CKM_JUNIPER_KEY_GEN 0x00001060 |
|
+#define CKM_JUNIPER_ECB128 0x00001061 |
|
+#define CKM_JUNIPER_CBC128 0x00001062 |
|
+#define CKM_JUNIPER_COUNTER 0x00001063 |
|
+#define CKM_JUNIPER_SHUFFLE 0x00001064 |
|
+#define CKM_JUNIPER_WRAP 0x00001065 |
|
+#define CKM_FASTHASH 0x00001070 |
|
+ |
|
+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC, |
|
+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN, |
|
+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are |
|
+ * new for v2.11 */ |
|
+#define CKM_AES_KEY_GEN 0x00001080 |
|
+#define CKM_AES_ECB 0x00001081 |
|
+#define CKM_AES_CBC 0x00001082 |
|
+#define CKM_AES_MAC 0x00001083 |
|
+#define CKM_AES_MAC_GENERAL 0x00001084 |
|
+#define CKM_AES_CBC_PAD 0x00001085 |
|
+ |
|
+/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */ |
|
+#define CKM_AES_CTR 0x00001086 |
|
+ |
|
+/* Missing CKM_AES_GCM and co! */ |
|
+ |
|
+/* BlowFish and TwoFish are new for v2.20 */ |
|
+#define CKM_BLOWFISH_KEY_GEN 0x00001090 |
|
+#define CKM_BLOWFISH_CBC 0x00001091 |
|
+#define CKM_TWOFISH_KEY_GEN 0x00001092 |
|
+#define CKM_TWOFISH_CBC 0x00001093 |
|
+ |
|
+ |
|
+/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */ |
|
+#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100 |
|
+#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101 |
|
+#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102 |
|
+#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103 |
|
+#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104 |
|
+#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105 |
|
+ |
|
+/* GOST mechanism from v2.30? */ |
|
+#define CKM_GOSTR3410_KEY_PAIR_GEN 0x00001200 |
|
+#define CKM_GOSTR3410 0x00001201 |
|
+#define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202 |
|
+#define CKM_GOSTR3410_KEY_WRAP 0x00001203 |
|
+#define CKM_GOSTR3410_DERIVE 0x00001204 |
|
+#define CKM_GOSTR3411 0x00001210 |
|
+#define CKM_GOSTR3411_HMAC 0x00001211 |
|
+#define CKM_GOST28147_KEY_GEN 0x00001220 |
|
+#define CKM_GOST28147_ECB 0x00001221 |
|
+#define CKM_GOST28147 0x00001222 |
|
+#define CKM_GOST28147_MAC 0x00001223 |
|
+#define CKM_GOST28147_KEY_WRAP 0x00001224 |
|
+ |
|
+#define CKM_DSA_PARAMETER_GEN 0x00002000 |
|
+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001 |
|
+#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002 |
|
+ |
|
+/* Missing AES_OFB and co, and RSA_PKCS 1_1 */ |
|
+ |
|
+#define CKM_VENDOR_DEFINED 0x80000000 |
|
+ |
|
+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR; |
|
+ |
|
+ |
|
+/* CK_MECHANISM is a structure that specifies a particular |
|
+ * mechanism */ |
|
+typedef struct CK_MECHANISM { |
|
+ CK_MECHANISM_TYPE mechanism; |
|
+ CK_VOID_PTR pParameter; |
|
+ |
|
+ /* ulParameterLen was changed from CK_USHORT to CK_ULONG for |
|
+ * v2.0 */ |
|
+ CK_ULONG ulParameterLen; /* in bytes */ |
|
+} CK_MECHANISM; |
|
+ |
|
+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR; |
|
+ |
|
+ |
|
+/* CK_MECHANISM_INFO provides information about a particular |
|
+ * mechanism */ |
|
+typedef struct CK_MECHANISM_INFO { |
|
+ CK_ULONG ulMinKeySize; |
|
+ CK_ULONG ulMaxKeySize; |
|
+ CK_FLAGS flags; |
|
+} CK_MECHANISM_INFO; |
|
+ |
|
+/* The flags are defined as follows: |
|
+ * Bit Flag Mask Meaning */ |
|
+#define CKF_HW 0x00000001 /* performed by HW */ |
|
+ |
|
+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN, |
|
+ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER, |
|
+ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP, |
|
+ * and CKF_DERIVE are new for v2.0. They specify whether or not |
|
+ * a mechanism can be used for a particular task */ |
|
+#define CKF_ENCRYPT 0x00000100 |
|
+#define CKF_DECRYPT 0x00000200 |
|
+#define CKF_DIGEST 0x00000400 |
|
+#define CKF_SIGN 0x00000800 |
|
+#define CKF_SIGN_RECOVER 0x00001000 |
|
+#define CKF_VERIFY 0x00002000 |
|
+#define CKF_VERIFY_RECOVER 0x00004000 |
|
+#define CKF_GENERATE 0x00008000 |
|
+#define CKF_GENERATE_KEY_PAIR 0x00010000 |
|
+#define CKF_WRAP 0x00020000 |
|
+#define CKF_UNWRAP 0x00040000 |
|
+#define CKF_DERIVE 0x00080000 |
|
+ |
|
+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE, |
|
+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They |
|
+ * describe a token's EC capabilities not available in mechanism |
|
+ * information. */ |
|
+#define CKF_EC_F_P 0x00100000 |
|
+#define CKF_EC_F_2M 0x00200000 |
|
+#define CKF_EC_ECPARAMETERS 0x00400000 |
|
+#define CKF_EC_NAMEDCURVE 0x00800000 |
|
+#define CKF_EC_UNCOMPRESS 0x01000000 |
|
+#define CKF_EC_COMPRESS 0x02000000 |
|
+ |
|
+#define CKF_EXTENSION 0x80000000 /* FALSE for this version */ |
|
+ |
|
+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR; |
|
+ |
|
+ |
|
+/* CK_RV is a value that identifies the return value of a |
|
+ * Cryptoki function */ |
|
+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */ |
|
+typedef CK_ULONG CK_RV; |
|
+ |
|
+#define CKR_OK 0x00000000 |
|
+#define CKR_CANCEL 0x00000001 |
|
+#define CKR_HOST_MEMORY 0x00000002 |
|
+#define CKR_SLOT_ID_INVALID 0x00000003 |
|
+ |
|
+/* CKR_FLAGS_INVALID was removed for v2.0 */ |
|
+ |
|
+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */ |
|
+#define CKR_GENERAL_ERROR 0x00000005 |
|
+#define CKR_FUNCTION_FAILED 0x00000006 |
|
+ |
|
+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS, |
|
+ * and CKR_CANT_LOCK are new for v2.01 */ |
|
+#define CKR_ARGUMENTS_BAD 0x00000007 |
|
+#define CKR_NO_EVENT 0x00000008 |
|
+#define CKR_NEED_TO_CREATE_THREADS 0x00000009 |
|
+#define CKR_CANT_LOCK 0x0000000A |
|
+ |
|
+#define CKR_ATTRIBUTE_READ_ONLY 0x00000010 |
|
+#define CKR_ATTRIBUTE_SENSITIVE 0x00000011 |
|
+#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012 |
|
+#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013 |
|
+/* New CKR_COPY_PROHIBITED in v2.30? */ |
|
+#define CKR_COPY_PROHIBITED 0x0000001A |
|
+#define CKR_DATA_INVALID 0x00000020 |
|
+#define CKR_DATA_LEN_RANGE 0x00000021 |
|
+#define CKR_DEVICE_ERROR 0x00000030 |
|
+#define CKR_DEVICE_MEMORY 0x00000031 |
|
+#define CKR_DEVICE_REMOVED 0x00000032 |
|
+#define CKR_ENCRYPTED_DATA_INVALID 0x00000040 |
|
+#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041 |
|
+#define CKR_FUNCTION_CANCELED 0x00000050 |
|
+#define CKR_FUNCTION_NOT_PARALLEL 0x00000051 |
|
+ |
|
+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */ |
|
+#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054 |
|
+ |
|
+#define CKR_KEY_HANDLE_INVALID 0x00000060 |
|
+ |
|
+/* CKR_KEY_SENSITIVE was removed for v2.0 */ |
|
+ |
|
+#define CKR_KEY_SIZE_RANGE 0x00000062 |
|
+#define CKR_KEY_TYPE_INCONSISTENT 0x00000063 |
|
+ |
|
+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED, |
|
+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED, |
|
+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for |
|
+ * v2.0 */ |
|
+#define CKR_KEY_NOT_NEEDED 0x00000064 |
|
+#define CKR_KEY_CHANGED 0x00000065 |
|
+#define CKR_KEY_NEEDED 0x00000066 |
|
+#define CKR_KEY_INDIGESTIBLE 0x00000067 |
|
+#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068 |
|
+#define CKR_KEY_NOT_WRAPPABLE 0x00000069 |
|
+#define CKR_KEY_UNEXTRACTABLE 0x0000006A |
|
+ |
|
+#define CKR_MECHANISM_INVALID 0x00000070 |
|
+#define CKR_MECHANISM_PARAM_INVALID 0x00000071 |
|
+ |
|
+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID |
|
+ * were removed for v2.0 */ |
|
+#define CKR_OBJECT_HANDLE_INVALID 0x00000082 |
|
+#define CKR_OPERATION_ACTIVE 0x00000090 |
|
+#define CKR_OPERATION_NOT_INITIALIZED 0x00000091 |
|
+#define CKR_PIN_INCORRECT 0x000000A0 |
|
+#define CKR_PIN_INVALID 0x000000A1 |
|
+#define CKR_PIN_LEN_RANGE 0x000000A2 |
|
+ |
|
+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */ |
|
+#define CKR_PIN_EXPIRED 0x000000A3 |
|
+#define CKR_PIN_LOCKED 0x000000A4 |
|
+ |
|
+#define CKR_SESSION_CLOSED 0x000000B0 |
|
+#define CKR_SESSION_COUNT 0x000000B1 |
|
+#define CKR_SESSION_HANDLE_INVALID 0x000000B3 |
|
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4 |
|
+#define CKR_SESSION_READ_ONLY 0x000000B5 |
|
+#define CKR_SESSION_EXISTS 0x000000B6 |
|
+ |
|
+/* CKR_SESSION_READ_ONLY_EXISTS and |
|
+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */ |
|
+#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7 |
|
+#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8 |
|
+ |
|
+#define CKR_SIGNATURE_INVALID 0x000000C0 |
|
+#define CKR_SIGNATURE_LEN_RANGE 0x000000C1 |
|
+#define CKR_TEMPLATE_INCOMPLETE 0x000000D0 |
|
+#define CKR_TEMPLATE_INCONSISTENT 0x000000D1 |
|
+#define CKR_TOKEN_NOT_PRESENT 0x000000E0 |
|
+#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1 |
|
+#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2 |
|
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0 |
|
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1 |
|
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2 |
|
+ |
|
+/* private extra values */ |
|
+#define CKR_LIBRARY_ALREADY_INITIALIZED 0x000000FD |
|
+#define CKR_LIBRARY_FAILED_TO_LOAD 0x000000FE |
|
+#define CKR_SYMBOL_RESOLUTION_FAILED 0x000000FF |
|
+ |
|
+#define CKR_USER_ALREADY_LOGGED_IN 0x00000100 |
|
+#define CKR_USER_NOT_LOGGED_IN 0x00000101 |
|
+#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102 |
|
+#define CKR_USER_TYPE_INVALID 0x00000103 |
|
+ |
|
+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES |
|
+ * are new to v2.01 */ |
|
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104 |
|
+#define CKR_USER_TOO_MANY_TYPES 0x00000105 |
|
+ |
|
+#define CKR_WRAPPED_KEY_INVALID 0x00000110 |
|
+#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112 |
|
+#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113 |
|
+#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114 |
|
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115 |
|
+#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120 |
|
+ |
|
+/* These are new to v2.0 */ |
|
+#define CKR_RANDOM_NO_RNG 0x00000121 |
|
+ |
|
+/* These are new to v2.11 */ |
|
+#define CKR_DOMAIN_PARAMS_INVALID 0x00000130 |
|
+ |
|
+/* These are new to v2.0 */ |
|
+#define CKR_BUFFER_TOO_SMALL 0x00000150 |
|
+#define CKR_SAVED_STATE_INVALID 0x00000160 |
|
+#define CKR_INFORMATION_SENSITIVE 0x00000170 |
|
+#define CKR_STATE_UNSAVEABLE 0x00000180 |
|
+ |
|
+/* These are new to v2.01 */ |
|
+#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190 |
|
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191 |
|
+#define CKR_MUTEX_BAD 0x000001A0 |
|
+#define CKR_MUTEX_NOT_LOCKED 0x000001A1 |
|
+ |
|
+/* The following return values are new for PKCS #11 v2.20 amendment 3 */ |
|
+#define CKR_NEW_PIN_MODE 0x000001B0 |
|
+#define CKR_NEXT_OTP 0x000001B1 |
|
+ |
|
+/* New from v2.30? */ |
|
+#define CKR_EXCEEDED_MAX_ITERATIONS 0x000001B5 |
|
+#define CKR_FIPS_SELF_TEST_FAILED 0x000001B6 |
|
+#define CKR_LIBRARY_LOAD_FAILED 0x000001B7 |
|
+#define CKR_PIN_TOO_WEAK 0x000001B8 |
|
+#define CKR_PUBLIC_KEY_INVALID 0x000001B9 |
|
+ |
|
+/* This is new to v2.20 */ |
|
+#define CKR_FUNCTION_REJECTED 0x00000200 |
|
+ |
|
+#define CKR_VENDOR_DEFINED 0x80000000 |
|
+ |
|
+ |
|
+/* CK_NOTIFY is an application callback that processes events */ |
|
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)( |
|
+ CK_SESSION_HANDLE hSession, /* the session's handle */ |
|
+ CK_NOTIFICATION event, |
|
+ CK_VOID_PTR pApplication /* passed to C_OpenSession */ |
|
+); |
|
+ |
|
+ |
|
+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec |
|
+ * version and pointers of appropriate types to all the |
|
+ * Cryptoki functions */ |
|
+/* CK_FUNCTION_LIST is new for v2.0 */ |
|
+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST; |
|
+ |
|
+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR; |
|
+ |
|
+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR; |
|
+ |
|
+ |
|
+/* CK_CREATEMUTEX is an application callback for creating a |
|
+ * mutex object */ |
|
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)( |
|
+ CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */ |
|
+); |
|
+ |
|
+ |
|
+/* CK_DESTROYMUTEX is an application callback for destroying a |
|
+ * mutex object */ |
|
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)( |
|
+ CK_VOID_PTR pMutex /* pointer to mutex */ |
|
+); |
|
+ |
|
+ |
|
+/* CK_LOCKMUTEX is an application callback for locking a mutex */ |
|
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)( |
|
+ CK_VOID_PTR pMutex /* pointer to mutex */ |
|
+); |
|
+ |
|
+ |
|
+/* CK_UNLOCKMUTEX is an application callback for unlocking a |
|
+ * mutex */ |
|
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)( |
|
+ CK_VOID_PTR pMutex /* pointer to mutex */ |
|
+); |
|
+ |
|
+ |
|
+/* CK_C_INITIALIZE_ARGS provides the optional arguments to |
|
+ * C_Initialize */ |
|
+typedef struct CK_C_INITIALIZE_ARGS { |
|
+ CK_CREATEMUTEX CreateMutex; |
|
+ CK_DESTROYMUTEX DestroyMutex; |
|
+ CK_LOCKMUTEX LockMutex; |
|
+ CK_UNLOCKMUTEX UnlockMutex; |
|
+ CK_FLAGS flags; |
|
+ CK_VOID_PTR pReserved; |
|
+} CK_C_INITIALIZE_ARGS; |
|
+ |
|
+/* flags: bit flags that provide capabilities of the slot |
|
+ * Bit Flag Mask Meaning |
|
+ */ |
|
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001 |
|
+#define CKF_OS_LOCKING_OK 0x00000002 |
|
+ |
|
+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR; |
|
+ |
|
+ |
|
+/* additional flags for parameters to functions */ |
|
+ |
|
+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */ |
|
+#define CKF_DONT_BLOCK 1 |
|
+ |
|
+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10. |
|
+ * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message |
|
+ * Generation Function (MGF) applied to a message block when |
|
+ * formatting a message block for the PKCS #1 OAEP encryption |
|
+ * scheme. */ |
|
+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE; |
|
+ |
|
+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR; |
|
+ |
|
+/* The following MGFs are defined */ |
|
+/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512 |
|
+ * are new for v2.20 */ |
|
+#define CKG_MGF1_SHA1 0x00000001 |
|
+#define CKG_MGF1_SHA256 0x00000002 |
|
+#define CKG_MGF1_SHA384 0x00000003 |
|
+#define CKG_MGF1_SHA512 0x00000004 |
|
+/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */ |
|
+#define CKG_MGF1_SHA224 0x00000005 |
|
+ |
|
+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10. |
|
+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source |
|
+ * of the encoding parameter when formatting a message block |
|
+ * for the PKCS #1 OAEP encryption scheme. */ |
|
+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE; |
|
+ |
|
+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR; |
|
+ |
|
+/* The following encoding parameter sources are defined */ |
|
+#define CKZ_DATA_SPECIFIED 0x00000001 |
|
+ |
|
+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10. |
|
+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the |
|
+ * CKM_RSA_PKCS_OAEP mechanism. */ |
|
+typedef struct CK_RSA_PKCS_OAEP_PARAMS { |
|
+ CK_MECHANISM_TYPE hashAlg; |
|
+ CK_RSA_PKCS_MGF_TYPE mgf; |
|
+ CK_RSA_PKCS_OAEP_SOURCE_TYPE source; |
|
+ CK_VOID_PTR pSourceData; |
|
+ CK_ULONG ulSourceDataLen; |
|
+} CK_RSA_PKCS_OAEP_PARAMS; |
|
+ |
|
+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR; |
|
+ |
|
+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11. |
|
+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the |
|
+ * CKM_RSA_PKCS_PSS mechanism(s). */ |
|
+typedef struct CK_RSA_PKCS_PSS_PARAMS { |
|
+ CK_MECHANISM_TYPE hashAlg; |
|
+ CK_RSA_PKCS_MGF_TYPE mgf; |
|
+ CK_ULONG sLen; |
|
+} CK_RSA_PKCS_PSS_PARAMS; |
|
+ |
|
+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR; |
|
+ |
|
+/* CK_EC_KDF_TYPE is new for v2.11. */ |
|
+typedef CK_ULONG CK_EC_KDF_TYPE; |
|
+ |
|
+/* The following EC Key Derivation Functions are defined */ |
|
+#define CKD_NULL 0x00000001 |
|
+#define CKD_SHA1_KDF 0x00000002 |
|
+ |
|
+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11. |
|
+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the |
|
+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms, |
|
+ * where each party contributes one key pair. |
|
+ */ |
|
+typedef struct CK_ECDH1_DERIVE_PARAMS { |
|
+ CK_EC_KDF_TYPE kdf; |
|
+ CK_ULONG ulSharedDataLen; |
|
+ CK_BYTE_PTR pSharedData; |
|
+ CK_ULONG ulPublicDataLen; |
|
+ CK_BYTE_PTR pPublicData; |
|
+} CK_ECDH1_DERIVE_PARAMS; |
|
+ |
|
+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR; |
|
+ |
|
+ |
|
+/* CK_ECDH2_DERIVE_PARAMS is new for v2.11. |
|
+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the |
|
+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */ |
|
+typedef struct CK_ECDH2_DERIVE_PARAMS { |
|
+ CK_EC_KDF_TYPE kdf; |
|
+ CK_ULONG ulSharedDataLen; |
|
+ CK_BYTE_PTR pSharedData; |
|
+ CK_ULONG ulPublicDataLen; |
|
+ CK_BYTE_PTR pPublicData; |
|
+ CK_ULONG ulPrivateDataLen; |
|
+ CK_OBJECT_HANDLE hPrivateData; |
|
+ CK_ULONG ulPublicDataLen2; |
|
+ CK_BYTE_PTR pPublicData2; |
|
+} CK_ECDH2_DERIVE_PARAMS; |
|
+ |
|
+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR; |
|
+ |
|
+typedef struct CK_ECMQV_DERIVE_PARAMS { |
|
+ CK_EC_KDF_TYPE kdf; |
|
+ CK_ULONG ulSharedDataLen; |
|
+ CK_BYTE_PTR pSharedData; |
|
+ CK_ULONG ulPublicDataLen; |
|
+ CK_BYTE_PTR pPublicData; |
|
+ CK_ULONG ulPrivateDataLen; |
|
+ CK_OBJECT_HANDLE hPrivateData; |
|
+ CK_ULONG ulPublicDataLen2; |
|
+ CK_BYTE_PTR pPublicData2; |
|
+ CK_OBJECT_HANDLE publicKey; |
|
+} CK_ECMQV_DERIVE_PARAMS; |
|
+ |
|
+typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR; |
|
+ |
|
+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the |
|
+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */ |
|
+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE; |
|
+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR; |
|
+ |
|
+/* The following X9.42 DH key derivation functions are defined |
|
+ (besides CKD_NULL already defined : */ |
|
+#define CKD_SHA1_KDF_ASN1 0x00000003 |
|
+#define CKD_SHA1_KDF_CONCATENATE 0x00000004 |
|
+ |
|
+/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11. |
|
+ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the |
|
+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party |
|
+ * contributes one key pair */ |
|
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS { |
|
+ CK_X9_42_DH_KDF_TYPE kdf; |
|
+ CK_ULONG ulOtherInfoLen; |
|
+ CK_BYTE_PTR pOtherInfo; |
|
+ CK_ULONG ulPublicDataLen; |
|
+ CK_BYTE_PTR pPublicData; |
|
+} CK_X9_42_DH1_DERIVE_PARAMS; |
|
+ |
|
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR; |
|
+ |
|
+/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11. |
|
+ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the |
|
+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation |
|
+ * mechanisms, where each party contributes two key pairs */ |
|
+typedef struct CK_X9_42_DH2_DERIVE_PARAMS { |
|
+ CK_X9_42_DH_KDF_TYPE kdf; |
|
+ CK_ULONG ulOtherInfoLen; |
|
+ CK_BYTE_PTR pOtherInfo; |
|
+ CK_ULONG ulPublicDataLen; |
|
+ CK_BYTE_PTR pPublicData; |
|
+ CK_ULONG ulPrivateDataLen; |
|
+ CK_OBJECT_HANDLE hPrivateData; |
|
+ CK_ULONG ulPublicDataLen2; |
|
+ CK_BYTE_PTR pPublicData2; |
|
+} CK_X9_42_DH2_DERIVE_PARAMS; |
|
+ |
|
+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR; |
|
+ |
|
+typedef struct CK_X9_42_MQV_DERIVE_PARAMS { |
|
+ CK_X9_42_DH_KDF_TYPE kdf; |
|
+ CK_ULONG ulOtherInfoLen; |
|
+ CK_BYTE_PTR pOtherInfo; |
|
+ CK_ULONG ulPublicDataLen; |
|
+ CK_BYTE_PTR pPublicData; |
|
+ CK_ULONG ulPrivateDataLen; |
|
+ CK_OBJECT_HANDLE hPrivateData; |
|
+ CK_ULONG ulPublicDataLen2; |
|
+ CK_BYTE_PTR pPublicData2; |
|
+ CK_OBJECT_HANDLE publicKey; |
|
+} CK_X9_42_MQV_DERIVE_PARAMS; |
|
+ |
|
+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR; |
|
+ |
|
+/* CK_KEA_DERIVE_PARAMS provides the parameters to the |
|
+ * CKM_KEA_DERIVE mechanism */ |
|
+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */ |
|
+typedef struct CK_KEA_DERIVE_PARAMS { |
|
+ CK_BBOOL isSender; |
|
+ CK_ULONG ulRandomLen; |
|
+ CK_BYTE_PTR pRandomA; |
|
+ CK_BYTE_PTR pRandomB; |
|
+ CK_ULONG ulPublicDataLen; |
|
+ CK_BYTE_PTR pPublicData; |
|
+} CK_KEA_DERIVE_PARAMS; |
|
+ |
|
+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR; |
|
+ |
|
+ |
|
+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and |
|
+ * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just |
|
+ * holds the effective keysize */ |
|
+typedef CK_ULONG CK_RC2_PARAMS; |
|
+ |
|
+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR; |
|
+ |
|
+ |
|
+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC |
|
+ * mechanism */ |
|
+typedef struct CK_RC2_CBC_PARAMS { |
|
+ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for |
|
+ * v2.0 */ |
|
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ |
|
+ |
|
+ CK_BYTE iv[8]; /* IV for CBC mode */ |
|
+} CK_RC2_CBC_PARAMS; |
|
+ |
|
+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR; |
|
+ |
|
+ |
|
+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the |
|
+ * CKM_RC2_MAC_GENERAL mechanism */ |
|
+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */ |
|
+typedef struct CK_RC2_MAC_GENERAL_PARAMS { |
|
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */ |
|
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */ |
|
+} CK_RC2_MAC_GENERAL_PARAMS; |
|
+ |
|
+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \ |
|
+ CK_RC2_MAC_GENERAL_PARAMS_PTR; |
|
+ |
|
+ |
|
+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and |
|
+ * CKM_RC5_MAC mechanisms */ |
|
+/* CK_RC5_PARAMS is new for v2.0 */ |
|
+typedef struct CK_RC5_PARAMS { |
|
+ CK_ULONG ulWordsize; /* wordsize in bits */ |
|
+ CK_ULONG ulRounds; /* number of rounds */ |
|
+} CK_RC5_PARAMS; |
|
+ |
|
+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR; |
|
+ |
|
+ |
|
+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC |
|
+ * mechanism */ |
|
+/* CK_RC5_CBC_PARAMS is new for v2.0 */ |
|
+typedef struct CK_RC5_CBC_PARAMS { |
|
+ CK_ULONG ulWordsize; /* wordsize in bits */ |
|
+ CK_ULONG ulRounds; /* number of rounds */ |
|
+ CK_BYTE_PTR pIv; /* pointer to IV */ |
|
+ CK_ULONG ulIvLen; /* length of IV in bytes */ |
|
+} CK_RC5_CBC_PARAMS; |
|
+ |
|
+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR; |
|
+ |
|
+ |
|
+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the |
|
+ * CKM_RC5_MAC_GENERAL mechanism */ |
|
+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */ |
|
+typedef struct CK_RC5_MAC_GENERAL_PARAMS { |
|
+ CK_ULONG ulWordsize; /* wordsize in bits */ |
|
+ CK_ULONG ulRounds; /* number of rounds */ |
|
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */ |
|
+} CK_RC5_MAC_GENERAL_PARAMS; |
|
+ |
|
+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \ |
|
+ CK_RC5_MAC_GENERAL_PARAMS_PTR; |
|
+ |
|
+ |
|
+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block |
|
+ * ciphers' MAC_GENERAL mechanisms. Its value is the length of |
|
+ * the MAC */ |
|
+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */ |
|
+typedef CK_ULONG CK_MAC_GENERAL_PARAMS; |
|
+ |
|
+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR; |
|
+ |
|
+/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */ |
|
+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS { |
|
+ CK_BYTE iv[8]; |
|
+ CK_BYTE_PTR pData; |
|
+ CK_ULONG length; |
|
+} CK_DES_CBC_ENCRYPT_DATA_PARAMS; |
|
+ |
|
+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR; |
|
+ |
|
+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS { |
|
+ CK_BYTE iv[16]; |
|
+ CK_BYTE_PTR pData; |
|
+ CK_ULONG length; |
|
+} CK_AES_CBC_ENCRYPT_DATA_PARAMS; |
|
+ |
|
+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR; |
|
+ |
|
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the |
|
+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */ |
|
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */ |
|
+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS { |
|
+ CK_ULONG ulPasswordLen; |
|
+ CK_BYTE_PTR pPassword; |
|
+ CK_ULONG ulPublicDataLen; |
|
+ CK_BYTE_PTR pPublicData; |
|
+ CK_ULONG ulPAndGLen; |
|
+ CK_ULONG ulQLen; |
|
+ CK_ULONG ulRandomLen; |
|
+ CK_BYTE_PTR pRandomA; |
|
+ CK_BYTE_PTR pPrimeP; |
|
+ CK_BYTE_PTR pBaseG; |
|
+ CK_BYTE_PTR pSubprimeQ; |
|
+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS; |
|
+ |
|
+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \ |
|
+ CK_SKIPJACK_PRIVATE_WRAP_PTR; |
|
+ |
|
+ |
|
+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the |
|
+ * CKM_SKIPJACK_RELAYX mechanism */ |
|
+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */ |
|
+typedef struct CK_SKIPJACK_RELAYX_PARAMS { |
|
+ CK_ULONG ulOldWrappedXLen; |
|
+ CK_BYTE_PTR pOldWrappedX; |
|
+ CK_ULONG ulOldPasswordLen; |
|
+ CK_BYTE_PTR pOldPassword; |
|
+ CK_ULONG ulOldPublicDataLen; |
|
+ CK_BYTE_PTR pOldPublicData; |
|
+ CK_ULONG ulOldRandomLen; |
|
+ CK_BYTE_PTR pOldRandomA; |
|
+ CK_ULONG ulNewPasswordLen; |
|
+ CK_BYTE_PTR pNewPassword; |
|
+ CK_ULONG ulNewPublicDataLen; |
|
+ CK_BYTE_PTR pNewPublicData; |
|
+ CK_ULONG ulNewRandomLen; |
|
+ CK_BYTE_PTR pNewRandomA; |
|
+} CK_SKIPJACK_RELAYX_PARAMS; |
|
+ |
|
+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \ |
|
+ CK_SKIPJACK_RELAYX_PARAMS_PTR; |
|
+ |
|
+ |
|
+typedef struct CK_PBE_PARAMS { |
|
+ CK_BYTE_PTR pInitVector; |
|
+ CK_UTF8CHAR_PTR pPassword; |
|
+ CK_ULONG ulPasswordLen; |
|
+ CK_BYTE_PTR pSalt; |
|
+ CK_ULONG ulSaltLen; |
|
+ CK_ULONG ulIteration; |
|
+} CK_PBE_PARAMS; |
|
+ |
|
+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR; |
|
+ |
|
+ |
|
+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the |
|
+ * CKM_KEY_WRAP_SET_OAEP mechanism */ |
|
+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */ |
|
+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS { |
|
+ CK_BYTE bBC; /* block contents byte */ |
|
+ CK_BYTE_PTR pX; /* extra data */ |
|
+ CK_ULONG ulXLen; /* length of extra data in bytes */ |
|
+} CK_KEY_WRAP_SET_OAEP_PARAMS; |
|
+ |
|
+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \ |
|
+ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR; |
|
+ |
|
+ |
|
+typedef struct CK_SSL3_RANDOM_DATA { |
|
+ CK_BYTE_PTR pClientRandom; |
|
+ CK_ULONG ulClientRandomLen; |
|
+ CK_BYTE_PTR pServerRandom; |
|
+ CK_ULONG ulServerRandomLen; |
|
+} CK_SSL3_RANDOM_DATA; |
|
+ |
|
+ |
|
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS { |
|
+ CK_SSL3_RANDOM_DATA RandomInfo; |
|
+ CK_VERSION_PTR pVersion; |
|
+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS; |
|
+ |
|
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \ |
|
+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR; |
|
+ |
|
+ |
|
+typedef struct CK_SSL3_KEY_MAT_OUT { |
|
+ CK_OBJECT_HANDLE hClientMacSecret; |
|
+ CK_OBJECT_HANDLE hServerMacSecret; |
|
+ CK_OBJECT_HANDLE hClientKey; |
|
+ CK_OBJECT_HANDLE hServerKey; |
|
+ CK_BYTE_PTR pIVClient; |
|
+ CK_BYTE_PTR pIVServer; |
|
+} CK_SSL3_KEY_MAT_OUT; |
|
+ |
|
+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR; |
|
+ |
|
+ |
|
+typedef struct CK_SSL3_KEY_MAT_PARAMS { |
|
+ CK_ULONG ulMacSizeInBits; |
|
+ CK_ULONG ulKeySizeInBits; |
|
+ CK_ULONG ulIVSizeInBits; |
|
+ CK_BBOOL bIsExport; |
|
+ CK_SSL3_RANDOM_DATA RandomInfo; |
|
+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial; |
|
+} CK_SSL3_KEY_MAT_PARAMS; |
|
+ |
|
+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR; |
|
+ |
|
+/* CK_TLS_PRF_PARAMS is new for version 2.20 */ |
|
+typedef struct CK_TLS_PRF_PARAMS { |
|
+ CK_BYTE_PTR pSeed; |
|
+ CK_ULONG ulSeedLen; |
|
+ CK_BYTE_PTR pLabel; |
|
+ CK_ULONG ulLabelLen; |
|
+ CK_BYTE_PTR pOutput; |
|
+ CK_ULONG_PTR pulOutputLen; |
|
+} CK_TLS_PRF_PARAMS; |
|
+ |
|
+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR; |
|
+ |
|
+/* WTLS is new for version 2.20 */ |
|
+typedef struct CK_WTLS_RANDOM_DATA { |
|
+ CK_BYTE_PTR pClientRandom; |
|
+ CK_ULONG ulClientRandomLen; |
|
+ CK_BYTE_PTR pServerRandom; |
|
+ CK_ULONG ulServerRandomLen; |
|
+} CK_WTLS_RANDOM_DATA; |
|
+ |
|
+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR; |
|
+ |
|
+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS { |
|
+ CK_MECHANISM_TYPE DigestMechanism; |
|
+ CK_WTLS_RANDOM_DATA RandomInfo; |
|
+ CK_BYTE_PTR pVersion; |
|
+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS; |
|
+ |
|
+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \ |
|
+ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR; |
|
+ |
|
+typedef struct CK_WTLS_PRF_PARAMS { |
|
+ CK_MECHANISM_TYPE DigestMechanism; |
|
+ CK_BYTE_PTR pSeed; |
|
+ CK_ULONG ulSeedLen; |
|
+ CK_BYTE_PTR pLabel; |
|
+ CK_ULONG ulLabelLen; |
|
+ CK_BYTE_PTR pOutput; |
|
+ CK_ULONG_PTR pulOutputLen; |
|
+} CK_WTLS_PRF_PARAMS; |
|
+ |
|
+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR; |
|
+ |
|
+typedef struct CK_WTLS_KEY_MAT_OUT { |
|
+ CK_OBJECT_HANDLE hMacSecret; |
|
+ CK_OBJECT_HANDLE hKey; |
|
+ CK_BYTE_PTR pIV; |
|
+} CK_WTLS_KEY_MAT_OUT; |
|
+ |
|
+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR; |
|
+ |
|
+typedef struct CK_WTLS_KEY_MAT_PARAMS { |
|
+ CK_MECHANISM_TYPE DigestMechanism; |
|
+ CK_ULONG ulMacSizeInBits; |
|
+ CK_ULONG ulKeySizeInBits; |
|
+ CK_ULONG ulIVSizeInBits; |
|
+ CK_ULONG ulSequenceNumber; |
|
+ CK_BBOOL bIsExport; |
|
+ CK_WTLS_RANDOM_DATA RandomInfo; |
|
+ CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial; |
|
+} CK_WTLS_KEY_MAT_PARAMS; |
|
+ |
|
+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR; |
|
+ |
|
+/* CMS is new for version 2.20 */ |
|
+typedef struct CK_CMS_SIG_PARAMS { |
|
+ CK_OBJECT_HANDLE certificateHandle; |
|
+ CK_MECHANISM_PTR pSigningMechanism; |
|
+ CK_MECHANISM_PTR pDigestMechanism; |
|
+ CK_UTF8CHAR_PTR pContentType; |
|
+ CK_BYTE_PTR pRequestedAttributes; |
|
+ CK_ULONG ulRequestedAttributesLen; |
|
+ CK_BYTE_PTR pRequiredAttributes; |
|
+ CK_ULONG ulRequiredAttributesLen; |
|
+} CK_CMS_SIG_PARAMS; |
|
+ |
|
+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR; |
|
+ |
|
+typedef struct CK_KEY_DERIVATION_STRING_DATA { |
|
+ CK_BYTE_PTR pData; |
|
+ CK_ULONG ulLen; |
|
+} CK_KEY_DERIVATION_STRING_DATA; |
|
+ |
|
+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \ |
|
+ CK_KEY_DERIVATION_STRING_DATA_PTR; |
|
+ |
|
+ |
|
+/* The CK_EXTRACT_PARAMS is used for the |
|
+ * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit |
|
+ * of the base key should be used as the first bit of the |
|
+ * derived key */ |
|
+/* CK_EXTRACT_PARAMS is new for v2.0 */ |
|
+typedef CK_ULONG CK_EXTRACT_PARAMS; |
|
+ |
|
+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR; |
|
+ |
|
+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10. |
|
+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to |
|
+ * indicate the Pseudo-Random Function (PRF) used to generate |
|
+ * key bits using PKCS #5 PBKDF2. */ |
|
+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE; |
|
+ |
|
+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR; |
|
+ |
|
+/* The following PRFs are defined in PKCS #5 v2.0. */ |
|
+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001 |
|
+ |
|
+ |
|
+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10. |
|
+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the |
|
+ * source of the salt value when deriving a key using PKCS #5 |
|
+ * PBKDF2. */ |
|
+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE; |
|
+ |
|
+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR; |
|
+ |
|
+/* The following salt value sources are defined in PKCS #5 v2.0. */ |
|
+#define CKZ_SALT_SPECIFIED 0x00000001 |
|
+ |
|
+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10. |
|
+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the |
|
+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */ |
|
+typedef struct CK_PKCS5_PBKD2_PARAMS { |
|
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource; |
|
+ CK_VOID_PTR pSaltSourceData; |
|
+ CK_ULONG ulSaltSourceDataLen; |
|
+ CK_ULONG iterations; |
|
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf; |
|
+ CK_VOID_PTR pPrfData; |
|
+ CK_ULONG ulPrfDataLen; |
|
+ CK_UTF8CHAR_PTR pPassword; |
|
+ CK_ULONG_PTR ulPasswordLen; |
|
+} CK_PKCS5_PBKD2_PARAMS; |
|
+ |
|
+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR; |
|
+ |
|
+/* All CK_OTP structs are new for PKCS #11 v2.20 amendment 3 */ |
|
+ |
|
+typedef CK_ULONG CK_OTP_PARAM_TYPE; |
|
+typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* B/w compatibility */ |
|
+ |
|
+typedef struct CK_OTP_PARAM { |
|
+ CK_OTP_PARAM_TYPE type; |
|
+ CK_VOID_PTR pValue; |
|
+ CK_ULONG ulValueLen; |
|
+} CK_OTP_PARAM; |
|
+ |
|
+typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR; |
|
+ |
|
+typedef struct CK_OTP_PARAMS { |
|
+ CK_OTP_PARAM_PTR pParams; |
|
+ CK_ULONG ulCount; |
|
+} CK_OTP_PARAMS; |
|
+ |
|
+typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR; |
|
+ |
|
+typedef struct CK_OTP_SIGNATURE_INFO { |
|
+ CK_OTP_PARAM_PTR pParams; |
|
+ CK_ULONG ulCount; |
|
+} CK_OTP_SIGNATURE_INFO; |
|
+ |
|
+typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR; |
|
+ |
|
+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */ |
|
+#define CK_OTP_VALUE 0 |
|
+#define CK_OTP_PIN 1 |
|
+#define CK_OTP_CHALLENGE 2 |
|
+#define CK_OTP_TIME 3 |
|
+#define CK_OTP_COUNTER 4 |
|
+#define CK_OTP_FLAGS 5 |
|
+#define CK_OTP_OUTPUT_LENGTH 6 |
|
+#define CK_OTP_OUTPUT_FORMAT 7 |
|
+ |
|
+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */ |
|
+#define CKF_NEXT_OTP 0x00000001 |
|
+#define CKF_EXCLUDE_TIME 0x00000002 |
|
+#define CKF_EXCLUDE_COUNTER 0x00000004 |
|
+#define CKF_EXCLUDE_CHALLENGE 0x00000008 |
|
+#define CKF_EXCLUDE_PIN 0x00000010 |
|
+#define CKF_USER_FRIENDLY_OTP 0x00000020 |
|
+ |
|
+/* CK_KIP_PARAMS is new for PKCS #11 v2.20 amendment 2 */ |
|
+typedef struct CK_KIP_PARAMS { |
|
+ CK_MECHANISM_PTR pMechanism; |
|
+ CK_OBJECT_HANDLE hKey; |
|
+ CK_BYTE_PTR pSeed; |
|
+ CK_ULONG ulSeedLen; |
|
+} CK_KIP_PARAMS; |
|
+ |
|
+typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR; |
|
+ |
|
+/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */ |
|
+typedef struct CK_AES_CTR_PARAMS { |
|
+ CK_ULONG ulCounterBits; |
|
+ CK_BYTE cb[16]; |
|
+} CK_AES_CTR_PARAMS; |
|
+ |
|
+typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR; |
|
+ |
|
+/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */ |
|
+typedef struct CK_CAMELLIA_CTR_PARAMS { |
|
+ CK_ULONG ulCounterBits; |
|
+ CK_BYTE cb[16]; |
|
+} CK_CAMELLIA_CTR_PARAMS; |
|
+ |
|
+typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR; |
|
+ |
|
+/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */ |
|
+typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS { |
|
+ CK_BYTE iv[16]; |
|
+ CK_BYTE_PTR pData; |
|
+ CK_ULONG length; |
|
+} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS; |
|
+ |
|
+typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR; |
|
+ |
|
+/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */ |
|
+typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS { |
|
+ CK_BYTE iv[16]; |
|
+ CK_BYTE_PTR pData; |
|
+ CK_ULONG length; |
|
+} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS; |
|
+ |
|
+typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR; |
|
+ |
|
+#endif |
|
diff --git a/lib/isc/md5.c b/lib/isc/md5.c |
|
index 7c6419b..2e3cf9a 100644 |
|
--- a/lib/isc/md5.c |
|
+++ b/lib/isc/md5.c |
|
@@ -41,6 +41,12 @@ |
|
#include <isc/platform.h> |
|
#include <isc/string.h> |
|
#include <isc/types.h> |
|
+ |
|
+#if PKCS11CRYPTO |
|
+#include <pk11/internal.h> |
|
+#include <pk11/pk11.h> |
|
+#endif |
|
+ |
|
#include <isc/util.h> |
|
|
|
#ifdef ISC_PLATFORM_OPENSSLHASH |
|
@@ -65,6 +71,50 @@ isc_md5_final(isc_md5_t *ctx, unsigned char *digest) { |
|
EVP_DigestFinal(ctx, digest, NULL); |
|
} |
|
|
|
+#elif PKCS11CRYPTO |
|
+ |
|
+void |
|
+isc_md5_init(isc_md5_t *ctx) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_MD5, NULL, 0 }; |
|
+ |
|
+ RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech)); |
|
+} |
|
+ |
|
+void |
|
+isc_md5_invalidate(isc_md5_t *ctx) { |
|
+ CK_BYTE garbage[ISC_MD5_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_MD5_DIGESTLENGTH; |
|
+ |
|
+ if (ctx->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_DigestFinal(ctx->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
+void |
|
+isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) { |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ DE_CONST(buf, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_DigestUpdate, |
|
+ (ctx->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_md5_final(isc_md5_t *ctx, unsigned char *digest) { |
|
+ CK_RV rv; |
|
+ CK_ULONG len = ISC_MD5_DIGESTLENGTH; |
|
+ |
|
+ PK11_FATALCHECK(pkcs_C_DigestFinal, |
|
+ (ctx->session, (CK_BYTE_PTR) digest, &len)); |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
#else |
|
|
|
static void |
|
diff --git a/lib/isc/pk11.c b/lib/isc/pk11.c |
|
new file mode 100644 |
|
index 0000000..015bff2 |
|
--- /dev/null |
|
+++ b/lib/isc/pk11.c |
|
@@ -0,0 +1,1327 @@ |
|
+/* |
|
+ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Portions copyright (c) 2008 Nominet UK. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in the |
|
+ * documentation and/or other materials provided with the distribution. |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
|
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
|
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
|
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ */ |
|
+ |
|
+/* |
|
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved. |
|
+ * Use is subject to license terms. |
|
+ */ |
|
+ |
|
+/* |
|
+ * This product includes software developed by the OpenSSL Project for |
|
+ * use in the OpenSSL Toolkit (http://www.openssl.org/). |
|
+ * |
|
+ * This project also referenced hw_pkcs11-0.9.7b.patch written by |
|
+ * Afchine Madjlessi. |
|
+ */ |
|
+/* |
|
+ * ==================================================================== |
|
+ * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved. |
|
+ * |
|
+ * Redistribution and use in source and binary forms, with or without |
|
+ * modification, are permitted provided that the following conditions |
|
+ * are met: |
|
+ * |
|
+ * 1. Redistributions of source code must retain the above copyright |
|
+ * notice, this list of conditions and the following disclaimer. |
|
+ * |
|
+ * 2. Redistributions in binary form must reproduce the above copyright |
|
+ * notice, this list of conditions and the following disclaimer in |
|
+ * the documentation and/or other materials provided with the |
|
+ * distribution. |
|
+ * |
|
+ * 3. All advertising materials mentioning features or use of this |
|
+ * software must display the following acknowledgment: |
|
+ * "This product includes software developed by the OpenSSL Project |
|
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" |
|
+ * |
|
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
|
+ * endorse or promote products derived from this software without |
|
+ * prior written permission. For written permission, please contact |
|
+ * licensing@OpenSSL.org. |
|
+ * |
|
+ * 5. Products derived from this software may not be called "OpenSSL" |
|
+ * nor may "OpenSSL" appear in their names without prior written |
|
+ * permission of the OpenSSL Project. |
|
+ * |
|
+ * 6. Redistributions of any form whatsoever must retain the following |
|
+ * acknowledgment: |
|
+ * "This product includes software developed by the OpenSSL Project |
|
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" |
|
+ * |
|
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
|
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
|
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
|
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
|
+ * OF THE POSSIBILITY OF SUCH DAMAGE. |
|
+ * ==================================================================== |
|
+ * |
|
+ * This product includes cryptographic software written by Eric Young |
|
+ * (eay@cryptsoft.com). This product includes software written by Tim |
|
+ * Hudson (tjh@cryptsoft.com). |
|
+ * |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+ |
|
+#include <isc/log.h> |
|
+#include <isc/mem.h> |
|
+#include <isc/once.h> |
|
+#include <isc/platform.h> |
|
+#include <isc/stdio.h> |
|
+#include <isc/thread.h> |
|
+#include <isc/util.h> |
|
+ |
|
+#include <dst/result.h> |
|
+ |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/internal.h> |
|
+#include <pk11/result.h> |
|
+ |
|
+#include <pkcs11/cryptoki.h> |
|
+#include <pkcs11/pkcs11.h> |
|
+ |
|
+#define PINLEN 32 |
|
+ |
|
+#ifndef PK11_NO_LOGERR |
|
+#define PK11_NO_LOGERR 1 |
|
+#endif |
|
+ |
|
+static isc_once_t once = ISC_ONCE_INIT; |
|
+static isc_mem_t *pk11_mctx = NULL; |
|
+static isc_int32_t allocsize = 0; |
|
+static isc_boolean_t initialized = ISC_FALSE; |
|
+ |
|
+typedef struct pk11_session pk11_session_t; |
|
+typedef struct pk11_token pk11_token_t; |
|
+typedef ISC_LIST(pk11_session_t) pk11_sessionlist_t; |
|
+ |
|
+struct pk11_session { |
|
+ unsigned int magic; |
|
+ CK_SESSION_HANDLE session; |
|
+ ISC_LINK(pk11_session_t) link; |
|
+ pk11_token_t *token; |
|
+}; |
|
+ |
|
+struct pk11_token { |
|
+ unsigned int magic; |
|
+ unsigned int operations; |
|
+ ISC_LINK(pk11_token_t) link; |
|
+ CK_SLOT_ID slotid; |
|
+ pk11_sessionlist_t sessions; |
|
+ isc_boolean_t logged; |
|
+ char name[32]; |
|
+ char manuf[32]; |
|
+ char model[16]; |
|
+ char serial[16]; |
|
+ char pin[PINLEN]; |
|
+}; |
|
+static ISC_LIST(pk11_token_t) tokens; |
|
+ |
|
+static pk11_token_t *rand_token; |
|
+static pk11_token_t *best_rsa_token; |
|
+static pk11_token_t *best_dsa_token; |
|
+static pk11_token_t *best_dh_token; |
|
+static pk11_token_t *digest_token; |
|
+static pk11_token_t *best_ec_token; |
|
+static pk11_token_t *best_gost_token; |
|
+static pk11_token_t *aes_token; |
|
+ |
|
+static isc_result_t free_all_sessions(void); |
|
+static isc_result_t free_session_list(pk11_sessionlist_t *slist); |
|
+static isc_result_t setup_session(pk11_session_t *sp, |
|
+ pk11_token_t *token, |
|
+ isc_boolean_t rw); |
|
+static void choose_slots(void); |
|
+static isc_result_t token_login(pk11_session_t *sp); |
|
+static char *percent_decode(char *x, size_t *len); |
|
+static isc_boolean_t pk11strcmp(const char *x, size_t lenx, |
|
+ const char *y, size_t leny); |
|
+static CK_ATTRIBUTE *push_attribute(pk11_object_t *obj, |
|
+ isc_mem_t *mctx, |
|
+ size_t len); |
|
+ |
|
+static isc_mutex_t alloclock; |
|
+static isc_mutex_t sessionlock; |
|
+ |
|
+static pk11_sessionlist_t actives; |
|
+ |
|
+static CK_C_INITIALIZE_ARGS pk11_init_args = { |
|
+ NULL_PTR, /* CreateMutex */ |
|
+ NULL_PTR, /* DestroyMutex */ |
|
+ NULL_PTR, /* LockMutex */ |
|
+ NULL_PTR, /* UnlockMutex */ |
|
+ CKF_OS_LOCKING_OK, /* flags */ |
|
+ NULL_PTR, /* pReserved */ |
|
+}; |
|
+ |
|
+#ifndef PK11_LIB_LOCATION |
|
+#define PK11_LIB_LOCATION "unknown_provider" |
|
+#endif |
|
+ |
|
+#ifndef WIN32 |
|
+static const char *lib_name = PK11_LIB_LOCATION; |
|
+#else |
|
+static const char *lib_name = PK11_LIB_LOCATION ".dll"; |
|
+#endif |
|
+ |
|
+void |
|
+pk11_set_lib_name(const char *name) { |
|
+ lib_name = name; |
|
+} |
|
+ |
|
+const char * |
|
+pk11_get_lib_name(void) { |
|
+ return (lib_name); |
|
+} |
|
+ |
|
+static void |
|
+initialize(void) { |
|
+ char *pk11_provider; |
|
+ |
|
+ RUNTIME_CHECK(isc_mutex_init(&alloclock) == ISC_R_SUCCESS); |
|
+ RUNTIME_CHECK(isc_mutex_init(&sessionlock) == ISC_R_SUCCESS); |
|
+ |
|
+ pk11_provider = getenv("PKCS11_PROVIDER"); |
|
+ if (pk11_provider != NULL) |
|
+ lib_name = pk11_provider; |
|
+} |
|
+ |
|
+void * |
|
+pk11_mem_get(size_t size) { |
|
+ void *ptr; |
|
+ |
|
+ LOCK(&alloclock); |
|
+ if (pk11_mctx != NULL) |
|
+ ptr = isc_mem_get(pk11_mctx, size); |
|
+ else { |
|
+ ptr = malloc(size); |
|
+ if (ptr != NULL) |
|
+ allocsize += (int)size; |
|
+ } |
|
+ UNLOCK(&alloclock); |
|
+ |
|
+ if (ptr != NULL) |
|
+ memset(ptr, 0, size); |
|
+ return (ptr); |
|
+} |
|
+ |
|
+void |
|
+pk11_mem_put(void *ptr, size_t size) { |
|
+ if (ptr != NULL) |
|
+ memset(ptr, 0, size); |
|
+ LOCK(&alloclock); |
|
+ if (pk11_mctx != NULL) |
|
+ isc_mem_put(pk11_mctx, ptr, size); |
|
+ else { |
|
+ if (ptr != NULL) |
|
+ allocsize -= (int)size; |
|
+ free(ptr); |
|
+ } |
|
+ UNLOCK(&alloclock); |
|
+} |
|
+ |
|
+isc_result_t |
|
+pk11_initialize(isc_mem_t *mctx, const char *engine) { |
|
+ isc_result_t result; |
|
+ CK_RV rv; |
|
+ |
|
+ RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS); |
|
+ |
|
+ LOCK(&alloclock); |
|
+ if ((mctx != NULL) && (pk11_mctx == NULL) && (allocsize == 0)) |
|
+ isc_mem_attach(mctx, &pk11_mctx); |
|
+ if (initialized) { |
|
+ UNLOCK(&alloclock); |
|
+ return (ISC_R_SUCCESS); |
|
+ } else { |
|
+ LOCK(&sessionlock); |
|
+ initialized = ISC_TRUE; |
|
+ UNLOCK(&alloclock); |
|
+ } |
|
+ |
|
+ ISC_LIST_INIT(tokens); |
|
+ ISC_LIST_INIT(actives); |
|
+ |
|
+ if (engine != NULL) |
|
+ lib_name = engine; |
|
+ |
|
+ /* Initialize the CRYPTOKI library */ |
|
+ rv = pkcs_C_Initialize((CK_VOID_PTR) &pk11_init_args); |
|
+ |
|
+ if (rv == 0xfe) { |
|
+ result = PK11_R_NOPROVIDER; |
|
+ goto unlock; |
|
+ } |
|
+ if (rv != CKR_OK) { |
|
+ result = PK11_R_INITFAILED; |
|
+ goto unlock; |
|
+ } |
|
+ |
|
+ choose_slots(); |
|
+#ifdef PKCS11CRYPTO |
|
+ if (rand_token == NULL) { |
|
+ result = PK11_R_NORANDOMSERVICE; |
|
+ goto unlock; |
|
+ } |
|
+ if (digest_token == NULL) { |
|
+ result = PK11_R_NODIGESTSERVICE; |
|
+ goto unlock; |
|
+ } |
|
+#if defined(ISC_PLATFORM_USESIT) && defined(AES_SIT) |
|
+ if (aes_token == NULL) { |
|
+ result = PK11_R_NOAESSERVICE; |
|
+ goto unlock; |
|
+ } |
|
+#endif |
|
+#endif /* PKCS11CRYPTO */ |
|
+ result = ISC_R_SUCCESS; |
|
+ unlock: |
|
+ UNLOCK(&sessionlock); |
|
+ return (result); |
|
+} |
|
+ |
|
+isc_result_t |
|
+pk11_finalize(void) { |
|
+ pk11_token_t *token, *next; |
|
+ isc_result_t ret; |
|
+ |
|
+ ret = free_all_sessions(); |
|
+ (void) pkcs_C_Finalize(NULL_PTR); |
|
+ token = ISC_LIST_HEAD(tokens); |
|
+ while (token != NULL) { |
|
+ next = ISC_LIST_NEXT(token, link); |
|
+ ISC_LIST_UNLINK(tokens, token, link); |
|
+ if (token == rand_token) |
|
+ rand_token = NULL; |
|
+ if (token == best_rsa_token) |
|
+ best_rsa_token = NULL; |
|
+ if (token == best_dsa_token) |
|
+ best_dsa_token = NULL; |
|
+ if (token == best_dh_token) |
|
+ best_dh_token = NULL; |
|
+ if (token == digest_token) |
|
+ digest_token = NULL; |
|
+ if (token == best_ec_token) |
|
+ best_ec_token = NULL; |
|
+ if (token == best_gost_token) |
|
+ best_gost_token = NULL; |
|
+ if (token == aes_token) |
|
+ aes_token = NULL; |
|
+ pk11_mem_put(token, sizeof(*token)); |
|
+ token = next; |
|
+ } |
|
+ if (pk11_mctx != NULL) |
|
+ isc_mem_detach(&pk11_mctx); |
|
+ initialized = ISC_FALSE; |
|
+ return (ret); |
|
+} |
|
+ |
|
+isc_result_t |
|
+pk11_rand_bytes(unsigned char *buf, int num) { |
|
+ isc_result_t ret; |
|
+ CK_RV rv; |
|
+ pk11_context_t ctx; |
|
+ |
|
+ ret = pk11_get_session(&ctx, OP_RAND, ISC_FALSE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0); |
|
+ if ((ret != ISC_R_SUCCESS) && |
|
+ (ret != PK11_R_NODIGESTSERVICE) && |
|
+ (ret != PK11_R_NOAESSERVICE)) |
|
+ return (ret); |
|
+ RUNTIME_CHECK(ctx.session != CK_INVALID_HANDLE); |
|
+ rv = pkcs_C_GenerateRandom(ctx.session, |
|
+ (CK_BYTE_PTR) buf, (CK_ULONG) num); |
|
+ pk11_return_session(&ctx); |
|
+ if (rv == CKR_OK) |
|
+ return (ISC_R_SUCCESS); |
|
+ else |
|
+ return (DST_R_CRYPTOFAILURE); |
|
+} |
|
+ |
|
+#define SEEDSIZE 1024 |
|
+ |
|
+static CK_BYTE seed[SEEDSIZE]; |
|
+ |
|
+void |
|
+pk11_rand_seed_fromfile(const char *randomfile) { |
|
+ pk11_context_t ctx; |
|
+ FILE *stream = NULL; |
|
+ size_t cc = 0; |
|
+ isc_result_t ret; |
|
+ |
|
+ ret = pk11_get_session(&ctx, OP_RAND, ISC_FALSE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0); |
|
+ if ((ret != ISC_R_SUCCESS) && |
|
+ (ret != PK11_R_NODIGESTSERVICE) && |
|
+ (ret != PK11_R_NOAESSERVICE)) |
|
+ return; |
|
+ RUNTIME_CHECK(ctx.session != CK_INVALID_HANDLE); |
|
+ ret = isc_stdio_open(randomfile, "r", &stream); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto cleanup; |
|
+ ret = isc_stdio_read(seed, 1, SEEDSIZE, stream, &cc); |
|
+ if (ret!= ISC_R_SUCCESS) |
|
+ goto cleanup; |
|
+ ret = isc_stdio_close(stream); |
|
+ stream = NULL; |
|
+ if (ret!= ISC_R_SUCCESS) |
|
+ goto cleanup; |
|
+ (void) pkcs_C_SeedRandom(ctx.session, seed, (CK_ULONG) cc); |
|
+ |
|
+ cleanup: |
|
+ if (stream != NULL) |
|
+ (void) isc_stdio_close(stream); |
|
+ pk11_return_session(&ctx); |
|
+} |
|
+ |
|
+isc_result_t |
|
+pk11_get_session(pk11_context_t *ctx, pk11_optype_t optype, |
|
+ isc_boolean_t need_services, isc_boolean_t rw, |
|
+ isc_boolean_t logon, const char *pin, CK_SLOT_ID slot) |
|
+{ |
|
+ pk11_token_t *token = NULL; |
|
+ pk11_sessionlist_t *freelist; |
|
+ pk11_session_t *sp; |
|
+ isc_result_t ret; |
|
+#ifdef PKCS11CRYPTO |
|
+ isc_result_t service_ret = ISC_R_SUCCESS; |
|
+#else |
|
+ UNUSED(need_services); |
|
+#endif |
|
+ |
|
+ memset(ctx, 0, sizeof(pk11_context_t)); |
|
+ ctx->handle = NULL; |
|
+ ctx->session = CK_INVALID_HANDLE; |
|
+ |
|
+ ret = pk11_initialize(NULL, NULL); |
|
+#ifdef PKCS11CRYPTO |
|
+ if (ret == PK11_R_NORANDOMSERVICE || |
|
+ ret == PK11_R_NODIGESTSERVICE || |
|
+ ret == PK11_R_NOAESSERVICE) { |
|
+ if (need_services) |
|
+ return (ret); |
|
+ service_ret = ret; |
|
+ } |
|
+ else |
|
+#endif /* PKCS11CRYPTO */ |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ return (ret); |
|
+ |
|
+ LOCK(&sessionlock); |
|
+ /* wait for initialization to finish */ |
|
+ UNLOCK(&sessionlock); |
|
+ |
|
+ switch(optype) { |
|
+#ifdef PKCS11CRYPTO |
|
+ case OP_RAND: |
|
+ token = rand_token; |
|
+ break; |
|
+ case OP_DIGEST: |
|
+ token = digest_token; |
|
+ break; |
|
+ case OP_AES: |
|
+ token = aes_token; |
|
+ break; |
|
+ case OP_ANY: |
|
+ for (token = ISC_LIST_HEAD(tokens); |
|
+ token != NULL; |
|
+ token = ISC_LIST_NEXT(token, link)) |
|
+ if (token->slotid == slot) |
|
+ break; |
|
+ break; |
|
+#endif |
|
+ default: |
|
+ for (token = ISC_LIST_HEAD(tokens); |
|
+ token != NULL; |
|
+ token = ISC_LIST_NEXT(token, link)) |
|
+ if (token->slotid == slot) |
|
+ break; |
|
+#ifdef PKCS11CRYPTO |
|
+ if ((token == NULL) || |
|
+ ((token->operations & (1 << optype)) == 0)) |
|
+ return (ISC_R_NOTFOUND); |
|
+#endif |
|
+ break; |
|
+ } |
|
+ if (token == NULL) |
|
+ return (ISC_R_NOTFOUND); |
|
+ |
|
+ /* Override the token's PIN */ |
|
+ if (logon && pin != NULL && *pin != '\0') { |
|
+ memset(token->pin, 0, PINLEN); |
|
+ strncpy(token->pin, pin, PINLEN); |
|
+ } |
|
+ |
|
+ freelist = &token->sessions; |
|
+ |
|
+ LOCK(&sessionlock); |
|
+ sp = ISC_LIST_HEAD(*freelist); |
|
+ if (sp != NULL) { |
|
+ ISC_LIST_UNLINK(*freelist, sp, link); |
|
+ ISC_LIST_APPEND(actives, sp, link); |
|
+ UNLOCK(&sessionlock); |
|
+ if (logon) |
|
+ ret = token_login(sp); |
|
+ ctx->handle = sp; |
|
+ ctx->session = sp->session; |
|
+ return (ret); |
|
+ } |
|
+ UNLOCK(&sessionlock); |
|
+ |
|
+ sp = pk11_mem_get(sizeof(*sp)); |
|
+ if (sp == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ sp->magic = SES_MAGIC; |
|
+ sp->token = token; |
|
+ sp->session = CK_INVALID_HANDLE; |
|
+ ISC_LINK_INIT(sp, link); |
|
+ ret = setup_session(sp, token, rw); |
|
+ if ((ret == ISC_R_SUCCESS) && logon) |
|
+ ret = token_login(sp); |
|
+ LOCK(&sessionlock); |
|
+ ISC_LIST_APPEND(actives, sp, link); |
|
+ UNLOCK(&sessionlock); |
|
+ ctx->handle = sp; |
|
+ ctx->session = sp->session; |
|
+#ifdef PKCS11CRYPTO |
|
+ if (ret == ISC_R_SUCCESS) |
|
+ ret = service_ret; |
|
+#endif |
|
+ return (ret); |
|
+} |
|
+ |
|
+void |
|
+pk11_return_session(pk11_context_t *ctx) { |
|
+ pk11_session_t *sp = (pk11_session_t *) ctx->handle; |
|
+ |
|
+ if (sp == NULL) |
|
+ return; |
|
+ ctx->handle = NULL; |
|
+ ctx->session = CK_INVALID_HANDLE; |
|
+ |
|
+ LOCK(&sessionlock); |
|
+ ISC_LIST_UNLINK(actives, sp, link); |
|
+ UNLOCK(&sessionlock); |
|
+ if (sp->session == CK_INVALID_HANDLE) { |
|
+ pk11_mem_put(sp, sizeof(*sp)); |
|
+ return; |
|
+ } |
|
+ |
|
+ LOCK(&sessionlock); |
|
+ ISC_LIST_APPEND(sp->token->sessions, sp, link); |
|
+ UNLOCK(&sessionlock); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+free_all_sessions(void) { |
|
+ pk11_token_t *token; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ isc_result_t oret; |
|
+ |
|
+ for (token = ISC_LIST_HEAD(tokens); |
|
+ token != NULL; |
|
+ token = ISC_LIST_NEXT(token, link)) { |
|
+ oret = free_session_list(&token->sessions); |
|
+ if (oret != ISC_R_SUCCESS) |
|
+ ret = oret; |
|
+ } |
|
+ if (!ISC_LIST_EMPTY(actives)) { |
|
+ ret = ISC_R_ADDRINUSE; |
|
+ oret = free_session_list(&actives); |
|
+ if (oret != ISC_R_SUCCESS) |
|
+ ret = oret; |
|
+ } |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+free_session_list(pk11_sessionlist_t *slist) { |
|
+ pk11_session_t *sp; |
|
+ CK_RV rv; |
|
+ isc_result_t ret; |
|
+ |
|
+ ret = ISC_R_SUCCESS; |
|
+ LOCK(&sessionlock); |
|
+ while (!ISC_LIST_EMPTY(*slist)) { |
|
+ sp = ISC_LIST_HEAD(*slist); |
|
+ UNLOCK(&sessionlock); |
|
+ if (sp->session != CK_INVALID_HANDLE) { |
|
+ rv = pkcs_C_CloseSession(sp->session); |
|
+ if (rv != CKR_OK) |
|
+ ret = DST_R_CRYPTOFAILURE; |
|
+ } |
|
+ LOCK(&sessionlock); |
|
+ ISC_LIST_UNLINK(*slist, sp, link); |
|
+ pk11_mem_put(sp, sizeof(*sp)); |
|
+ } |
|
+ UNLOCK(&sessionlock); |
|
+ |
|
+ return (ret); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+setup_session(pk11_session_t *sp, pk11_token_t *token, |
|
+ isc_boolean_t rw) |
|
+{ |
|
+ CK_RV rv; |
|
+ CK_FLAGS flags = CKF_SERIAL_SESSION; |
|
+ |
|
+ if (rw) |
|
+ flags += CKF_RW_SESSION; |
|
+ |
|
+ rv = pkcs_C_OpenSession(token->slotid, flags, NULL_PTR, |
|
+ NULL_PTR, &sp->session); |
|
+ if (rv != CKR_OK) |
|
+ return (DST_R_CRYPTOFAILURE); |
|
+ return (ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+static isc_result_t |
|
+token_login(pk11_session_t *sp) { |
|
+ CK_RV rv; |
|
+ pk11_token_t *token = sp->token; |
|
+ isc_result_t ret = ISC_R_SUCCESS; |
|
+ |
|
+ LOCK(&sessionlock); |
|
+ if (!token->logged) { |
|
+ rv = pkcs_C_Login(sp->session, CKU_USER, |
|
+ (CK_UTF8CHAR_PTR) token->pin, |
|
+ (CK_ULONG) strlen(token->pin)); |
|
+ if (rv != CKR_OK) { |
|
+ ret = ISC_R_NOPERM; |
|
+#if PK11_NO_LOGERR |
|
+ pk11_error_fatalcheck(__FILE__, __LINE__, |
|
+ "pkcs_C_Login", rv); |
|
+#endif |
|
+ } else |
|
+ token->logged = ISC_TRUE; |
|
+ } |
|
+ UNLOCK(&sessionlock); |
|
+ return (ret); |
|
+} |
|
+ |
|
+static void |
|
+choose_slots(void) { |
|
+ CK_MECHANISM_INFO mechInfo; |
|
+ CK_TOKEN_INFO tokenInfo; |
|
+ CK_RV rv; |
|
+ CK_SLOT_ID slot; |
|
+ CK_SLOT_ID_PTR slotList; |
|
+ CK_ULONG slotCount; |
|
+ pk11_token_t *token; |
|
+ unsigned int i; |
|
+ |
|
+ slotCount = 0; |
|
+ PK11_FATALCHECK(pkcs_C_GetSlotList, (CK_FALSE, NULL_PTR, &slotCount)); |
|
+ /* it's not an error if we didn't find any providers */ |
|
+ if (slotCount == 0) |
|
+ return; |
|
+ slotList = pk11_mem_get(sizeof(CK_SLOT_ID_PTR) * slotCount); |
|
+ RUNTIME_CHECK(slotList != NULL); |
|
+ PK11_FATALCHECK(pkcs_C_GetSlotList, (CK_FALSE, slotList, &slotCount)); |
|
+ |
|
+ for (i = 0; i < slotCount; i++) { |
|
+ slot = slotList[i]; |
|
+ |
|
+ rv = pkcs_C_GetTokenInfo(slot, &tokenInfo); |
|
+ if (rv != CKR_OK) |
|
+ continue; |
|
+ token = pk11_mem_get(sizeof(*token)); |
|
+ RUNTIME_CHECK(token != NULL); |
|
+ token->magic = TOK_MAGIC; |
|
+ token->slotid = slot; |
|
+ ISC_LINK_INIT(token, link); |
|
+ ISC_LIST_INIT(token->sessions); |
|
+ memmove(token->name, tokenInfo.label, 32); |
|
+ memmove(token->manuf, tokenInfo.manufacturerID, 32); |
|
+ memmove(token->model, tokenInfo.model, 16); |
|
+ memmove(token->serial, tokenInfo.serialNumber, 16); |
|
+ ISC_LIST_APPEND(tokens, token, link); |
|
+ if ((tokenInfo.flags & CKF_RNG) == 0) |
|
+ goto try_rsa; |
|
+ token->operations |= 1 << OP_RAND; |
|
+ if (rand_token == NULL) |
|
+ rand_token = token; |
|
+ |
|
+ try_rsa: |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || |
|
+ ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) |
|
+ goto try_dsa; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5_RSA_PKCS, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || |
|
+ ((mechInfo.flags & CKF_SIGN) == 0) || |
|
+ ((mechInfo.flags & CKF_VERIFY) == 0)) |
|
+ goto try_dsa; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA1_RSA_PKCS, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || |
|
+ ((mechInfo.flags & CKF_SIGN) == 0) || |
|
+ ((mechInfo.flags & CKF_VERIFY) == 0)) |
|
+ goto try_dsa; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA256_RSA_PKCS, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || |
|
+ ((mechInfo.flags & CKF_SIGN) == 0) || |
|
+ ((mechInfo.flags & CKF_VERIFY) == 0)) |
|
+ goto try_dsa; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA512_RSA_PKCS, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || |
|
+ ((mechInfo.flags & CKF_SIGN) == 0) || |
|
+ ((mechInfo.flags & CKF_VERIFY) == 0)) |
|
+ goto try_dsa; |
|
+ token->operations |= 1 << OP_RSA; |
|
+ if (best_rsa_token == NULL) |
|
+ best_rsa_token = token; |
|
+ |
|
+ try_dsa: |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_DSA_PARAMETER_GEN, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_GENERATE) == 0)) |
|
+ goto try_dh; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_DSA_KEY_PAIR_GEN, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || |
|
+ ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) |
|
+ goto try_dh; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_DSA_SHA1, &mechInfo); |
|
+ if ((rv != CKR_OK) || |
|
+ ((mechInfo.flags & CKF_SIGN) == 0) || |
|
+ ((mechInfo.flags & CKF_VERIFY) == 0)) |
|
+ goto try_dh; |
|
+ token->operations |= 1 << OP_DSA; |
|
+ if (best_dsa_token == NULL) |
|
+ best_dsa_token = token; |
|
+ |
|
+ try_dh: |
|
+#ifdef notdef |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_DH_PKCS_PARAMETER_GEN, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_GENERATE) == 0)) |
|
+ goto try_digest; |
|
+#endif |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_DH_PKCS_KEY_PAIR_GEN, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || |
|
+ ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) |
|
+ goto try_digest; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_DH_PKCS_DERIVE, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DERIVE) == 0)) |
|
+ goto try_digest; |
|
+ token->operations |= 1 << OP_DH; |
|
+ if (best_dh_token == NULL) |
|
+ best_dh_token = token; |
|
+ |
|
+ try_digest: |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) |
|
+ continue; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA_1, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) |
|
+ continue; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA224, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) |
|
+ continue; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA256, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) |
|
+ continue; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA384, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) |
|
+ continue; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA512, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) |
|
+ continue; |
|
+#ifdef PKCS11CRYPTOWITHHMAC |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_MD5_HMAC, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) |
|
+ continue; |
|
+#endif |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA_1_HMAC, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) |
|
+ continue; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA224_HMAC, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) |
|
+ continue; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA256_HMAC, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) |
|
+ continue; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA384_HMAC, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) |
|
+ continue; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_SHA512_HMAC, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_SIGN) == 0)) |
|
+ continue; |
|
+ token->operations |= 1 << OP_DIGEST; |
|
+ if (digest_token == NULL) |
|
+ digest_token = token; |
|
+ |
|
+ /* ECDSA requires digest */ |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_EC_KEY_PAIR_GEN, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || |
|
+ ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) |
|
+ goto try_gost; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_ECDSA, &mechInfo); |
|
+ if ((rv != CKR_OK) || |
|
+ ((mechInfo.flags & CKF_SIGN) == 0) || |
|
+ ((mechInfo.flags & CKF_VERIFY) == 0)) |
|
+ goto try_gost; |
|
+ token->operations |= 1 << OP_EC; |
|
+ if (best_ec_token == NULL) |
|
+ best_ec_token = token; |
|
+ |
|
+ try_gost: |
|
+ /* does GOST require digest too? */ |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_GOSTR3411, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_DIGEST) == 0)) |
|
+ goto try_aes; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_GOSTR3410_KEY_PAIR_GEN, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || |
|
+ ((mechInfo.flags & CKF_GENERATE_KEY_PAIR) == 0)) |
|
+ goto try_aes; |
|
+ rv = pkcs_C_GetMechanismInfo(slot, |
|
+ CKM_GOSTR3410_WITH_GOSTR3411, |
|
+ &mechInfo); |
|
+ if ((rv != CKR_OK) || |
|
+ ((mechInfo.flags & CKF_SIGN) == 0) || |
|
+ ((mechInfo.flags & CKF_VERIFY) == 0)) |
|
+ goto try_aes; |
|
+ token->operations |= 1 << OP_GOST; |
|
+ if (best_gost_token == NULL) |
|
+ best_gost_token = token; |
|
+ |
|
+ try_aes: |
|
+ rv = pkcs_C_GetMechanismInfo(slot, CKM_AES_ECB, &mechInfo); |
|
+ if ((rv != CKR_OK) || ((mechInfo.flags & CKF_ENCRYPT) == 0)) |
|
+ continue; |
|
+ token->operations |= 1 << OP_AES; |
|
+ if (aes_token == NULL) |
|
+ aes_token = token; |
|
+ } |
|
+ |
|
+ if (slotList != NULL) |
|
+ pk11_mem_put(slotList, sizeof(CK_SLOT_ID_PTR) * slotCount); |
|
+} |
|
+ |
|
+CK_SLOT_ID |
|
+pk11_get_best_token(pk11_optype_t optype) { |
|
+ pk11_token_t *token = NULL; |
|
+ |
|
+ switch (optype) { |
|
+ case OP_RAND: |
|
+ token = rand_token; |
|
+ break; |
|
+ case OP_RSA: |
|
+ token = best_rsa_token; |
|
+ break; |
|
+ case OP_DSA: |
|
+ token = best_dsa_token; |
|
+ break; |
|
+ case OP_DH: |
|
+ token = best_dh_token; |
|
+ break; |
|
+ case OP_DIGEST: |
|
+ token = digest_token; |
|
+ break; |
|
+ case OP_EC: |
|
+ token = best_ec_token; |
|
+ break; |
|
+ case OP_GOST: |
|
+ token = best_gost_token; |
|
+ break; |
|
+ case OP_AES: |
|
+ token = aes_token; |
|
+ break; |
|
+ default: |
|
+ break; |
|
+ } |
|
+ if (token == NULL) |
|
+ return (0); |
|
+ return (token->slotid); |
|
+} |
|
+ |
|
+unsigned int |
|
+pk11_numbits(CK_BYTE_PTR data, unsigned int bytecnt) { |
|
+ unsigned int bitcnt, i; |
|
+ CK_BYTE top; |
|
+ |
|
+ if (bytecnt == 0) |
|
+ return (0); |
|
+ bitcnt = bytecnt * 8; |
|
+ for (i = 0; i < bytecnt; i++) { |
|
+ top = data[i]; |
|
+ if (top == 0) { |
|
+ bitcnt -= 8; |
|
+ continue; |
|
+ } |
|
+ if (top & 0x80) |
|
+ return (bitcnt); |
|
+ if (top & 0x40) |
|
+ return (bitcnt - 1); |
|
+ if (top & 0x20) |
|
+ return (bitcnt - 2); |
|
+ if (top & 0x10) |
|
+ return (bitcnt - 3); |
|
+ if (top & 0x08) |
|
+ return (bitcnt - 4); |
|
+ if (top & 0x04) |
|
+ return (bitcnt - 5); |
|
+ if (top & 0x02) |
|
+ return (bitcnt - 6); |
|
+ if (top & 0x01) |
|
+ return (bitcnt - 7); |
|
+ break; |
|
+ } |
|
+ INSIST(0); |
|
+} |
|
+ |
|
+CK_ATTRIBUTE * |
|
+pk11_attribute_first(const pk11_object_t *obj) { |
|
+ return (obj->repr); |
|
+} |
|
+ |
|
+CK_ATTRIBUTE * |
|
+pk11_attribute_next(const pk11_object_t *obj, CK_ATTRIBUTE *attr) { |
|
+ CK_ATTRIBUTE *next; |
|
+ |
|
+ next = attr + 1; |
|
+ if ((next - obj->repr) >= obj->attrcnt) |
|
+ return (NULL); |
|
+ return (next); |
|
+} |
|
+ |
|
+CK_ATTRIBUTE * |
|
+pk11_attribute_bytype(const pk11_object_t *obj, CK_ATTRIBUTE_TYPE type) { |
|
+ CK_ATTRIBUTE *attr; |
|
+ |
|
+ for(attr = pk11_attribute_first(obj); |
|
+ attr != NULL; |
|
+ attr = pk11_attribute_next(obj, attr)) |
|
+ if (attr->type == type) |
|
+ return (attr); |
|
+ return (NULL); |
|
+} |
|
+ |
|
+static char * |
|
+percent_decode(char *x, size_t *len) { |
|
+ char *p, *c; |
|
+ unsigned char v; |
|
+ |
|
+ INSIST(len != NULL); |
|
+ |
|
+ for (p = c = x; p[0] != '\0'; p++, c++) { |
|
+ switch (p[0]) { |
|
+ case '%': |
|
+ v = 0; |
|
+ switch (p[1]) { |
|
+ case '0': |
|
+ case '1': |
|
+ case '2': |
|
+ case '3': |
|
+ case '4': |
|
+ case '5': |
|
+ case '6': |
|
+ case '7': |
|
+ case '8': |
|
+ case '9': |
|
+ v = (p[1] - '0') << 4; |
|
+ break; |
|
+ case 'A': |
|
+ case 'B': |
|
+ case 'C': |
|
+ case 'D': |
|
+ case 'E': |
|
+ case 'F': |
|
+ v = (p[1] - 'A' + 10) << 4; |
|
+ break; |
|
+ case 'a': |
|
+ case 'b': |
|
+ case 'c': |
|
+ case 'd': |
|
+ case 'e': |
|
+ case 'f': |
|
+ v = (p[1] - 'a' + 10) << 4; |
|
+ break; |
|
+ default: |
|
+ return (NULL); |
|
+ } |
|
+ switch (p[2]) { |
|
+ case '0': |
|
+ case '1': |
|
+ case '2': |
|
+ case '3': |
|
+ case '4': |
|
+ case '5': |
|
+ case '6': |
|
+ case '7': |
|
+ case '8': |
|
+ case '9': |
|
+ v |= (p[2] - '0') & 0x0f; |
|
+ break; |
|
+ case 'A': |
|
+ case 'B': |
|
+ case 'C': |
|
+ case 'D': |
|
+ case 'E': |
|
+ case 'F': |
|
+ v = (p[2] - 'A' + 10) & 0x0f; |
|
+ break; |
|
+ case 'a': |
|
+ case 'b': |
|
+ case 'c': |
|
+ case 'd': |
|
+ case 'e': |
|
+ case 'f': |
|
+ v = (p[2] - 'a' + 10) & 0x0f; |
|
+ break; |
|
+ default: |
|
+ return (NULL); |
|
+ } |
|
+ p += 2; |
|
+ *c = (char) v; |
|
+ (*len)++; |
|
+ break; |
|
+ default: |
|
+ *c = *p; |
|
+ (*len)++; |
|
+ } |
|
+ } |
|
+ return (x); |
|
+} |
|
+ |
|
+static isc_boolean_t |
|
+pk11strcmp(const char *x, size_t lenx, const char *y, size_t leny) { |
|
+ char buf[32]; |
|
+ |
|
+ INSIST((leny == 32) || (leny == 16)); |
|
+ |
|
+ memset(buf, ' ', 32); |
|
+ if (lenx > leny) |
|
+ lenx = leny; |
|
+ memmove(buf, x, lenx); |
|
+ return (ISC_TF(memcmp(buf, y, leny) == 0)); |
|
+} |
|
+ |
|
+static CK_ATTRIBUTE * |
|
+push_attribute(pk11_object_t *obj, isc_mem_t *mctx, size_t len) { |
|
+ CK_ATTRIBUTE *old = obj->repr; |
|
+ CK_ATTRIBUTE *attr; |
|
+ CK_BYTE cnt = obj->attrcnt; |
|
+ |
|
+ obj->repr = isc_mem_get(mctx, (cnt + 1) * sizeof(*attr)); |
|
+ if (obj->repr == NULL) { |
|
+ obj->repr = old; |
|
+ return (NULL); |
|
+ } |
|
+ memset(obj->repr, 0, (cnt + 1) * sizeof(*attr)); |
|
+ memmove(obj->repr, old, cnt * sizeof(*attr)); |
|
+ attr = obj->repr + cnt; |
|
+ attr->ulValueLen = (CK_ULONG) len; |
|
+ attr->pValue = isc_mem_get(mctx, len); |
|
+ if (attr->pValue == NULL) { |
|
+ memset(obj->repr, 0, (cnt + 1) * sizeof(*attr)); |
|
+ isc_mem_put(mctx, obj->repr, (cnt + 1) * sizeof(*attr)); |
|
+ obj->repr = old; |
|
+ return (NULL); |
|
+ } |
|
+ memset(attr->pValue, 0, len); |
|
+ if (old != NULL) { |
|
+ memset(old, 0, cnt * sizeof(*attr)); |
|
+ isc_mem_put(mctx, old, cnt * sizeof(*attr)); |
|
+ } |
|
+ obj->attrcnt++; |
|
+ return (attr); |
|
+} |
|
+ |
|
+#define DST_RET(a) { ret = a; goto err; } |
|
+ |
|
+isc_result_t |
|
+pk11_parse_uri(pk11_object_t *obj, const char *label, |
|
+ isc_mem_t *mctx, pk11_optype_t optype) |
|
+{ |
|
+ CK_ATTRIBUTE *attr; |
|
+ pk11_token_t *token = NULL; |
|
+ char *uri, *p, *a, *na, *v; |
|
+ size_t len, l; |
|
+ FILE *stream = NULL; |
|
+ char pin[PINLEN]; |
|
+ isc_boolean_t gotpin = ISC_FALSE; |
|
+ isc_result_t ret; |
|
+ |
|
+ /* get values to work on */ |
|
+ len = strlen(label) + 1; |
|
+ uri = isc_mem_get(mctx, len); |
|
+ if (uri == NULL) |
|
+ return (ISC_R_NOMEMORY); |
|
+ memmove(uri, label, len); |
|
+ |
|
+ /* get the URI scheme */ |
|
+ p = strchr(uri, ':'); |
|
+ if (p == NULL) |
|
+ DST_RET(PK11_R_NOPROVIDER); |
|
+ *p++ = '\0'; |
|
+ if (strcmp(uri, "pkcs11") != 0) |
|
+ DST_RET(PK11_R_NOPROVIDER); |
|
+ |
|
+ /* get attributes */ |
|
+ for (na = p; na != NULL;) { |
|
+ a = na; |
|
+ p = strchr(a, ';'); |
|
+ if (p == NULL) { |
|
+ /* last attribute */ |
|
+ na = NULL; |
|
+ } else { |
|
+ *p++ = '\0'; |
|
+ na = p; |
|
+ } |
|
+ p = strchr(a, '='); |
|
+ if (p != NULL) { |
|
+ *p++ = '\0'; |
|
+ v = p; |
|
+ } else |
|
+ v = a; |
|
+ l = 0; |
|
+ v = percent_decode(v, &l); |
|
+ if (v == NULL) |
|
+ DST_RET(PK11_R_NOPROVIDER); |
|
+ if ((a == v) || (strcmp(a, "object") == 0)) { |
|
+ /* object: CKA_LABEL */ |
|
+ attr = pk11_attribute_bytype(obj, CKA_LABEL); |
|
+ if (attr != NULL) |
|
+ DST_RET(PK11_R_NOPROVIDER); |
|
+ attr = push_attribute(obj, mctx, l); |
|
+ if (attr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ attr->type = CKA_LABEL; |
|
+ memmove(attr->pValue, v, l); |
|
+ } else if (strcmp(a, "token") == 0) { |
|
+ /* token: CK_TOKEN_INFO label */ |
|
+ if (token == NULL) |
|
+ for (token = ISC_LIST_HEAD(tokens); |
|
+ token != NULL; |
|
+ token = ISC_LIST_NEXT(token, link)) |
|
+ if (pk11strcmp(v, l, token->name, 32)) |
|
+ break; |
|
+ } else if (strcmp(a, "manufacturer") == 0) { |
|
+ /* manufacturer: CK_TOKEN_INFO manufacturerID */ |
|
+ if (token == NULL) |
|
+ for (token = ISC_LIST_HEAD(tokens); |
|
+ token != NULL; |
|
+ token = ISC_LIST_NEXT(token, link)) |
|
+ if (pk11strcmp(v, l, token->manuf, 32)) |
|
+ break; |
|
+ } else if (strcmp(a, "serial") == 0) { |
|
+ /* serial: CK_TOKEN_INFO serialNumber */ |
|
+ if (token == NULL) |
|
+ for (token = ISC_LIST_HEAD(tokens); |
|
+ token != NULL; |
|
+ token = ISC_LIST_NEXT(token, link)) |
|
+ if (pk11strcmp(v, l, token->serial, 16)) |
|
+ break; |
|
+ } else if (strcmp(a, "model") == 0) { |
|
+ /* model: CK_TOKEN_INFO model */ |
|
+ if (token == NULL) |
|
+ for (token = ISC_LIST_HEAD(tokens); |
|
+ token != NULL; |
|
+ token = ISC_LIST_NEXT(token, link)) |
|
+ if (pk11strcmp(v, l, token->model, 16)) |
|
+ break; |
|
+ } else if (strcmp(a, "library-manufacturer") == 0) { |
|
+ /* ignored */ |
|
+ } else if (strcmp(a, "library-description") == 0) { |
|
+ /* ignored */ |
|
+ } else if (strcmp(a, "library-version") == 0) { |
|
+ /* ignored */ |
|
+ } else if (strcmp(a, "object-type") == 0) { |
|
+ /* object-type: CKA_CLASS */ |
|
+ /* only private makes sense */ |
|
+ if (strcmp(v, "private") != 0) |
|
+ DST_RET(PK11_R_NOPROVIDER); |
|
+ } else if (strcmp(a, "id") == 0) { |
|
+ /* id: CKA_ID */ |
|
+ attr = pk11_attribute_bytype(obj, CKA_ID); |
|
+ if (attr != NULL) |
|
+ DST_RET(PK11_R_NOPROVIDER); |
|
+ attr = push_attribute(obj, mctx, l); |
|
+ if (attr == NULL) |
|
+ DST_RET(ISC_R_NOMEMORY); |
|
+ attr->type = CKA_ID; |
|
+ memmove(attr->pValue, v, l); |
|
+ } else if (strcmp(a, "pin-source") == 0) { |
|
+ /* pin-source: PIN */ |
|
+ ret = isc_stdio_open(v, "r", &stream); |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ memset(pin, 0, PINLEN); |
|
+ ret = isc_stdio_read(pin, 1, PINLEN - 1, stream, NULL); |
|
+ if ((ret != ISC_R_SUCCESS) && (ret != ISC_R_EOF)) |
|
+ goto err; |
|
+ ret = isc_stdio_close(stream); |
|
+ stream = NULL; |
|
+ if (ret != ISC_R_SUCCESS) |
|
+ goto err; |
|
+ gotpin = ISC_TRUE; |
|
+ } else |
|
+ DST_RET(PK11_R_NOPROVIDER); |
|
+ } |
|
+ |
|
+ if ((pk11_attribute_bytype(obj, CKA_LABEL) == NULL) && |
|
+ (pk11_attribute_bytype(obj, CKA_ID) == NULL)) |
|
+ DST_RET(ISC_R_NOTFOUND); |
|
+ |
|
+ if (token == NULL) { |
|
+ if (optype == OP_RSA) |
|
+ token = best_rsa_token; |
|
+ else if (optype == OP_DSA) |
|
+ token = best_dsa_token; |
|
+ else if (optype == OP_DH) |
|
+ token = best_dh_token; |
|
+ else if (optype == OP_EC) |
|
+ token = best_ec_token; |
|
+ } |
|
+ if (token == NULL) |
|
+ DST_RET(ISC_R_NOTFOUND); |
|
+ obj->slot = token->slotid; |
|
+ if (gotpin) { |
|
+ memmove(token->pin, pin, PINLEN); |
|
+ obj->reqlogon = ISC_TRUE; |
|
+ } |
|
+ |
|
+ ret = ISC_R_SUCCESS; |
|
+ |
|
+ err: |
|
+ if (stream != NULL) |
|
+ (void) isc_stdio_close(stream); |
|
+ isc_mem_put(mctx, uri, len); |
|
+ return (ret); |
|
+} |
|
+ |
|
+void |
|
+pk11_error_fatalcheck(const char *file, int line, |
|
+ const char *funcname, CK_RV rv) |
|
+{ |
|
+ isc_error_fatal(file, line, "%s: Error = 0x%.8lX\n", funcname, rv); |
|
+} |
|
+ |
|
+void |
|
+pk11_dump_tokens(void) |
|
+{ |
|
+ pk11_token_t *token; |
|
+ isc_boolean_t first; |
|
+ |
|
+ printf("DEFAULTS\n"); |
|
+ printf("\trand_token=%p\n", rand_token); |
|
+ printf("\tbest_rsa_token=%p\n", best_rsa_token); |
|
+ printf("\tbest_dsa_token=%p\n", best_dsa_token); |
|
+ printf("\tbest_dh_token=%p\n", best_dh_token); |
|
+ printf("\tdigest_token=%p\n", digest_token); |
|
+ printf("\tbest_ec_token=%p\n", best_ec_token); |
|
+ printf("\tbest_gost_token=%p\n", best_gost_token); |
|
+ printf("\taes_token=%p\n", aes_token); |
|
+ |
|
+ for (token = ISC_LIST_HEAD(tokens); |
|
+ token != NULL; |
|
+ token = ISC_LIST_NEXT(token, link)) { |
|
+ printf("\nTOKEN\n"); |
|
+ printf("\taddress=%p\n", token); |
|
+ printf("\tslotID=%lu\n", token->slotid); |
|
+ printf("\tlabel=%.32s\n", token->name); |
|
+ printf("\tmanufacturerID=%.32s\n", token->manuf); |
|
+ printf("\tmodel=%.16s\n", token->model); |
|
+ printf("\tserialNumber=%.16s\n", token->serial); |
|
+ printf("\tsupported operations=0x%x (", token->operations); |
|
+ first = ISC_TRUE; |
|
+ if (token->operations & (1 << OP_RAND)) { |
|
+ if (!first) |
|
+ printf(","); |
|
+ first = ISC_FALSE; |
|
+ printf("RAND"); |
|
+ } |
|
+ if (token->operations & (1 << OP_RSA)) { |
|
+ if (!first) |
|
+ printf(","); |
|
+ first = ISC_FALSE; |
|
+ printf("RSA"); |
|
+ } |
|
+ if (token->operations & (1 << OP_DSA)) { |
|
+ if (!first) |
|
+ printf(","); |
|
+ first = ISC_FALSE; |
|
+ printf("DSA"); |
|
+ } |
|
+ if (token->operations & (1 << OP_DH)) { |
|
+ if (!first) |
|
+ printf(","); |
|
+ first = ISC_FALSE; |
|
+ printf("DH"); |
|
+ } |
|
+ if (token->operations & (1 << OP_DIGEST)) { |
|
+ if (!first) |
|
+ printf(","); |
|
+ first = ISC_FALSE; |
|
+ printf("DIGEST"); |
|
+ } |
|
+ if (token->operations & (1 << OP_EC)) { |
|
+ if (!first) |
|
+ printf(","); |
|
+ first = ISC_FALSE; |
|
+ printf("EC"); |
|
+ } |
|
+ printf(")\n"); |
|
+ } |
|
+} |
|
diff --git a/lib/isc/pk11_result.c b/lib/isc/pk11_result.c |
|
new file mode 100644 |
|
index 0000000..0ada753 |
|
--- /dev/null |
|
+++ b/lib/isc/pk11_result.c |
|
@@ -0,0 +1,85 @@ |
|
+/* |
|
+ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+#include <config.h> |
|
+#include <stddef.h> |
|
+ |
|
+#include <isc/once.h> |
|
+#include <isc/msgcat.h> |
|
+#include <isc/util.h> |
|
+ |
|
+#include <pk11/result.h> |
|
+ |
|
+LIBISC_EXTERNAL_DATA isc_msgcat_t * pk11_msgcat = NULL; |
|
+ |
|
+static isc_once_t msgcat_once = ISC_ONCE_INIT; |
|
+ |
|
+static const char *text[PK11_R_NRESULTS] = { |
|
+ "PKCS#11 initialization failed", /*%< 0 */ |
|
+ "no PKCS#11 provider", /*%< 1 */ |
|
+ "PKCS#11 provider has no random service", /*%< 2 */ |
|
+ "PKCS#11 provider has no digest service", /*%< 3 */ |
|
+ "PKCS#11 provider has no AES service", /*%< 4 */ |
|
+}; |
|
+ |
|
+#define PK11_RESULT_RESULTSET 2 |
|
+ |
|
+static isc_once_t once = ISC_ONCE_INIT; |
|
+ |
|
+static void |
|
+open_msgcat(void) { |
|
+ isc_msgcat_open("libpk11.cat", &pk11_msgcat); |
|
+} |
|
+ |
|
+void |
|
+pk11_initmsgcat(void) { |
|
+ |
|
+ /* |
|
+ * Initialize the PKCS#11 support's message catalog, |
|
+ * pk11_msgcat, if it has not already been initialized. |
|
+ */ |
|
+ |
|
+ RUNTIME_CHECK(isc_once_do(&msgcat_once, open_msgcat) == ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+static void |
|
+initialize_action(void) { |
|
+ isc_result_t result; |
|
+ |
|
+ result = isc_result_register(ISC_RESULTCLASS_PK11, PK11_R_NRESULTS, |
|
+ text, pk11_msgcat, PK11_RESULT_RESULTSET); |
|
+ if (result != ISC_R_SUCCESS) |
|
+ UNEXPECTED_ERROR(__FILE__, __LINE__, |
|
+ "isc_result_register() failed: %u", result); |
|
+} |
|
+ |
|
+static void |
|
+initialize(void) { |
|
+ pk11_initmsgcat(); |
|
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS); |
|
+} |
|
+ |
|
+const char * |
|
+pk11_result_totext(isc_result_t result) { |
|
+ initialize(); |
|
+ |
|
+ return (isc_result_totext(result)); |
|
+} |
|
+ |
|
+void |
|
+pk11_result_register(void) { |
|
+ initialize(); |
|
+} |
|
diff --git a/lib/isc/sha1.c b/lib/isc/sha1.c |
|
index cce9603..caa721e 100644 |
|
--- a/lib/isc/sha1.c |
|
+++ b/lib/isc/sha1.c |
|
@@ -44,8 +44,12 @@ |
|
#include <isc/types.h> |
|
#include <isc/util.h> |
|
|
|
-#ifdef ISC_PLATFORM_OPENSSLHASH |
|
+#if PKCS11CRYPTO |
|
+#include <pk11/internal.h> |
|
+#include <pk11/pk11.h> |
|
+#endif |
|
|
|
+#ifdef ISC_PLATFORM_OPENSSLHASH |
|
void |
|
isc_sha1_init(isc_sha1_t *context) |
|
{ |
|
@@ -77,6 +81,50 @@ isc_sha1_final(isc_sha1_t *context, unsigned char *digest) { |
|
EVP_DigestFinal(context, digest, NULL); |
|
} |
|
|
|
+#elif PKCS11CRYPTO |
|
+ |
|
+void |
|
+isc_sha1_init(isc_sha1_t *ctx) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_SHA_1, NULL, 0 }; |
|
+ |
|
+ RUNTIME_CHECK(pk11_get_session(ctx, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ PK11_FATALCHECK(pkcs_C_DigestInit, (ctx->session, &mech)); |
|
+} |
|
+ |
|
+void |
|
+isc_sha1_invalidate(isc_sha1_t *ctx) { |
|
+ CK_BYTE garbage[ISC_SHA1_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_SHA1_DIGESTLENGTH; |
|
+ |
|
+ if (ctx->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_DigestFinal(ctx->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
+void |
|
+isc_sha1_update(isc_sha1_t *ctx, const unsigned char *buf, unsigned int len) { |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ DE_CONST(buf, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_DigestUpdate, |
|
+ (ctx->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_sha1_final(isc_sha1_t *ctx, unsigned char *digest) { |
|
+ CK_RV rv; |
|
+ CK_ULONG len = ISC_SHA1_DIGESTLENGTH; |
|
+ |
|
+ PK11_FATALCHECK(pkcs_C_DigestFinal, |
|
+ (ctx->session, (CK_BYTE_PTR) digest, &len)); |
|
+ pk11_return_session(ctx); |
|
+} |
|
+ |
|
#else |
|
|
|
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) |
|
diff --git a/lib/isc/sha2.c b/lib/isc/sha2.c |
|
index db2e349..d7e0cf6 100644 |
|
--- a/lib/isc/sha2.c |
|
+++ b/lib/isc/sha2.c |
|
@@ -63,6 +63,11 @@ |
|
#include <isc/string.h> |
|
#include <isc/util.h> |
|
|
|
+#if PKCS11CRYPTO |
|
+#include <pk11/internal.h> |
|
+#include <pk11/pk11.h> |
|
+#endif |
|
+ |
|
#ifdef ISC_PLATFORM_OPENSSLHASH |
|
|
|
void |
|
@@ -219,6 +224,272 @@ isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) { |
|
} |
|
} |
|
|
|
+#elif PKCS11CRYPTO |
|
+ |
|
+void |
|
+isc_sha224_init(isc_sha224_t *context) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_SHA224, NULL, 0 }; |
|
+ |
|
+ if (context == (isc_sha224_t *)0) { |
|
+ return; |
|
+ } |
|
+ RUNTIME_CHECK(pk11_get_session(context, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ PK11_FATALCHECK(pkcs_C_DigestInit, (context->session, &mech)); |
|
+} |
|
+ |
|
+void |
|
+isc_sha224_invalidate(isc_sha224_t *context) { |
|
+ CK_BYTE garbage[ISC_SHA224_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_SHA224_DIGESTLENGTH; |
|
+ |
|
+ if (context->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_DigestFinal(context->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ pk11_return_session(context); |
|
+} |
|
+ |
|
+void |
|
+isc_sha224_update(isc_sha224_t *context, const isc_uint8_t* data, size_t len) { |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ if (len == 0U) { |
|
+ /* Calling with no data is valid - we do nothing */ |
|
+ return; |
|
+ } |
|
+ |
|
+ /* Sanity check: */ |
|
+ REQUIRE(context != (isc_sha224_t *)0 && data != (isc_uint8_t*)0); |
|
+ |
|
+ DE_CONST(data, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_DigestUpdate, |
|
+ (context->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_sha224_final(isc_uint8_t digest[], isc_sha224_t *context) { |
|
+ CK_RV rv; |
|
+ CK_ULONG len = ISC_SHA224_DIGESTLENGTH; |
|
+ |
|
+ /* Sanity check: */ |
|
+ REQUIRE(context != (isc_sha224_t *)0); |
|
+ |
|
+ /* If no digest buffer is passed, we don't bother doing this: */ |
|
+ if (digest != (isc_uint8_t*)0) { |
|
+ PK11_FATALCHECK(pkcs_C_DigestFinal, |
|
+ (context->session, |
|
+ (CK_BYTE_PTR) digest, |
|
+ &len)); |
|
+ } else { |
|
+ CK_BYTE garbage[ISC_SHA224_DIGESTLENGTH]; |
|
+ |
|
+ (void) pkcs_C_DigestFinal(context->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ } |
|
+ pk11_return_session(context); |
|
+} |
|
+ |
|
+void |
|
+isc_sha256_init(isc_sha256_t *context) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_SHA256, NULL, 0 }; |
|
+ |
|
+ if (context == (isc_sha256_t *)0) { |
|
+ return; |
|
+ } |
|
+ RUNTIME_CHECK(pk11_get_session(context, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ PK11_FATALCHECK(pkcs_C_DigestInit, (context->session, &mech)); |
|
+} |
|
+ |
|
+void |
|
+isc_sha256_invalidate(isc_sha256_t *context) { |
|
+ CK_BYTE garbage[ISC_SHA256_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_SHA256_DIGESTLENGTH; |
|
+ |
|
+ if (context->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_DigestFinal(context->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ pk11_return_session(context); |
|
+} |
|
+ |
|
+void |
|
+isc_sha256_update(isc_sha256_t *context, const isc_uint8_t* data, size_t len) { |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ if (len == 0U) { |
|
+ /* Calling with no data is valid - we do nothing */ |
|
+ return; |
|
+ } |
|
+ |
|
+ /* Sanity check: */ |
|
+ REQUIRE(context != (isc_sha256_t *)0 && data != (isc_uint8_t*)0); |
|
+ |
|
+ DE_CONST(data, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_DigestUpdate, |
|
+ (context->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_sha256_final(isc_uint8_t digest[], isc_sha256_t *context) { |
|
+ CK_RV rv; |
|
+ CK_ULONG len = ISC_SHA256_DIGESTLENGTH; |
|
+ |
|
+ /* Sanity check: */ |
|
+ REQUIRE(context != (isc_sha256_t *)0); |
|
+ |
|
+ /* If no digest buffer is passed, we don't bother doing this: */ |
|
+ if (digest != (isc_uint8_t*)0) { |
|
+ PK11_FATALCHECK(pkcs_C_DigestFinal, |
|
+ (context->session, |
|
+ (CK_BYTE_PTR) digest, |
|
+ &len)); |
|
+ } else { |
|
+ CK_BYTE garbage[ISC_SHA256_DIGESTLENGTH]; |
|
+ |
|
+ (void) pkcs_C_DigestFinal(context->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ } |
|
+ pk11_return_session(context); |
|
+} |
|
+ |
|
+void |
|
+isc_sha512_init(isc_sha512_t *context) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_SHA512, NULL, 0 }; |
|
+ |
|
+ if (context == (isc_sha512_t *)0) { |
|
+ return; |
|
+ } |
|
+ RUNTIME_CHECK(pk11_get_session(context, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ PK11_FATALCHECK(pkcs_C_DigestInit, (context->session, &mech)); |
|
+} |
|
+ |
|
+void |
|
+isc_sha512_invalidate(isc_sha512_t *context) { |
|
+ CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_SHA512_DIGESTLENGTH; |
|
+ |
|
+ if (context->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_DigestFinal(context->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ pk11_return_session(context); |
|
+} |
|
+ |
|
+void |
|
+isc_sha512_update(isc_sha512_t *context, const isc_uint8_t* data, size_t len) { |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ if (len == 0U) { |
|
+ /* Calling with no data is valid - we do nothing */ |
|
+ return; |
|
+ } |
|
+ |
|
+ /* Sanity check: */ |
|
+ REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0); |
|
+ |
|
+ DE_CONST(data, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_DigestUpdate, |
|
+ (context->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) { |
|
+ CK_RV rv; |
|
+ CK_ULONG len = ISC_SHA512_DIGESTLENGTH; |
|
+ |
|
+ /* Sanity check: */ |
|
+ REQUIRE(context != (isc_sha512_t *)0); |
|
+ |
|
+ /* If no digest buffer is passed, we don't bother doing this: */ |
|
+ if (digest != (isc_uint8_t*)0) { |
|
+ PK11_FATALCHECK(pkcs_C_DigestFinal, |
|
+ (context->session, |
|
+ (CK_BYTE_PTR) digest, |
|
+ &len)); |
|
+ } else { |
|
+ CK_BYTE garbage[ISC_SHA512_DIGESTLENGTH]; |
|
+ |
|
+ (void) pkcs_C_DigestFinal(context->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ } |
|
+ pk11_return_session(context); |
|
+} |
|
+ |
|
+void |
|
+isc_sha384_init(isc_sha384_t *context) { |
|
+ CK_RV rv; |
|
+ CK_MECHANISM mech = { CKM_SHA384, NULL, 0 }; |
|
+ |
|
+ if (context == (isc_sha384_t *)0) { |
|
+ return; |
|
+ } |
|
+ RUNTIME_CHECK(pk11_get_session(context, OP_DIGEST, ISC_TRUE, ISC_FALSE, |
|
+ ISC_FALSE, NULL, 0) == ISC_R_SUCCESS); |
|
+ PK11_FATALCHECK(pkcs_C_DigestInit, (context->session, &mech)); |
|
+} |
|
+ |
|
+void |
|
+isc_sha384_invalidate(isc_sha384_t *context) { |
|
+ CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH]; |
|
+ CK_ULONG len = ISC_SHA384_DIGESTLENGTH; |
|
+ |
|
+ if (context->handle == NULL) |
|
+ return; |
|
+ (void) pkcs_C_DigestFinal(context->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ pk11_return_session(context); |
|
+} |
|
+ |
|
+void |
|
+isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) { |
|
+ CK_RV rv; |
|
+ CK_BYTE_PTR pPart; |
|
+ |
|
+ if (len == 0U) { |
|
+ /* Calling with no data is valid - we do nothing */ |
|
+ return; |
|
+ } |
|
+ |
|
+ /* Sanity check: */ |
|
+ REQUIRE(context != (isc_sha384_t *)0 && data != (isc_uint8_t*)0); |
|
+ |
|
+ DE_CONST(data, pPart); |
|
+ PK11_FATALCHECK(pkcs_C_DigestUpdate, |
|
+ (context->session, pPart, (CK_ULONG) len)); |
|
+} |
|
+ |
|
+void |
|
+isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) { |
|
+ CK_RV rv; |
|
+ CK_ULONG len = ISC_SHA384_DIGESTLENGTH; |
|
+ |
|
+ /* Sanity check: */ |
|
+ REQUIRE(context != (isc_sha384_t *)0); |
|
+ |
|
+ /* If no digest buffer is passed, we don't bother doing this: */ |
|
+ if (digest != (isc_uint8_t*)0) { |
|
+ PK11_FATALCHECK(pkcs_C_DigestFinal, |
|
+ (context->session, |
|
+ (CK_BYTE_PTR) digest, |
|
+ &len)); |
|
+ } else { |
|
+ CK_BYTE garbage[ISC_SHA384_DIGESTLENGTH]; |
|
+ |
|
+ (void) pkcs_C_DigestFinal(context->session, garbage, &len); |
|
+ memset(garbage, 0, sizeof(garbage)); |
|
+ } |
|
+ pk11_return_session(context); |
|
+} |
|
+ |
|
#else |
|
|
|
/* |
|
@@ -1312,6 +1583,8 @@ isc_sha224_end(isc_sha224_t *context, char buffer[]) { |
|
} else { |
|
#ifdef ISC_PLATFORM_OPENSSLHASH |
|
EVP_MD_CTX_cleanup(context); |
|
+#elif PKCS11CRYPTO |
|
+ pk11_return_session(context); |
|
#else |
|
memset(context, 0, sizeof(*context)); |
|
#endif |
|
@@ -1351,6 +1624,8 @@ isc_sha256_end(isc_sha256_t *context, char buffer[]) { |
|
} else { |
|
#ifdef ISC_PLATFORM_OPENSSLHASH |
|
EVP_MD_CTX_cleanup(context); |
|
+#elif PKCS11CRYPTO |
|
+ pk11_return_session(context); |
|
#else |
|
memset(context, 0, sizeof(*context)); |
|
#endif |
|
@@ -1390,6 +1665,8 @@ isc_sha512_end(isc_sha512_t *context, char buffer[]) { |
|
} else { |
|
#ifdef ISC_PLATFORM_OPENSSLHASH |
|
EVP_MD_CTX_cleanup(context); |
|
+#elif PKCS11CRYPTO |
|
+ pk11_return_session(context); |
|
#else |
|
memset(context, 0, sizeof(*context)); |
|
#endif |
|
@@ -1429,6 +1706,8 @@ isc_sha384_end(isc_sha384_t *context, char buffer[]) { |
|
} else { |
|
#ifdef ISC_PLATFORM_OPENSSLHASH |
|
EVP_MD_CTX_cleanup(context); |
|
+#elif PKCS11CRYPTO |
|
+ pk11_return_session(context); |
|
#else |
|
memset(context, 0, sizeof(*context)); |
|
#endif |
|
diff --git a/lib/isc/unix/Makefile.in b/lib/isc/unix/Makefile.in |
|
index c1411cb..0595fa2 100644 |
|
--- a/lib/isc/unix/Makefile.in |
|
+++ b/lib/isc/unix/Makefile.in |
|
@@ -29,14 +29,14 @@ CDEFINES = |
|
CWARNINGS = |
|
|
|
# Alphabetically |
|
-OBJS = @ISC_IPV6_O@ \ |
|
+OBJS = @ISC_IPV6_O@ @ISC_PK11_API_O@ \ |
|
app.@O@ dir.@O@ entropy.@O@ errno2result.@O@ file.@O@ \ |
|
fsaccess.@O@ interfaceiter.@O@ keyboard.@O@ net.@O@ \ |
|
os.@O@ resource.@O@ socket.@O@ stdio.@O@ stdtime.@O@ \ |
|
strerror.@O@ syslog.@O@ time.@O@ |
|
|
|
# Alphabetically |
|
-SRCS = @ISC_IPV6_C@ \ |
|
+SRCS = @ISC_IPV6_C@ @ISC_PK11_API_C@ \ |
|
app.c dir.c entropy.c errno2result.c file.c \ |
|
fsaccess.c interfaceiter.c keyboard.c net.c \ |
|
os.c resource.c socket.c stdio.c stdtime.c \ |
|
diff --git a/lib/isc/unix/include/Makefile.in b/lib/isc/unix/include/Makefile.in |
|
index 46c243e..354e6c8 100644 |
|
--- a/lib/isc/unix/include/Makefile.in |
|
+++ b/lib/isc/unix/include/Makefile.in |
|
@@ -19,7 +19,7 @@ srcdir = @srcdir@ |
|
VPATH = @srcdir@ |
|
top_srcdir = @top_srcdir@ |
|
|
|
-SUBDIRS = isc |
|
+SUBDIRS = isc pkcs11 |
|
TARGETS = |
|
|
|
@BIND9_MAKE_RULES@ |
|
diff --git a/lib/isc/unix/include/pkcs11/Makefile.in b/lib/isc/unix/include/pkcs11/Makefile.in |
|
new file mode 100644 |
|
index 0000000..8b175f4 |
|
--- /dev/null |
|
+++ b/lib/isc/unix/include/pkcs11/Makefile.in |
|
@@ -0,0 +1,33 @@ |
|
+# Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") |
|
+# |
|
+# Permission to use, copy, modify, and/or distribute this software for any |
|
+# purpose with or without fee is hereby granted, provided that the above |
|
+# copyright notice and this permission notice appear in all copies. |
|
+# |
|
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+# PERFORMANCE OF THIS SOFTWARE. |
|
+ |
|
+# $Id: Makefile.in,v 1.4 2007/06/19 23:47:23 tbox Exp $ |
|
+ |
|
+srcdir = @srcdir@ |
|
+VPATH = @srcdir@ |
|
+top_srcdir = @top_srcdir@ |
|
+ |
|
+HEADERS = cryptoki.h |
|
+SUBDIRS = |
|
+TARGETS = |
|
+ |
|
+@BIND9_MAKE_RULES@ |
|
+ |
|
+installdirs: |
|
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/pkcs11 |
|
+ |
|
+install:: installdirs |
|
+ for i in ${HEADERS}; do \ |
|
+ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/pkcs11 ; \ |
|
+ done |
|
diff --git a/lib/isc/unix/include/pkcs11/cryptoki.h b/lib/isc/unix/include/pkcs11/cryptoki.h |
|
new file mode 100644 |
|
index 0000000..7dc48b0 |
|
--- /dev/null |
|
+++ b/lib/isc/unix/include/pkcs11/cryptoki.h |
|
@@ -0,0 +1,66 @@ |
|
+/* cryptoki.h include file for PKCS #11. */ |
|
+/* |
|
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS |
|
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
|
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE |
|
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR |
|
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+/* $Revision: 1.3 $ */ |
|
+ |
|
+/* |
|
+ * Portions Copyright RSA Security Inc. |
|
+ * |
|
+ * License to copy and use this software is granted provided that it is |
|
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface |
|
+ * (Cryptoki)" in all material mentioning or referencing this software. |
|
+ |
|
+ * License is also granted to make and use derivative works provided that |
|
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11 |
|
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or |
|
+ * referencing the derived work. |
|
+ |
|
+ * RSA Security Inc. makes no representations concerning either the |
|
+ * merchantability of this software or the suitability of this software for |
|
+ * any particular purpose. It is provided "as is" without express or implied |
|
+ * warranty of any kind. |
|
+ */ |
|
+ |
|
+/* This is a sample file containing the top level include directives |
|
+ * for building Unix Cryptoki libraries and applications. |
|
+ */ |
|
+ |
|
+#ifndef ___CRYPTOKI_H_INC___ |
|
+#define ___CRYPTOKI_H_INC___ |
|
+ |
|
+#define CK_PTR * |
|
+ |
|
+#define CK_DEFINE_FUNCTION(returnType, name) \ |
|
+ returnType name |
|
+ |
|
+#define CK_DECLARE_FUNCTION(returnType, name) \ |
|
+ returnType name |
|
+ |
|
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \ |
|
+ returnType (* name) |
|
+ |
|
+#define CK_CALLBACK_FUNCTION(returnType, name) \ |
|
+ returnType (* name) |
|
+ |
|
+/* NULL is in unistd.h */ |
|
+#include <unistd.h> |
|
+#define NULL_PTR NULL |
|
+ |
|
+#undef CK_PKCS11_FUNCTION_INFO |
|
+ |
|
+#include <pkcs11/pkcs11.h> |
|
+ |
|
+#endif /* ___CRYPTOKI_H_INC___ */ |
|
diff --git a/lib/isc/unix/pk11_api.c b/lib/isc/unix/pk11_api.c |
|
new file mode 100644 |
|
index 0000000..9ccb959 |
|
--- /dev/null |
|
+++ b/lib/isc/unix/pk11_api.c |
|
@@ -0,0 +1,673 @@ |
|
+/* |
|
+ * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") |
|
+ * |
|
+ * Permission to use, copy, modify, and/or distribute this software for any |
|
+ * purpose with or without fee is hereby granted, provided that the above |
|
+ * copyright notice and this permission notice appear in all copies. |
|
+ * |
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH |
|
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
|
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, |
|
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
|
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE |
|
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
|
+ * PERFORMANCE OF THIS SOFTWARE. |
|
+ */ |
|
+ |
|
+/* $Id$ */ |
|
+ |
|
+/*! \file */ |
|
+ |
|
+#include <config.h> |
|
+ |
|
+#include <string.h> |
|
+#include <dlfcn.h> |
|
+ |
|
+#include <isc/log.h> |
|
+#include <isc/mem.h> |
|
+#include <isc/once.h> |
|
+#include <isc/stdio.h> |
|
+#include <isc/thread.h> |
|
+#include <isc/util.h> |
|
+ |
|
+#include <pkcs11/cryptoki.h> |
|
+#include <pkcs11/pkcs11.h> |
|
+ |
|
+#define KEEP_PKCS11_NAMES |
|
+#include <pk11/pk11.h> |
|
+#include <pk11/internal.h> |
|
+ |
|
+static void *hPK11 = NULL; |
|
+ |
|
+CK_RV |
|
+pkcs_C_Initialize(CK_VOID_PTR pReserved) { |
|
+ CK_C_Initialize sym; |
|
+ |
|
+ if (hPK11 != NULL) |
|
+ return (CKR_LIBRARY_ALREADY_INITIALIZED); |
|
+ |
|
+ hPK11 = dlopen(pk11_get_lib_name(), RTLD_NOW); |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ sym = (CK_C_Initialize)dlsym(hPK11, "C_Initialize"); |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(pReserved); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_Finalize(CK_VOID_PTR pReserved) { |
|
+ CK_C_Finalize sym; |
|
+ CK_RV rv; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ sym = (CK_C_Finalize)dlsym(hPK11, "C_Finalize"); |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ rv = (*sym)(pReserved); |
|
+ if ((rv == CKR_OK) && (dlclose(hPK11) != 0)) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ hPK11 = NULL; |
|
+ return (rv); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_GetSlotList(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, |
|
+ CK_ULONG_PTR pulCount) |
|
+{ |
|
+ static CK_C_GetSlotList sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_GetSlotList)dlsym(hPK11, "C_GetSlotList"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(tokenPresent, pSlotList, pulCount); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) { |
|
+ static CK_C_GetTokenInfo sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_GetTokenInfo)dlsym(hPK11, "C_GetTokenInfo"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(slotID, pInfo); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, |
|
+ CK_MECHANISM_INFO_PTR pInfo) |
|
+{ |
|
+ static CK_C_GetMechanismInfo sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_GetMechanismInfo)dlsym(hPK11, |
|
+ "C_GetMechanismInfo"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(slotID, type, pInfo); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, |
|
+ CK_VOID_PTR pApplication, |
|
+ CK_RV (*Notify) (CK_SESSION_HANDLE hSession, |
|
+ CK_NOTIFICATION event, |
|
+ CK_VOID_PTR pApplication), |
|
+ CK_SESSION_HANDLE_PTR phSession) |
|
+{ |
|
+ static CK_C_OpenSession sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ hPK11 = dlopen(pk11_get_lib_name(), RTLD_NOW); |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_OpenSession)dlsym(hPK11, "C_OpenSession"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(slotID, flags, pApplication, Notify, phSession); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_CloseSession(CK_SESSION_HANDLE hSession) { |
|
+ static CK_C_CloseSession sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_CloseSession)dlsym(hPK11, "C_CloseSession"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, |
|
+ CK_CHAR_PTR pPin, CK_ULONG usPinLen) |
|
+{ |
|
+ static CK_C_Login sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_Login)dlsym(hPK11, "C_Login"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, userType, pPin, usPinLen); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_Logout(CK_SESSION_HANDLE hSession) { |
|
+ static CK_C_Logout sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_Logout)dlsym(hPK11, "C_Logout"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_CreateObject(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, |
|
+ CK_ULONG usCount, CK_OBJECT_HANDLE_PTR phObject) |
|
+{ |
|
+ static CK_C_CreateObject sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_CreateObject)dlsym(hPK11, "C_CreateObject"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pTemplate, usCount, phObject); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject) { |
|
+ static CK_C_DestroyObject sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_DestroyObject)dlsym(hPK11, "C_DestroyObject"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, hObject); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, |
|
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) |
|
+{ |
|
+ static CK_C_GetAttributeValue sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_GetAttributeValue)dlsym(hPK11, |
|
+ "C_GetAttributeValue"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, hObject, pTemplate, usCount); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, |
|
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG usCount) |
|
+{ |
|
+ static CK_C_SetAttributeValue sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_SetAttributeValue)dlsym(hPK11, |
|
+ "C_SetAttributeValue"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, hObject, pTemplate, usCount); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_FindObjectsInit(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, |
|
+ CK_ULONG usCount) |
|
+{ |
|
+ static CK_C_FindObjectsInit sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_FindObjectsInit)dlsym(hPK11, "C_FindObjectsInit"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pTemplate, usCount); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, |
|
+ CK_ULONG usMaxObjectCount, CK_ULONG_PTR pusObjectCount) |
|
+{ |
|
+ static CK_C_FindObjects sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_FindObjects)dlsym(hPK11, "C_FindObjects"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, phObject, usMaxObjectCount, pusObjectCount); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_FindObjectsFinal(CK_SESSION_HANDLE hSession) |
|
+{ |
|
+ static CK_C_FindObjectsFinal sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_FindObjectsFinal)dlsym(hPK11, |
|
+ "C_FindObjectsFinal"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
|
+ CK_OBJECT_HANDLE hKey) |
|
+{ |
|
+ static CK_C_EncryptInit sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_EncryptInit)dlsym(hPK11, "C_EncryptInit"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pMechanism, hKey); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, |
|
+ CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, |
|
+ CK_ULONG_PTR pulEncryptedDataLen) |
|
+{ |
|
+ static CK_C_Encrypt sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_Encrypt)dlsym(hPK11, "C_Encrypt"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pData, ulDataLen, |
|
+ pEncryptedData, pulEncryptedDataLen); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_DigestInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism) { |
|
+ static CK_C_DigestInit sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_DigestInit)dlsym(hPK11, "C_DigestInit"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pMechanism); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_DigestUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, |
|
+ CK_ULONG ulPartLen) |
|
+{ |
|
+ static CK_C_DigestUpdate sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_DigestUpdate)dlsym(hPK11, "C_DigestUpdate"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pPart, ulPartLen); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, |
|
+ CK_ULONG_PTR pulDigestLen) |
|
+{ |
|
+ static CK_C_DigestFinal sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_DigestFinal)dlsym(hPK11, "C_DigestFinal"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pDigest, pulDigestLen); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
|
+ CK_OBJECT_HANDLE hKey) |
|
+{ |
|
+ static CK_C_SignInit sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_SignInit)dlsym(hPK11, "C_SignInit"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pMechanism, hKey); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, |
|
+ CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, |
|
+ CK_ULONG_PTR pulSignatureLen) |
|
+{ |
|
+ static CK_C_Sign sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_Sign)dlsym(hPK11, "C_Sign"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pData, ulDataLen, pSignature, pulSignatureLen); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, |
|
+ CK_ULONG ulPartLen) |
|
+{ |
|
+ static CK_C_SignUpdate sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_SignUpdate)dlsym(hPK11, "C_SignUpdate"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pPart, ulPartLen); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_SignFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, |
|
+ CK_ULONG_PTR pulSignatureLen) |
|
+{ |
|
+ static CK_C_SignFinal sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_SignFinal)dlsym(hPK11, "C_SignFinal"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pSignature, pulSignatureLen); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_VerifyInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
|
+ CK_OBJECT_HANDLE hKey) |
|
+{ |
|
+ static CK_C_VerifyInit sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_VerifyInit)dlsym(hPK11, "C_VerifyInit"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pMechanism, hKey); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, |
|
+ CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, |
|
+ CK_ULONG ulSignatureLen) |
|
+{ |
|
+ static CK_C_Verify sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_Verify)dlsym(hPK11, "C_Verify"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pData, ulDataLen, pSignature, ulSignatureLen); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_VerifyUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, |
|
+ CK_ULONG ulPartLen) |
|
+{ |
|
+ static CK_C_VerifyUpdate sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_VerifyUpdate)dlsym(hPK11, "C_VerifyUpdate"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pPart, ulPartLen); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_VerifyFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, |
|
+ CK_ULONG ulSignatureLen) |
|
+{ |
|
+ static CK_C_VerifyFinal sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_VerifyFinal)dlsym(hPK11, "C_VerifyFinal"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pSignature, ulSignatureLen); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
|
+ CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, |
|
+ CK_OBJECT_HANDLE_PTR phKey) |
|
+{ |
|
+ static CK_C_GenerateKey sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_GenerateKey)dlsym(hPK11, "C_GenerateKey"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pMechanism, pTemplate, ulCount, phKey); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_GenerateKeyPair(CK_SESSION_HANDLE hSession, |
|
+ CK_MECHANISM_PTR pMechanism, |
|
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, |
|
+ CK_ULONG usPublicKeyAttributeCount, |
|
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, |
|
+ CK_ULONG usPrivateKeyAttributeCount, |
|
+ CK_OBJECT_HANDLE_PTR phPrivateKey, |
|
+ CK_OBJECT_HANDLE_PTR phPublicKey) |
|
+{ |
|
+ static CK_C_GenerateKeyPair sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_GenerateKeyPair)dlsym(hPK11, "C_GenerateKeyPair"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, |
|
+ pMechanism, |
|
+ pPublicKeyTemplate, |
|
+ usPublicKeyAttributeCount, |
|
+ pPrivateKeyTemplate, |
|
+ usPrivateKeyAttributeCount, |
|
+ phPrivateKey, |
|
+ phPublicKey); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, |
|
+ CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, |
|
+ CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey) |
|
+{ |
|
+ static CK_C_DeriveKey sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_DeriveKey)dlsym(hPK11, "C_DeriveKey"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, |
|
+ pMechanism, |
|
+ hBaseKey, |
|
+ pTemplate, |
|
+ ulAttributeCount, |
|
+ phKey); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_SeedRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, |
|
+ CK_ULONG ulSeedLen) |
|
+{ |
|
+ static CK_C_SeedRandom sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_SeedRandom)dlsym(hPK11, "C_SeedRandom"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, pSeed, ulSeedLen); |
|
+} |
|
+ |
|
+CK_RV |
|
+pkcs_C_GenerateRandom(CK_SESSION_HANDLE hSession, CK_BYTE_PTR RandomData, |
|
+ CK_ULONG ulRandomLen) |
|
+{ |
|
+ static CK_C_GenerateRandom sym = NULL; |
|
+ static void *pPK11 = NULL; |
|
+ |
|
+ if (hPK11 == NULL) |
|
+ return (CKR_LIBRARY_FAILED_TO_LOAD); |
|
+ if ((sym == NULL) || (hPK11 != pPK11)) { |
|
+ pPK11 = hPK11; |
|
+ sym = (CK_C_GenerateRandom)dlsym(hPK11, "C_GenerateRandom"); |
|
+ } |
|
+ if (sym == NULL) |
|
+ return (CKR_SYMBOL_RESOLUTION_FAILED); |
|
+ return (*sym)(hSession, RandomData, ulRandomLen); |
|
+} |
|
-- |
|
2.1.0 |
|
|
|
|