summaryrefslogtreecommitdiff
path: root/security/nss/lib/ckfw
diff options
context:
space:
mode:
authorrelyea%netscape.com <devnull@localhost>2000-03-31 20:13:40 +0000
committerrelyea%netscape.com <devnull@localhost>2000-03-31 20:13:40 +0000
commit9502869e82d4f3ce26b292263e1c626dca3a34f3 (patch)
tree4d0f8ab157505b57c13a5e2bdf979560ab751527 /security/nss/lib/ckfw
parent222a52dab759085f56dcb6588b69a6a937d82aa2 (diff)
downloadnss-hg-9502869e82d4f3ce26b292263e1c626dca3a34f3.tar.gz
Initial NSS Open Source checkin
Diffstat (limited to 'security/nss/lib/ckfw')
-rw-r--r--security/nss/lib/ckfw/.cvsignore4
-rw-r--r--security/nss/lib/ckfw/Makefile46
-rw-r--r--security/nss/lib/ckfw/builtins/.cvsignore1
-rw-r--r--security/nss/lib/ckfw/builtins/Makefile43
-rw-r--r--security/nss/lib/ckfw/builtins/anchor.c50
-rw-r--r--security/nss/lib/ckfw/builtins/builtins.h103
-rw-r--r--security/nss/lib/ckfw/builtins/certdata.perl291
-rw-r--r--security/nss/lib/ckfw/builtins/certdata.txt143
-rw-r--r--security/nss/lib/ckfw/builtins/config.mk37
-rw-r--r--security/nss/lib/ckfw/builtins/constants.c81
-rw-r--r--security/nss/lib/ckfw/builtins/find.c242
-rw-r--r--security/nss/lib/ckfw/builtins/instance.c130
-rw-r--r--security/nss/lib/ckfw/builtins/manifest.mn53
-rw-r--r--security/nss/lib/ckfw/builtins/object.c254
-rw-r--r--security/nss/lib/ckfw/builtins/session.c108
-rw-r--r--security/nss/lib/ckfw/builtins/slot.c124
-rw-r--r--security/nss/lib/ckfw/builtins/token.c184
-rw-r--r--security/nss/lib/ckfw/ck.api571
-rw-r--r--security/nss/lib/ckfw/ck.h121
-rw-r--r--security/nss/lib/ckfw/ckapi.perl498
-rw-r--r--security/nss/lib/ckfw/ckfw.h1765
-rw-r--r--security/nss/lib/ckfw/ckfwm.h161
-rw-r--r--security/nss/lib/ckfw/ckfwtm.h56
-rw-r--r--security/nss/lib/ckfw/ckmd.h65
-rw-r--r--security/nss/lib/ckfw/ckt.h196
-rw-r--r--security/nss/lib/ckfw/config.mk37
-rw-r--r--security/nss/lib/ckfw/find.c408
-rw-r--r--security/nss/lib/ckfw/hash.c334
-rw-r--r--security/nss/lib/ckfw/instance.c1273
-rw-r--r--security/nss/lib/ckfw/manifest.mn76
-rw-r--r--security/nss/lib/ckfw/mutex.c346
-rw-r--r--security/nss/lib/ckfw/nssckfw.h499
-rw-r--r--security/nss/lib/ckfw/nssckfwc.h1046
-rw-r--r--security/nss/lib/ckfw/nssckfwt.h111
-rw-r--r--security/nss/lib/ckfw/nssckmdt.h2014
-rw-r--r--security/nss/lib/ckfw/nssckp.h66
-rw-r--r--security/nss/lib/ckfw/nssckt.h1117
-rw-r--r--security/nss/lib/ckfw/nsscku.h72
-rw-r--r--security/nss/lib/ckfw/object.c957
-rw-r--r--security/nss/lib/ckfw/session.c1651
-rw-r--r--security/nss/lib/ckfw/sessobj.c1096
-rw-r--r--security/nss/lib/ckfw/slot.c752
-rw-r--r--security/nss/lib/ckfw/token.c1859
-rw-r--r--security/nss/lib/ckfw/wrap.c3413
44 files changed, 22454 insertions, 0 deletions
diff --git a/security/nss/lib/ckfw/.cvsignore b/security/nss/lib/ckfw/.cvsignore
new file mode 100644
index 000000000..988228d5a
--- /dev/null
+++ b/security/nss/lib/ckfw/.cvsignore
@@ -0,0 +1,4 @@
+nssckepv.h
+nssckg.h
+nssckft.h
+nssck.api
diff --git a/security/nss/lib/ckfw/Makefile b/security/nss/lib/ckfw/Makefile
new file mode 100644
index 000000000..df7317052
--- /dev/null
+++ b/security/nss/lib/ckfw/Makefile
@@ -0,0 +1,46 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
+
+include manifest.mn
+include config.mk
+include $(CORE_DEPTH)/coreconf/config.mk
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+# This'll need some help from a build person.
+
+nssckepv.h: ck.api ckapi.perl
+nssckft.h: ck.api ckapi.perl
+nssckg.h: ck.api ckapi.perl
+ perl ckapi.perl < ck.api
+
diff --git a/security/nss/lib/ckfw/builtins/.cvsignore b/security/nss/lib/ckfw/builtins/.cvsignore
new file mode 100644
index 000000000..ccbbcce86
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/.cvsignore
@@ -0,0 +1 @@
+certdata.c
diff --git a/security/nss/lib/ckfw/builtins/Makefile b/security/nss/lib/ckfw/builtins/Makefile
new file mode 100644
index 000000000..31d5ab3fb
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/Makefile
@@ -0,0 +1,43 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+MAKEFILE_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
+
+include manifest.mn
+include config.mk
+include $(CORE_DEPTH)/coreconf/config.mk
+include $(CORE_DEPTH)/coreconf/rules.mk
+
+# This'll need some help from a build person.
+
+certdata.c: certdata.txt certdata.perl
+ perl certdata.perl < certdata.txt
diff --git a/security/nss/lib/ckfw/builtins/anchor.c b/security/nss/lib/ckfw/builtins/anchor.c
new file mode 100644
index 000000000..12c77a75c
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/anchor.c
@@ -0,0 +1,50 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * builtins/anchor.c
+ *
+ * This file "anchors" the actual cryptoki entry points in this module's
+ * shared library, which is required for dynamic loading. See the
+ * comments in nssck.api for more information.
+ */
+
+#include "builtins.h"
+
+#define MODULE_NAME builtins
+#define INSTANCE_NAME (NSSCKMDInstance *)&nss_builtins_mdInstance
+#include "nssck.api"
diff --git a/security/nss/lib/ckfw/builtins/builtins.h b/security/nss/lib/ckfw/builtins/builtins.h
new file mode 100644
index 000000000..b506ccdc0
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/builtins.h
@@ -0,0 +1,103 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char BUILTINS_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+#include "nssckmdt.h"
+#include "nssckfw.h"
+
+/*
+ * I'm including this for access to the arena functions.
+ * Looks like we should publish that API.
+ */
+#ifndef BASE_H
+#include "base.h"
+#endif /* BASE_H */
+
+/*
+ * This is where the Netscape extensions live, at least for now.
+ */
+#ifndef CKT_H
+#include "ckt.h"
+#endif /* CKT_H */
+
+struct builtinsInternalObjectStr {
+ CK_ULONG n;
+ CK_ATTRIBUTE_TYPE *types;
+ NSSItem *items;
+};
+typedef struct builtinsInternalObjectStr builtinsInternalObject;
+
+NSS_EXTERN_DATA const builtinsInternalObject nss_builtins_data[];
+NSS_EXTERN_DATA const PRUint32 nss_builtins_nObjects;
+
+NSS_EXTERN_DATA const CK_VERSION nss_builtins_CryptokiVersion;
+NSS_EXTERN_DATA const NSSUTF8 * nss_builtins_ManufacturerID;
+NSS_EXTERN_DATA const NSSUTF8 * nss_builtins_LibraryDescription;
+NSS_EXTERN_DATA const CK_VERSION nss_builtins_LibraryVersion;
+NSS_EXTERN_DATA const NSSUTF8 * nss_builtins_SlotDescription;
+NSS_EXTERN_DATA const CK_VERSION nss_builtins_HardwareVersion;
+NSS_EXTERN_DATA const CK_VERSION nss_builtins_FirmwareVersion;
+NSS_EXTERN_DATA const NSSUTF8 * nss_builtins_TokenLabel;
+NSS_EXTERN_DATA const NSSUTF8 * nss_builtins_TokenModel;
+NSS_EXTERN_DATA const NSSUTF8 * nss_builtins_TokenSerialNumber;
+
+NSS_EXTERN_DATA const NSSCKMDInstance nss_builtins_mdInstance;
+NSS_EXTERN_DATA const NSSCKMDSlot nss_builtins_mdSlot;
+NSS_EXTERN_DATA const NSSCKMDToken nss_builtins_mdToken;
+
+NSS_EXTERN NSSCKMDSession *
+nss_builtins_CreateSession
+(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+);
+
+NSS_EXTERN NSSCKMDFindObjects *
+nss_builtins_FindObjectsInit
+(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+);
+
+NSS_EXTERN NSSCKMDObject *
+nss_builtins_CreateMDObject
+(
+ NSSArena *arena,
+ builtinsInternalObject *io,
+ CK_RV *pError
+);
diff --git a/security/nss/lib/ckfw/builtins/certdata.perl b/security/nss/lib/ckfw/builtins/certdata.perl
new file mode 100644
index 000000000..5ccd2e5ad
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/certdata.perl
@@ -0,0 +1,291 @@
+#!perl -w
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+my $cvs_id = '@(#) $RCSfile$ $Revision$ $Date$ $Name$';
+use strict;
+
+my %constants;
+my $count = 0;
+my $o;
+my @objects = ();
+my @objsize;
+my $cvsid;
+
+$constants{CKO_DATA} = "static const CK_OBJECT_CLASS cko_data = CKO_DATA;\n";
+$constants{CK_TRUE} = "static const CK_BBOOL ck_true = CK_TRUE;\n";
+$constants{CK_FALSE} = "static const CK_BBOOL ck_false = CK_FALSE;\n";
+
+while(<>) {
+ my @fields = ();
+ my $size;
+
+ s/^((?:[^"#]+|"[^"]*")*)(\s*#.*$)/$1/;
+ next if (/^\s*$/);
+
+ if( /(^CVS_ID\s+)(.*)/ ) {
+# print "The CVS ID is $2\n";
+ $cvsid = $2 . "\"; $cvs_id\"";
+ my $scratch = $cvsid;
+ $size = 1 + $scratch =~ s/[^"\n]//g;
+ @{$objects[0][0]} = ( "CKA_CLASS", "&cko_data", "sizeof(CK_OBJECT_CLASS)" );
+ @{$objects[0][1]} = ( "CKA_TOKEN", "&ck_true", "sizeof(CK_BBOOL)" );
+ @{$objects[0][2]} = ( "CKA_PRIVATE", "&ck_false", "sizeof(CK_BBOOL)" );
+ @{$objects[0][3]} = ( "CKA_MODIFIABLE", "&ck_false", "sizeof(CK_BBOOL)" );
+ @{$objects[0][4]} = ( "CKA_LABEL", "\"CVS ID\"", "7" );
+ @{$objects[0][5]} = ( "CKA_APPLICATION", "\"NSS\"", "4" );
+ @{$objects[0][6]} = ( "CKA_VALUE", $cvsid, "$size" );
+ $objsize[0] = 7;
+ next;
+ }
+
+ # This was taken from the perl faq #4.
+ my $text = $_;
+ push(@fields, $+) while $text =~ m{
+ "([^\"\\]*(?:\\.[^\"\\]*)*)"\s? # groups the phrase inside the quotes
+ | ([^\s]+)\s?
+ | \s
+ }gx;
+ push(@fields, undef) if substr($text,-1,1) eq '\s';
+
+ if( $fields[0] =~ /BEGINDATA/ ) {
+ next;
+ }
+
+ if( $fields[1] =~ /MULTILINE/ ) {
+ $fields[2] = "";
+ while(<>) {
+ last if /END/;
+ chomp;
+ $fields[2] .= "\"$_\"\n";
+ }
+ }
+
+ if( $fields[1] =~ /UTF8/ ) {
+ if( $fields[2] =~ /^"/ ) {
+ ;
+ } else {
+ $fields[2] = "\"" . $fields[2] . "\"";
+ }
+
+ my $scratch = $fields[2];
+ $size = $scratch =~ s/[^"\n]//g; # should supposedly handle multilines, too..
+ $size += 1; # null terminate
+ }
+
+ if( $fields[1] =~ /OCTAL/ ) {
+ if( $fields[2] =~ /^"/ ) {
+ ;
+ } else {
+ $fields[2] = "\"" . $fields[2] . "\"";
+ }
+
+ my $scratch = $fields[2];
+ $size = $scratch =~ tr/\\//;
+ # no null termination
+ }
+
+ if( $fields[1] =~ /^CK_/ ) {
+ my $lcv = $fields[2];
+ $lcv =~ tr/A-Z/a-z/;
+ if( !defined($constants{$fields[2]}) ) {
+ $constants{$fields[2]} = "static const $fields[1] $lcv = $fields[2];\n";
+ }
+
+ $size = "sizeof($fields[1])";
+ $fields[2] = "&$lcv";
+ }
+
+ if( $fields[0] =~ /CKA_CLASS/ ) {
+ $count++;
+ $objsize[$count] = 0;
+ }
+
+ @{$objects[$count][$objsize[$count]++]} = ( "$fields[0]", $fields[2], "$size" );
+
+# print "$fields[0] | $fields[1] | $size | $fields[2]\n";
+}
+
+doprint();
+
+sub dudump {
+my $i;
+#for( $i = 0; $i <= $count; $i++ ) {
+# print "\n";
+# $o = $objects[$i];
+# my @ob = @{$o};
+# my $l;
+# my $j;
+# for( $j = 0; $j < @ob; $j++ ) {
+# $l = $ob[$j];
+# my @a = @{$l};
+# print "$a[0] ! $a[1] ! $a[2]\n";
+# }
+#}
+
+}
+
+sub doprint {
+my $i;
+
+open(CFILE, ">certdata.c") || die "Can't open certdata.c: $!";
+
+print CFILE <<EOD
+/* THIS IS A GENERATED FILE */
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+#ifdef DEBUG
+static const char CVS_ID[] = $cvsid;
+#endif /* DEBUG */
+
+#ifndef BUILTINS_H
+#include "builtins.h"
+#endif /* BUILTINS_H */
+
+EOD
+ ;
+
+while(($a,$b) = each(%constants)) {
+ print CFILE $b;
+}
+
+for( $i = 0; $i <= $count; $i++ ) {
+ if( 0 == $i ) {
+ print CFILE "#ifdef DEBUG\n";
+ }
+
+ print CFILE "static const CK_ATTRIBUTE_TYPE nss_builtins_types_$i [] = {\n";
+ $o = $objects[$i];
+ my @ob = @{$o};
+ my $j;
+ for( $j = 0; $j < @ob; $j++ ) {
+ my $l = $ob[$j];
+ my @a = @{$l};
+ print CFILE " $a[0]";
+ if( $j+1 != @ob ) {
+ print CFILE ", ";
+ }
+ }
+ print CFILE "\n};\n";
+
+ if( 0 == $i ) {
+ print CFILE "#endif /* DEBUG */\n";
+ }
+}
+
+for( $i = 0; $i <= $count; $i++ ) {
+ if( 0 == $i ) {
+ print CFILE "#ifdef DEBUG\n";
+ }
+
+ print CFILE "static const NSSItem nss_builtins_items_$i [] = {\n";
+ $o = $objects[$i];
+ my @ob = @{$o};
+ my $j;
+ for( $j = 0; $j < @ob; $j++ ) {
+ my $l = $ob[$j];
+ my @a = @{$l};
+ print CFILE " { (void *)$a[1], (PRUint32)$a[2] }";
+ if( $j+1 != @ob ) {
+ print CFILE ",\n";
+ } else {
+ print CFILE "\n";
+ }
+ }
+ print CFILE "};\n";
+
+ if( 0 == $i ) {
+ print CFILE "#endif /* DEBUG */\n";
+ }
+}
+
+print CFILE "\nPR_IMPLEMENT_DATA(const builtinsInternalObject)\n";
+print CFILE "nss_builtins_data[] = {\n";
+
+for( $i = 0; $i <= $count; $i++ ) {
+
+ if( 0 == $i ) {
+ print CFILE "#ifdef DEBUG\n";
+ }
+
+ print CFILE " { $objsize[$i], nss_builtins_types_$i, nss_builtins_items_$i }";
+
+ if( $i == $count ) {
+ print CFILE "\n";
+ } else {
+ print CFILE ",\n";
+ }
+
+ if( 0 == $i ) {
+ print CFILE "#endif /* DEBUG */\n";
+ }
+}
+
+print CFILE "};\n";
+
+print CFILE "PR_IMPLEMENT_DATA(const PRUint32)\n";
+print CFILE "#ifdef DEBUG\n";
+print CFILE " nss_builtins_nObjects = $count+1;\n";
+print CFILE "#else\n";
+print CFILE " nss_builtins_nObjects = $count;\n";
+print CFILE "#endif /* DEBUG */\n";
+}
diff --git a/security/nss/lib/ckfw/builtins/certdata.txt b/security/nss/lib/ckfw/builtins/certdata.txt
new file mode 100644
index 000000000..355993a29
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/certdata.txt
@@ -0,0 +1,143 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+CVS_ID "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
+
+#
+# certdata.txt
+#
+# This file contains the object definitions for the certs and other
+# information "built into" NSS.
+#
+# Object definitions:
+#
+# Certificates
+#
+# -- Attribute -- -- type -- -- value --
+# CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
+# CKA_TOKEN CK_BBOOL CK_TRUE
+# CKA_PRIVATE CK_BBOOL CK_FALSE
+# CKA_MODIFIABLE CK_BBOOL CK_FALSE
+# CKA_LABEL UTF8 (varies)
+# CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+# CKA_SUBJECT DER+base64 (varies)
+# CKA_ID byte array (varies)
+# CKA_ISSUER DER+base64 (varies)
+# CKA_SERIAL_NUMBER DER+base64 (varies)
+# CKA_VALUE DER+base64 (varies)
+# CKA_NETSCAPE_EMAIL ASCII7 (unused here)
+#
+# Trust
+#
+# -- Attribute -- -- type -- -- value --
+# CKA_CLASS CK_OBJECT_CLASS CKO_TRUST
+# CKA_TOKEN CK_BBOOL CK_TRUE
+# CKA_PRIVATE CK_BBOOL CK_FALSE
+# CKA_MODIFIABLE CK_BBOOL CK_FALSE
+# CKA_LABEL UTF8 (varies)
+# CKA_ISSUER DER+base64 (varies)
+# CKA_SERIAL_NUMBER DER+base64 (varies)
+# CKA_CERT_HASH binary+base64 (varies)
+# CKA_EXPIRES CK_DATE (not used here)
+# CKA_TRUST_DIGITAL_SIGNATURE CK_TRUST (varies)
+# CKA_TRUST_NON_REPUDIATION CK_TRUST (varies)
+# CKA_TRUST_KEY_ENCIPHERMENT CK_TRUST (varies)
+# CKA_TRUST_DATA_ENCIPHERMENT CK_TRUST (varies)
+# CKA_TRUST_KEY_AGREEMENT CK_TRUST (varies)
+# CKA_TRUST_KEY_CERT_SIGN CK_TRUST (varies)
+# CKA_TRUST_CRL_SIGN CK_TRUST (varies)
+# CKA_TRUST_SERVER_AUTH CK_TRUST (varies)
+# CKA_TRUST_CLIENT_AUTH CK_TRUST (varies)
+# CKA_TRUST_CODE_SIGNING CK_TRUST (varies)
+# CKA_TRUST_EMAIL_PROTECTION CK_TRUST (varies)
+# CKA_TRUST_IPSEC_END_SYSTEM CK_TRUST (varies)
+# CKA_TRUST_IPSEC_TUNNEL CK_TRUST (varies)
+# CKA_TRUST_IPSEC_USER CK_TRUST (varies)
+# CKA_TRUST_TIME_STAMPING CK_TRUST (varies)
+# (other trust attributes can be defined)
+#
+
+BEGINDATA
+
+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "Test certificate #3"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\201\243\061\013\060\011\006\003\125\004\006\023\002\125\123
+\061\013\060\011\006\003\125\004\010\023\002\103\101\061\023\060
+\021\006\012\011\222\046\211\223\362\054\144\001\001\023\003\155
+\142\146\061\034\060\032\006\003\125\004\013\023\023\111\156\144
+\165\163\164\162\151\141\154\040\114\151\147\150\164\151\156\147
+\061\033\060\031\006\003\125\004\012\023\022\115\157\156\153\145
+\171\142\165\164\164\145\162\040\106\141\162\155\163\061\037\060
+\035\006\011\052\206\110\206\367\015\001\011\001\026\020\152\157
+\145\100\156\145\164\163\143\141\160\145\056\156\145\164\061\026
+\060\024\006\003\125\004\003\023\015\144\165\155\160\143\145\162
+\164\040\164\145\163\164
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\064\061\030\060\026\006\003\125\004\012\023\017\103\145\162
+\164\055\117\055\115\141\164\151\143\040\111\111\061\030\060\026
+\006\003\125\004\003\023\017\103\145\162\164\055\117\055\115\141
+\164\151\143\040\111\111
+END
+CKA_SERIAL_NUMBER OCTAL \001\276
+CKA_VALUE MULTILINE_OCTAL
+\0
+END
+
+CKA_CLASS CK_OBJECT_CLASS CKO_NETSCAPE_TRUST
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "Test certificate #3"
+CKA_ISSUER MULTILINE_OCTAL
+\060\064\061\030\060\026\006\003\125\004\012\023\017\103\145\162
+\164\055\117\055\115\141\164\151\143\040\111\111\061\030\060\026
+\006\003\125\004\003\023\017\103\145\162\164\055\117\055\115\141
+\164\151\143\040\111\111
+END
+CKA_SERIAL_NUMBER OCTAL \001\276
+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED
+CKA_TRUST_CLIENT_AUTH CK_TRUST CKT_NETSCAPE_TRUSTED
+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NETSCAPE_TRUSTED
+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NETSCAPE_TRUSTED
+CKA_TRUST_DIGITAL_SIGNATURE CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR
+CKA_TRUST_NON_REPUDIATION CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR
+CKA_TRUST_KEY_ENCIPHERMENT CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR
+CKA_TRUST_DATA_ENCIPHERMENT CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR
+CKA_TRUST_KEY_AGREEMENT CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR
+CKA_TRUST_KEY_CERT_SIGN CK_TRUST CKT_NETSCAPE_TRUSTED_DELEGATOR
diff --git a/security/nss/lib/ckfw/builtins/config.mk b/security/nss/lib/ckfw/builtins/config.mk
new file mode 100644
index 000000000..80b3135f4
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/config.mk
@@ -0,0 +1,37 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
+
+ifdef BUILD_IDG
+DEFINES += -DNSSDEBUG
+endif
diff --git a/security/nss/lib/ckfw/builtins/constants.c b/security/nss/lib/ckfw/builtins/constants.c
new file mode 100644
index 000000000..a04481b84
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/constants.c
@@ -0,0 +1,81 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * builtins/constants.c
+ *
+ * Identification and other constants, all collected here in one place.
+ */
+
+#ifndef NSSBASET_H
+#include "nssbaset.h"
+#endif /* NSSBASET_H */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+NSS_IMPLEMENT_DATA const CK_VERSION
+nss_builtins_CryptokiVersion = { 2, 1 };
+
+NSS_IMPLEMENT_DATA const NSSUTF8 *
+nss_builtins_ManufacturerID = "Netscape Communications Corp.";
+
+NSS_IMPLEMENT_DATA const NSSUTF8 *
+nss_builtins_LibraryDescription = "NSS Builtin Object Cryptoki Module";
+
+NSS_IMPLEMENT_DATA const CK_VERSION
+nss_builtins_LibraryVersion = { 1, 0 };
+
+NSS_IMPLEMENT_DATA const NSSUTF8 *
+nss_builtins_SlotDescription = "";
+
+NSS_IMPLEMENT_DATA const CK_VERSION
+nss_builtins_HardwareVersion = { 1, 0 };
+
+NSS_IMPLEMENT_DATA const CK_VERSION
+nss_builtins_FirmwareVersion = { 1, 0 };
+
+NSS_IMPLEMENT_DATA const NSSUTF8 *
+nss_builtins_TokenLabel = "Builtin Object Token";
+
+NSS_IMPLEMENT_DATA const NSSUTF8 *
+nss_builtins_TokenModel = "1";
+
+NSS_IMPLEMENT_DATA const NSSUTF8 *
+nss_builtins_TokenSerialNumber = "1";
+
diff --git a/security/nss/lib/ckfw/builtins/find.c b/security/nss/lib/ckfw/builtins/find.c
new file mode 100644
index 000000000..693a14f48
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/find.c
@@ -0,0 +1,242 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+#ifndef BUILTINS_H
+#include "builtins.h"
+#endif /* BUILTINS_H */
+
+/*
+ * builtins/find.c
+ *
+ * This file implements the NSSCKMDFindObjects object for the
+ * "builtin objects" cryptoki module.
+ */
+
+struct builtinsFOStr {
+ NSSArena *arena;
+ CK_ULONG n;
+ CK_ULONG i;
+ builtinsInternalObject **objs;
+};
+
+static void
+builtins_mdFindObjects_Final
+(
+ NSSCKMDFindObjects *mdFindObjects,
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
+
+ nss_ZFreeIf(fo->objs);
+ nss_ZFreeIf(fo);
+
+ return;
+}
+
+static NSSCKMDObject *
+builtins_mdFindObjects_Next
+(
+ NSSCKMDFindObjects *mdFindObjects,
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError
+)
+{
+ struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
+ builtinsInternalObject *io;
+
+ if( fo->i == fo->n ) {
+ *pError = CKR_OK;
+ return (NSSCKMDObject *)NULL;
+ }
+
+ io = fo->objs[ fo->i ];
+ fo->i++;
+
+ return nss_builtins_CreateMDObject(arena, io, pError);
+}
+
+static CK_BBOOL
+builtins_attrmatch
+(
+ CK_ATTRIBUTE_PTR a,
+ NSSItem *b
+)
+{
+ PRBool prb;
+
+ if( a->ulValueLen != b->size ) {
+ return CK_FALSE;
+ }
+
+ prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
+
+ if( PR_TRUE == prb ) {
+ return CK_TRUE;
+ } else {
+ return CK_FALSE;
+ }
+}
+
+
+static CK_BBOOL
+builtins_match
+(
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ builtinsInternalObject *o
+)
+{
+ CK_ULONG i;
+
+ for( i = 0; i < ulAttributeCount; i++ ) {
+ CK_ULONG j;
+
+ for( j = 0; j < o->n; j++ ) {
+ if( o->types[j] == pTemplate[i].type ) {
+ if( CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j]) ) {
+ return CK_FALSE;
+ } else {
+ break;
+ }
+ }
+ }
+
+ if( j == o->n ) {
+ /* Loop ran to the end: no matching attribute */
+ return CK_FALSE;
+ }
+ }
+
+ /* Every attribute passed */
+ return CK_TRUE;
+}
+
+NSS_IMPLEMENT NSSCKMDFindObjects *
+nss_builtins_FindObjectsInit
+(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+)
+{
+ /* This could be made more efficient. I'm rather rushed. */
+ NSSArena *arena;
+ NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
+ struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL;
+ builtinsInternalObject **temp = (builtinsInternalObject **)NULL;
+ PRUint32 i;
+
+ arena = NSSCKFWSession_GetArena(fwSession, pError);
+ if( (NSSArena *)NULL == arena ) {
+ goto loser;
+ }
+
+ rv = nss_ZNEW(arena, NSSCKMDFindObjects);
+ if( (NSSCKMDFindObjects *)NULL == rv ) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ fo = nss_ZNEW(arena, struct builtinsFOStr);
+ if( (struct builtinsFOStr *)NULL == fo ) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ fo->arena = arena;
+ /* fo->n and fo->i are already zero */
+
+ rv->etc = (void *)fo;
+ rv->Final = builtins_mdFindObjects_Final;
+ rv->Next = builtins_mdFindObjects_Next;
+ rv->null = (void *)NULL;
+
+ temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
+ nss_builtins_nObjects);
+ if( (builtinsInternalObject **)NULL == temp ) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ for( i = 0; i < nss_builtins_nObjects; i++ ) {
+ builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i];
+
+ if( CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o) ) {
+ temp[ fo->n ] = o;
+ fo->n++;
+ }
+ }
+
+ if( 0 == fo->n ) {
+ *pError = CKR_OK;
+ goto loser;
+ }
+
+ fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n);
+ if( (builtinsInternalObject **)NULL == temp ) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ (void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n);
+ nss_ZFreeIf(temp);
+ temp = (builtinsInternalObject **)NULL;
+
+ return rv;
+
+ loser:
+ nss_ZFreeIf(temp);
+ nss_ZFreeIf(fo);
+ nss_ZFreeIf(rv);
+ return (NSSCKMDFindObjects *)NULL;
+}
+
diff --git a/security/nss/lib/ckfw/builtins/instance.c b/security/nss/lib/ckfw/builtins/instance.c
new file mode 100644
index 000000000..e97c0d4bf
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/instance.c
@@ -0,0 +1,130 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+#include "builtins.h"
+
+/*
+ * builtins/instance.c
+ *
+ * This file implements the NSSCKMDInstance object for the
+ * "builtin objects" cryptoki module.
+ */
+
+/*
+ * NSSCKMDInstance methods
+ */
+
+static CK_ULONG
+builtins_mdInstance_GetNSlots
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (CK_ULONG)1;
+}
+
+static CK_VERSION
+builtins_mdInstance_GetCryptokiVersion
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return nss_builtins_CryptokiVersion;
+}
+
+static NSSUTF8 *
+builtins_mdInstance_GetManufacturerID
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_builtins_ManufacturerID;
+}
+
+static NSSUTF8 *
+builtins_mdInstance_GetLibraryDescription
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_builtins_LibraryDescription;
+}
+
+static CK_VERSION
+builtins_mdInstance_GetLibraryVersion
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return nss_builtins_LibraryVersion;
+}
+
+static CK_RV
+builtins_mdInstance_GetSlots
+(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDSlot *slots[]
+)
+{
+ slots[0] = (NSSCKMDSlot *)&nss_builtins_mdSlot;
+ return CKR_OK;
+}
+
+NSS_IMPLEMENT_DATA const NSSCKMDInstance
+nss_builtins_mdInstance = {
+ (void *)NULL, /* etc */
+ NULL, /* Initialize */
+ NULL, /* Finalize */
+ builtins_mdInstance_GetNSlots,
+ builtins_mdInstance_GetCryptokiVersion,
+ builtins_mdInstance_GetManufacturerID,
+ builtins_mdInstance_GetLibraryDescription,
+ builtins_mdInstance_GetLibraryVersion,
+ NULL, /* ModuleHandlesSessionObjects -- defaults to false */
+ builtins_mdInstance_GetSlots,
+ NULL, /* WaitForSlotEvent */
+ (void *)NULL /* null terminator */
+};
diff --git a/security/nss/lib/ckfw/builtins/manifest.mn b/security/nss/lib/ckfw/builtins/manifest.mn
new file mode 100644
index 000000000..e40acd83c
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/manifest.mn
@@ -0,0 +1,53 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
+
+CORE_DEPTH = ../../../..
+
+MODULE = security
+
+CSRCS = \
+ anchor.c \
+ constants.c \
+ find.c \
+ instance.c \
+ object.c \
+ session.c \
+ slot.c \
+ token.c \
+ certdata.c \
+ $(NULL)
+
+REQUIRES = security nspr
+
+LIBRARY_NAME = nssckbi
diff --git a/security/nss/lib/ckfw/builtins/object.c b/security/nss/lib/ckfw/builtins/object.c
new file mode 100644
index 000000000..18cefda8a
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/object.c
@@ -0,0 +1,254 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+#include "builtins.h"
+
+/*
+ * builtins/object.c
+ *
+ * This file implements the NSSCKMDObject object for the
+ * "builtin objects" cryptoki module.
+ */
+
+/*
+ * Finalize - unneeded
+ * Destroy - CKR_SESSION_READ_ONLY
+ * IsTokenObject - CK_TRUE
+ * GetAttributeCount
+ * GetAttributeTypes
+ * GetAttributeSize
+ * GetAttribute
+ * SetAttribute - unneeded
+ * GetObjectSize
+ */
+
+static CK_RV
+builtins_mdObject_Destroy
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return CKR_SESSION_READ_ONLY;
+}
+
+static CK_BBOOL
+builtins_mdObject_IsTokenObject
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return CK_TRUE;
+}
+
+static CK_ULONG
+builtins_mdObject_GetAttributeCount
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
+ return io->n;
+}
+
+static CK_RV
+builtins_mdObject_GetAttributeTypes
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE_PTR typeArray,
+ CK_ULONG ulCount
+)
+{
+ builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
+ CK_ULONG i;
+
+ if( io->n != ulCount ) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ for( i = 0; i < io->n; i++ ) {
+ typeArray[i] = io->types[i];
+ }
+
+ return CKR_OK;
+}
+
+static CK_ULONG
+builtins_mdObject_GetAttributeSize
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+)
+{
+ builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
+ CK_ULONG i;
+
+ for( i = 0; i < io->n; i++ ) {
+ if( attribute == io->types[i] ) {
+ return (CK_ULONG)(io->items[i].size);
+ }
+ }
+
+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
+ return 0;
+}
+
+static NSSItem *
+builtins_mdObject_GetAttribute
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+)
+{
+ builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
+ CK_ULONG i;
+
+ for( i = 0; i < io->n; i++ ) {
+ if( attribute == io->types[i] ) {
+ return &io->items[i];
+ }
+ }
+
+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
+ return (NSSItem *)NULL;
+}
+
+static CK_ULONG
+builtins_mdObject_GetObjectSize
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ builtinsInternalObject *io = (builtinsInternalObject *)mdObject->etc;
+ CK_ULONG i;
+ CK_ULONG rv = sizeof(CK_ULONG);
+
+ for( i = 0; i < io->n; i++ ) {
+ rv += sizeof(CK_ATTRIBUTE_TYPE) + sizeof(NSSItem) + io->items[i].size;
+ }
+
+ return rv;
+}
+
+static NSSCKMDObject
+builtins_prototype_mdObject = {
+ (void *)NULL, /* etc */
+ NULL, /* Finalize */
+ builtins_mdObject_Destroy,
+ builtins_mdObject_IsTokenObject,
+ builtins_mdObject_GetAttributeCount,
+ builtins_mdObject_GetAttributeTypes,
+ builtins_mdObject_GetAttributeSize,
+ builtins_mdObject_GetAttribute,
+ NULL, /* SetAttribute */
+ builtins_mdObject_GetObjectSize,
+ (void *)NULL /* null terminator */
+};
+
+NSS_IMPLEMENT NSSCKMDObject *
+nss_builtins_CreateMDObject
+(
+ NSSArena *arena,
+ builtinsInternalObject *io,
+ CK_RV *pError
+)
+{
+ NSSCKMDObject *rv;
+
+ rv = nss_ZNEW(arena, NSSCKMDObject);
+ if( (NSSCKMDObject *)NULL == rv ) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKMDObject *)NULL;
+ }
+
+ *rv = builtins_prototype_mdObject;
+ rv->etc = (void *)io;
+
+ return rv;
+}
diff --git a/security/nss/lib/ckfw/builtins/session.c b/security/nss/lib/ckfw/builtins/session.c
new file mode 100644
index 000000000..e8d7f7522
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/session.c
@@ -0,0 +1,108 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+#include "builtins.h"
+
+/*
+ * builtins/session.c
+ *
+ * This file implements the NSSCKMDSession object for the
+ * "builtin objects" cryptoki module.
+ */
+
+static NSSCKMDFindObjects *
+builtins_mdSession_FindObjectsInit
+(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+)
+{
+ return nss_builtins_FindObjectsInit(fwSession, pTemplate, ulAttributeCount, pError);
+}
+
+NSS_IMPLEMENT NSSCKMDSession *
+nss_builtins_CreateSession
+(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+)
+{
+ NSSArena *arena;
+ NSSCKMDSession *rv;
+
+ arena = NSSCKFWSession_GetArena(fwSession, pError);
+ if( (NSSArena *)NULL == arena ) {
+ return (NSSCKMDSession *)NULL;
+ }
+
+ rv = nss_ZNEW(arena, NSSCKMDSession);
+ if( (NSSCKMDSession *)NULL == rv ) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKMDSession *)NULL;
+ }
+
+ /*
+ * rv was zeroed when allocated, so we only
+ * need to set the non-zero members.
+ */
+
+ rv->etc = (void *)fwSession;
+ /* rv->Close */
+ /* rv->GetDeviceError */
+ /* rv->Login */
+ /* rv->Logout */
+ /* rv->InitPIN */
+ /* rv->SetPIN */
+ /* rv->GetOperationStateLen */
+ /* rv->GetOperationState */
+ /* rv->SetOperationState */
+ /* rv->CreateObject */
+ /* rv->CopyObject */
+ rv->FindObjectsInit = builtins_mdSession_FindObjectsInit;
+ /* rv->SeedRandom */
+ /* rv->GetRandom */
+ /* rv->null */
+
+ return rv;
+}
diff --git a/security/nss/lib/ckfw/builtins/slot.c b/security/nss/lib/ckfw/builtins/slot.c
new file mode 100644
index 000000000..1a2df9e70
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/slot.c
@@ -0,0 +1,124 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+#include "builtins.h"
+
+/*
+ * builtins/slot.c
+ *
+ * This file implements the NSSCKMDSlot object for the
+ * "builtin objects" cryptoki module.
+ */
+
+static NSSUTF8 *
+builtins_mdSlot_GetSlotDescription
+(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_builtins_SlotDescription;
+}
+
+static NSSUTF8 *
+builtins_mdSlot_GetManufacturerID
+(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_builtins_ManufacturerID;
+}
+
+static CK_VERSION
+builtins_mdSlot_GetHardwareVersion
+(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return nss_builtins_HardwareVersion;
+}
+
+static CK_VERSION
+builtins_mdSlot_GetFirmwareVersion
+(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return nss_builtins_FirmwareVersion;
+}
+
+static NSSCKMDToken *
+builtins_mdSlot_GetToken
+(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSCKMDToken *)&nss_builtins_mdToken;
+}
+
+NSS_IMPLEMENT_DATA const NSSCKMDSlot
+nss_builtins_mdSlot = {
+ (void *)NULL, /* etc */
+ NULL, /* Initialize */
+ NULL, /* Destroy */
+ builtins_mdSlot_GetSlotDescription,
+ builtins_mdSlot_GetManufacturerID,
+ NULL, /* GetTokenPresent -- defaults to true */
+ NULL, /* GetRemovableDevice -- defaults to false */
+ NULL, /* GetHardwareSlot -- defaults to false */
+ builtins_mdSlot_GetHardwareVersion,
+ builtins_mdSlot_GetFirmwareVersion,
+ builtins_mdSlot_GetToken,
+ (void *)NULL /* null terminator */
+};
diff --git a/security/nss/lib/ckfw/builtins/token.c b/security/nss/lib/ckfw/builtins/token.c
new file mode 100644
index 000000000..ddf068e8e
--- /dev/null
+++ b/security/nss/lib/ckfw/builtins/token.c
@@ -0,0 +1,184 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+#include "builtins.h"
+
+/*
+ * builtins/token.c
+ *
+ * This file implements the NSSCKMDToken object for the
+ * "builtin objects" cryptoki module.
+ */
+
+static NSSUTF8 *
+builtins_mdToken_GetLabel
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_builtins_TokenLabel;
+}
+
+static NSSUTF8 *
+builtins_mdToken_GetManufacturerID
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_builtins_ManufacturerID;
+}
+
+static NSSUTF8 *
+builtins_mdToken_GetModel
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_builtins_TokenModel;
+}
+
+static NSSUTF8 *
+builtins_mdToken_GetSerialNumber
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ return (NSSUTF8 *)nss_builtins_TokenSerialNumber;
+}
+
+static CK_BBOOL
+builtins_mdToken_GetIsWriteProtected
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return CK_TRUE;
+}
+
+static CK_VERSION
+builtins_mdToken_GetHardwareVersion
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return nss_builtins_HardwareVersion;
+}
+
+static CK_VERSION
+builtins_mdToken_GetFirmwareVersion
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ return nss_builtins_FirmwareVersion;
+}
+
+static NSSCKMDSession *
+builtins_mdToken_OpenSession
+(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWSession *fwSession,
+ CK_BBOOL rw,
+ CK_RV *pError
+)
+{
+ return nss_builtins_CreateSession(fwSession, pError);
+}
+
+NSS_IMPLEMENT_DATA const NSSCKMDToken
+nss_builtins_mdToken = {
+ (void *)NULL, /* etc */
+ NULL, /* Setup */
+ NULL, /* Invalidate */
+ NULL, /* InitToken -- default errs */
+ builtins_mdToken_GetLabel,
+ builtins_mdToken_GetManufacturerID,
+ builtins_mdToken_GetModel,
+ builtins_mdToken_GetSerialNumber,
+ NULL, /* GetHasRNG -- default is false */
+ builtins_mdToken_GetIsWriteProtected,
+ NULL, /* GetLoginRequired -- default is false */
+ NULL, /* GetUserPinInitialized -- default is false */
+ NULL, /* GetRestoreKeyNotNeeded -- irrelevant */
+ NULL, /* GetHasClockOnToken -- default is false */
+ NULL, /* GetHasProtectedAuthenticationPath -- default is false */
+ NULL, /* GetSupportsDualCryptoOperations -- default is false */
+ NULL, /* GetMaxSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
+ NULL, /* GetMaxRwSessionCount -- default is CK_UNAVAILABLE_INFORMATION */
+ NULL, /* GetMaxPinLen -- irrelevant */
+ NULL, /* GetMinPinLen -- irrelevant */
+ NULL, /* GetTotalPublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
+ NULL, /* GetFreePublicMemory -- default is CK_UNAVAILABLE_INFORMATION */
+ NULL, /* GetTotalPrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
+ NULL, /* GetFreePrivateMemory -- default is CK_UNAVAILABLE_INFORMATION */
+ builtins_mdToken_GetHardwareVersion,
+ builtins_mdToken_GetFirmwareVersion,
+ NULL, /* GetUTCTime -- no clock */
+ builtins_mdToken_OpenSession,
+ NULL, /* GetMechanismCount -- default is zero */
+ NULL, /* GetMechanismTypes -- irrelevant */
+ NULL, /* GetMechanism -- irrelevant */
+ (void *)NULL /* null terminator */
+};
diff --git a/security/nss/lib/ckfw/ck.api b/security/nss/lib/ckfw/ck.api
new file mode 100644
index 000000000..6bae20fd3
--- /dev/null
+++ b/security/nss/lib/ckfw/ck.api
@@ -0,0 +1,571 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+
+# This file is in part derived from a file "pkcs11f.h" made available
+# by RSA Security at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/pkcs11f.h
+
+CVS_ID "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
+
+# Fields
+# FUNCTION introduces a Cryptoki function
+# CK_type specifies and introduces an argument
+#
+
+# General-purpose
+
+# C_Initialize initializes the Cryptoki library.
+FUNCTION C_Initialize
+CK_VOID_PTR pInitArgs # if this is not NULL_PTR, it gets
+ # cast to CK_C_INITIALIZE_ARGS_PTR
+ # and dereferenced
+
+# C_Finalize indicates that an application is done with the
+# Cryptoki library.
+FUNCTION C_Finalize
+CK_VOID_PTR pReserved # reserved. Should be NULL_PTR
+
+# C_GetInfo returns general information about Cryptoki.
+FUNCTION C_GetInfo
+CK_INFO_PTR pInfo # location that receives information
+
+# C_GetFunctionList returns the function list.
+FUNCTION C_GetFunctionList
+CK_FUNCTION_LIST_PTR_PTR ppFunctionList # receives pointer to function
+ # list
+
+
+# Slot and token management
+
+# C_GetSlotList obtains a list of slots in the system.
+FUNCTION C_GetSlotList
+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
+
+# C_GetSlotInfo obtains information about a particular slot in the
+# system.
+FUNCTION C_GetSlotInfo
+CK_SLOT_ID slotID # the ID of the slot
+CK_SLOT_INFO_PTR pInfo # receives the slot information
+
+# C_GetTokenInfo obtains information about a particular token in the
+# system.
+FUNCTION C_GetTokenInfo
+CK_SLOT_ID slotID # ID of the token's slot
+CK_TOKEN_INFO_PTR pInfo # receives the token information
+
+# C_GetMechanismList obtains a list of mechanism types supported by a
+# token.
+FUNCTION C_GetMechanismList
+CK_SLOT_ID slotID # ID of token's slot
+CK_MECHANISM_TYPE_PTR pMechanismList # gets mech. array
+CK_ULONG_PTR pulCount # gets # of mechs.
+
+# C_GetMechanismInfo obtains information about a particular mechanism
+# possibly supported by a token.
+FUNCTION C_GetMechanismInfo
+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
+
+# C_InitToken initializes a token.
+FUNCTION C_InitToken
+CK_SLOT_ID slotID # ID of the token's slot
+CK_CHAR_PTR pPin # the SO's initial PIN
+CK_ULONG ulPinLen # length in bytes of the PIN
+CK_CHAR_PTR pLabel # 32-byte token label (blank padded)
+
+# C_InitPIN initializes the normal user's PIN.
+FUNCTION C_InitPIN
+CK_SESSION_HANDLE hSession # the session's handle
+CK_CHAR_PTR pPin # the normal user's PIN
+CK_ULONG ulPinLen # length in bytes of the PIN
+
+# C_SetPIN modifies the PIN of the user who is logged in.
+FUNCTION C_SetPIN
+CK_SESSION_HANDLE hSession # the session's handle
+CK_CHAR_PTR pOldPin # the old PIN
+CK_ULONG ulOldLen # length of the old PIN
+CK_CHAR_PTR pNewPin # the new PIN
+CK_ULONG ulNewLen # length of the new PIN
+
+
+# Session management
+
+# C_OpenSession opens a session between an application and a token.
+FUNCTION C_OpenSession
+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
+
+# C_CloseSession closes a session between an application and a token.
+FUNCTION C_CloseSession
+CK_SESSION_HANDLE hSession # the session's handle
+
+# C_CloseAllSessions closes all sessions with a token.
+FUNCTION C_CloseAllSessions
+CK_SLOT_ID slotID # the token's slot
+
+# C_GetSessionInfo obtains information about the session.
+FUNCTION C_GetSessionInfo
+CK_SESSION_HANDLE hSession # the session's handle
+CK_SESSION_INFO_PTR pInfo # receives session info
+
+# C_GetOperationState obtains the state of the cryptographic
+# operation in a session.
+FUNCTION C_GetOperationState
+CK_SESSION_HANDLE hSession # session's handle
+CK_BYTE_PTR pOperationState # gets state
+CK_ULONG_PTR pulOperationStateLen # gets state length
+
+# C_SetOperationState restores the state of the cryptographic
+# operation in a session.
+FUNCTION C_SetOperationState
+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
+
+# C_Login logs a user into a token.
+FUNCTION C_Login
+CK_SESSION_HANDLE hSession # the session's handle
+CK_USER_TYPE userType # the user type
+CK_CHAR_PTR pPin # the user's PIN
+CK_ULONG ulPinLen # the length of the PIN
+
+# C_Logout logs a user out from a token.
+FUNCTION C_Logout
+CK_SESSION_HANDLE hSession # the session's handle
+
+
+# Object management
+
+# C_CreateObject creates a new object.
+FUNCTION C_CreateObject
+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.
+
+# C_CopyObject copies an object, creating a new object for the copy.
+FUNCTION C_CopyObject
+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
+
+# C_DestroyObject destroys an object.
+FUNCTION C_DestroyObject
+CK_SESSION_HANDLE hSession # the session's handle
+CK_OBJECT_HANDLE hObject # the object's handle
+
+# C_GetObjectSize gets the size of an object in bytes.
+FUNCTION C_GetObjectSize
+CK_SESSION_HANDLE hSession # the session's handle
+CK_OBJECT_HANDLE hObject # the object's handle
+CK_ULONG_PTR pulSize # receives size of object
+
+# C_GetAttributeValue obtains the value of one or more object
+# attributes.
+FUNCTION C_GetAttributeValue
+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
+
+# C_SetAttributeValue modifies the value of one or more object
+# attributes
+FUNCTION C_SetAttributeValue
+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
+
+# C_FindObjectsInit initializes a search for token and session
+# objects that match a template.
+FUNCTION C_FindObjectsInit
+CK_SESSION_HANDLE hSession # the session's handle
+CK_ATTRIBUTE_PTR pTemplate # attribute values to match
+CK_ULONG ulCount # attrs in search template
+
+# C_FindObjects continues a search for token and session objects that
+# match a template, obtaining additional object handles.
+FUNCTION C_FindObjects
+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
+
+# C_FindObjectsFinal finishes a search for token and session objects.
+FUNCTION C_FindObjectsFinal
+CK_SESSION_HANDLE hSession # the session's handle
+
+
+# Encryption and decryption
+
+# C_EncryptInit initializes an encryption operation.
+FUNCTION C_EncryptInit
+CK_SESSION_HANDLE hSession # the session's handle
+CK_MECHANISM_PTR pMechanism # the encryption mechanism
+CK_OBJECT_HANDLE hKey # handle of encryption key
+
+# C_Encrypt encrypts single-part data.
+FUNCTION C_Encrypt
+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
+
+# C_EncryptUpdate continues a multiple-part encryption operation.
+FUNCTION C_EncryptUpdate
+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
+
+# C_EncryptFinal finishes a multiple-part encryption operation.
+FUNCTION C_EncryptFinal
+CK_SESSION_HANDLE hSession # session handle
+CK_BYTE_PTR pLastEncryptedPart # last c-text
+CK_ULONG_PTR pulLastEncryptedPartLen # gets last size
+
+# C_DecryptInit initializes a decryption operation.
+FUNCTION C_DecryptInit
+CK_SESSION_HANDLE hSession # the session's handle
+CK_MECHANISM_PTR pMechanism # the decryption mechanism
+CK_OBJECT_HANDLE hKey # handle of decryption key
+
+# C_Decrypt decrypts encrypted data in a single part.
+FUNCTION C_Decrypt
+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
+
+# C_DecryptUpdate continues a multiple-part decryption operation.
+FUNCTION C_DecryptUpdate
+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
+
+# C_DecryptFinal finishes a multiple-part decryption operation.
+FUNCTION C_DecryptFinal
+CK_SESSION_HANDLE hSession # the session's handle
+CK_BYTE_PTR pLastPart # gets plaintext
+CK_ULONG_PTR pulLastPartLen # p-text size
+
+
+# Message digesting
+
+# C_DigestInit initializes a message-digesting operation.
+FUNCTION C_DigestInit
+CK_SESSION_HANDLE hSession # the session's handle
+CK_MECHANISM_PTR pMechanism # the digesting mechanism
+
+# C_Digest digests data in a single part.
+FUNCTION C_Digest
+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
+
+# C_DigestUpdate continues a multiple-part message-digesting operation.
+FUNCTION C_DigestUpdate
+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
+
+# C_DigestKey continues a multi-part message-digesting operation, by
+# digesting the value of a secret key as part of the data already
+# digested.
+FUNCTION C_DigestKey
+CK_SESSION_HANDLE hSession # the session's handle
+CK_OBJECT_HANDLE hKey # secret key to digest
+
+# C_DigestFinal finishes a multiple-part message-digesting operation.
+FUNCTION C_DigestFinal
+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
+
+
+# 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.
+FUNCTION C_SignInit
+CK_SESSION_HANDLE hSession # the session's handle
+CK_MECHANISM_PTR pMechanism # the signature mechanism
+CK_OBJECT_HANDLE hKey # handle of signature key
+
+# 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.
+FUNCTION C_Sign
+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
+
+# 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.
+FUNCTION C_SignUpdate
+CK_SESSION_HANDLE hSession # the session's handle
+CK_BYTE_PTR pPart # the data to sign
+CK_ULONG ulPartLen # count of bytes to sign
+
+# C_SignFinal finishes a multiple-part signature operation, returning
+# the signature.
+FUNCTION C_SignFinal
+CK_SESSION_HANDLE hSession # the session's handle
+CK_BYTE_PTR pSignature # gets the signature
+CK_ULONG_PTR pulSignatureLen # gets signature length
+
+# C_SignRecoverInit initializes a signature operation, where the data
+# can be recovered from the signature.
+FUNCTION C_SignRecoverInit
+CK_SESSION_HANDLE hSession # the session's handle
+CK_MECHANISM_PTR pMechanism # the signature mechanism
+CK_OBJECT_HANDLE hKey # handle of the signature key
+
+# C_SignRecover signs data in a single operation, where the data can
+# be recovered from the signature.
+FUNCTION C_SignRecover
+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
+
+
+# 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).
+FUNCTION C_VerifyInit
+CK_SESSION_HANDLE hSession # the session's handle
+CK_MECHANISM_PTR pMechanism # the verification mechanism
+CK_OBJECT_HANDLE hKey # verification key
+
+# 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.
+FUNCTION C_Verify
+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
+
+# 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.
+FUNCTION C_VerifyUpdate
+CK_SESSION_HANDLE hSession # the session's handle
+CK_BYTE_PTR pPart # signed data
+CK_ULONG ulPartLen # length of signed data
+
+# C_VerifyFinal finishes a multiple-part verification operation,
+# checking the signature.
+FUNCTION C_VerifyFinal
+CK_SESSION_HANDLE hSession # the session's handle
+CK_BYTE_PTR pSignature # signature to verify
+CK_ULONG ulSignatureLen # signature length
+
+# C_VerifyRecoverInit initializes a signature verification operation,
+# where the data is recovered from the signature.
+FUNCTION C_VerifyRecoverInit
+CK_SESSION_HANDLE hSession # the session's handle
+CK_MECHANISM_PTR pMechanism # the verification mechanism
+CK_OBJECT_HANDLE hKey # verification key
+
+# C_VerifyRecover verifies a signature in a single-part operation,
+# where the data is recovered from the signature.
+FUNCTION C_VerifyRecover
+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
+
+
+# Dual-function cryptographic operations
+
+# C_DigestEncryptUpdate continues a multiple-part digesting and
+# encryption operation.
+FUNCTION C_DigestEncryptUpdate
+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
+
+# C_DecryptDigestUpdate continues a multiple-part decryption and
+# digesting operation.
+FUNCTION C_DecryptDigestUpdate
+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
+
+# C_SignEncryptUpdate continues a multiple-part signing and
+# encryption operation.
+FUNCTION C_SignEncryptUpdate
+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
+
+# C_DecryptVerifyUpdate continues a multiple-part decryption and
+# verify operation.
+FUNCTION C_DecryptVerifyUpdate
+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
+
+
+# Key management
+
+# C_GenerateKey generates a secret key, creating a new key object.
+FUNCTION C_GenerateKey
+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
+
+# C_GenerateKeyPair generates a public-key/private-key pair, creating
+# new key objects.
+FUNCTION C_GenerateKeyPair
+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
+
+# C_WrapKey wraps (i.e., encrypts) a key.
+FUNCTION C_WrapKey
+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
+
+# C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key
+# object.
+FUNCTION C_UnwrapKey
+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
+
+# C_DeriveKey derives a key from a base key, creating a new key object.
+FUNCTION C_DeriveKey
+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
+
+
+# Random number generation
+
+# C_SeedRandom mixes additional seed material into the token's random
+# number generator.
+FUNCTION C_SeedRandom
+CK_SESSION_HANDLE hSession # the session's handle
+CK_BYTE_PTR pSeed # the seed material
+CK_ULONG ulSeedLen # length of seed material
+
+# C_GenerateRandom generates random data.
+FUNCTION C_GenerateRandom
+CK_SESSION_HANDLE hSession # the session's handle
+CK_BYTE_PTR RandomData # receives the random data
+CK_ULONG ulRandomLen # # of bytes to generate
+
+
+# Parallel function management
+
+# C_GetFunctionStatus is a legacy function; it obtains an updated
+# status of a function running in parallel with an application.
+FUNCTION C_GetFunctionStatus
+CK_SESSION_HANDLE hSession # the session's handle
+
+# C_CancelFunction is a legacy function; it cancels a function running
+# in parallel.
+FUNCTION C_CancelFunction
+CK_SESSION_HANDLE hSession # the session's handle
+
+
+# Functions added in for Cryptoki Version 2.01 or later
+
+# C_WaitForSlotEvent waits for a slot event (token insertion, removal,
+# etc.) to occur.
+FUNCTION C_WaitForSlotEvent
+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
+
+## C_ConfigureSlot passes an installation-specified bytestring to a
+## slot.
+#FUNCTION C_ConfigureSlot
+#CK_SLOT_ID slotID # the slot to configure
+#CK_BYTE_PTR pConfig # the configuration string
+#CK_ULONG ulConfigLen # length of the config string
diff --git a/security/nss/lib/ckfw/ck.h b/security/nss/lib/ckfw/ck.h
new file mode 100644
index 000000000..04df10656
--- /dev/null
+++ b/security/nss/lib/ckfw/ck.h
@@ -0,0 +1,121 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifndef CK_H
+#define CK_H
+
+#ifdef DEBUG
+static const char CK_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * ck.h
+ *
+ * This header file consolidates all header files needed by the source
+ * files implementing the NSS Cryptoki Framework. This makes managing
+ * the source files a bit easier.
+ */
+
+/* Types */
+
+#ifndef NSSBASET_H
+#include "nssbaset.h"
+#endif /* NSSBASET_H */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+#ifndef NSSCKFT_H
+#include "nssckft.h"
+#endif /* NSSCKFT_H */
+
+#ifndef NSSCKEPV_H
+#include "nssckepv.h"
+#endif /* NSSCKEPV_H */
+
+#ifndef NSSCKFWT_H
+#include "nssckfwt.h"
+#endif /* NSSCKFWT_H */
+
+#ifndef NSSCKMDT_H
+#include "nssckmdt.h"
+#endif /* NSSCKMDT_H */
+
+#ifndef CKT_H
+#include "ckt.h"
+#endif /* CKT_H */
+
+#ifndef CKFWTM_H
+#include "ckfwtm.h"
+#endif /* CKFWTM_H */
+
+/* Prototypes */
+
+#ifndef NSSBASE_H
+#include "nssbase.h"
+#endif /* NSSBASE_H */
+
+#ifndef NSSCKG_H
+#include "nssckg.h"
+#endif /* NSSCKG_H */
+
+#ifndef NSSCKFW_H
+#include "nssckfw.h"
+#endif /* NSSCKFW_H */
+
+#ifndef NSSCKFWC_H
+#include "nssckfwc.h"
+#endif /* NSSCKFWC_H */
+
+#ifndef CKFW_H
+#include "ckfw.h"
+#endif /* CKFW_H */
+
+#ifndef CKFWM_H
+#include "ckfwm.h"
+#endif /* CKFWM_H */
+
+#ifndef CKMD_H
+#include "ckmd.h"
+#endif /* CKMD_H */
+
+/* NSS-private */
+
+/* nss_ZNEW and the like. We might want to publish the memory APIs.. */
+
+#ifndef BASE_H
+#include "base.h"
+#endif /* BASE_H */
+
+#endif /* CK_H */
diff --git a/security/nss/lib/ckfw/ckapi.perl b/security/nss/lib/ckfw/ckapi.perl
new file mode 100644
index 000000000..e3cf17e34
--- /dev/null
+++ b/security/nss/lib/ckfw/ckapi.perl
@@ -0,0 +1,498 @@
+#!perl
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+$cvs_id = '@(#) $RCSfile$ $Revision$ $Date$ $Name$';
+
+$copyright = '/* THIS IS A GENERATED FILE */
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+';
+
+$count = -1;
+$i = 0;
+while(<>) {
+ s/^((?:[^"#]+|"[^"]*")*)(\s*#.*$)/$1/;
+ next if (/^\s*$/);
+
+# print;
+
+ /^([\S]+)\s+([^"][\S]*|"[^"]*")/;
+ $name = $1;
+ $value = $2;
+
+ if( ($name =~ "FUNCTION") && !($name =~ "CK_FUNCTION") ) {
+ $count++;
+ $x[$count]{name} = $value;
+ $i = 0;
+ } else {
+ if( $count < 0 ) {
+ $value =~ s/"//g;
+ $g{$name} = $value;
+ } else {
+ $x[$count]{args}[$i]{type} = $name;
+ $x[$count]{args}[$i]{name} = $value;
+ $i++;
+ $x[$count]{nargs} = $i; # rewritten each time, oh well
+ }
+ }
+}
+
+# dodump();
+doprint();
+
+sub dodump {
+ for( $j = 0; $j <= $count; $j++ ) {
+ print "CK_RV CK_ENTRY $x[$j]{name}\n";
+ for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
+ print " $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
+ if( $i == ($x[$j]{nargs} - 1) ) {
+ print "\n";
+ } else {
+ print ",\n";
+ }
+ }
+ }
+}
+
+sub doprint {
+open(PROTOTYPE, ">nssckg.h") || die "Can't open nssckg.h: $!";
+open(TYPEDEF, ">nssckft.h") || die "Can't open nssckft.h: $!";
+open(EPV, ">nssckepv.h") || die "Can't open nssckepv.h: $!";
+open(API, ">nssck.api") || die "Can't open nssck.api: $!";
+
+select PROTOTYPE;
+
+print $copyright;
+print <<EOD
+#ifndef NSSCKG_H
+#define NSSCKG_H
+
+#ifdef DEBUG
+static const char NSSCKG_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
+#endif /* DEBUG */
+
+/*
+ * nssckg.h
+ *
+ * This automatically-generated header file prototypes the Cryptoki
+ * functions specified by PKCS#11.
+ */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+EOD
+ ;
+
+for( $j = 0; $j <= $count; $j++ ) {
+ print "CK_RV CK_ENTRY $x[$j]{name}\n";
+ print "(\n";
+ for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
+ print " $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
+ if( $i == ($x[$j]{nargs} - 1) ) {
+ print "\n";
+ } else {
+ print ",\n";
+ }
+ }
+ print ");\n\n";
+}
+
+print <<EOD
+#endif /* NSSCKG_H */
+EOD
+ ;
+
+select TYPEDEF;
+
+print $copyright;
+print <<EOD
+#ifndef NSSCKFT_H
+#define NSSCKFT_H
+
+#ifdef DEBUG
+static const char NSSCKFT_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
+#endif /* DEBUG */
+
+/*
+ * nssckft.h
+ *
+ * The automatically-generated header file declares a typedef
+ * each of the Cryptoki functions specified by PKCS#11.
+ */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+EOD
+ ;
+
+for( $j = 0; $j <= $count; $j++ ) {
+# print "typedef CK_RV (CK_ENTRY *CK_$x[$j]{name})(\n";
+ print "typedef CK_CALLBACK_FUNCTION(CK_RV, CK_$x[$j]{name})(\n";
+ for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
+ print " $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
+ if( $i == ($x[$j]{nargs} - 1) ) {
+ print "\n";
+ } else {
+ print ",\n";
+ }
+ }
+ print ");\n\n";
+}
+
+print <<EOD
+#endif /* NSSCKFT_H */
+EOD
+ ;
+
+select EPV;
+
+print $copyright;
+print <<EOD
+#ifndef NSSCKEPV_H
+#define NSSCKEPV_H
+
+#ifdef DEBUG
+static const char NSSCKEPV_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
+#endif /* DEBUG */
+
+/*
+ * nssckepv.h
+ *
+ * This automatically-generated header file defines the type
+ * CK_FUNCTION_LIST specified by PKCS#11.
+ */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+#ifndef NSSCKFT_H
+#include "nssckft.h"
+#endif /* NSSCKFT_H */
+
+struct CK_FUNCTION_LIST {
+ CK_VERSION version;
+EOD
+ ;
+
+for( $j = 0; $j <= $count; $j++ ) {
+ print " CK_$x[$j]{name} $x[$j]{name};\n";
+}
+
+print <<EOD
+};
+
+#endif /* NSSCKEPV_H */
+EOD
+ ;
+
+select API;
+
+print $copyright;
+print <<EOD
+
+#ifdef DEBUG
+static const char NSSCKAPI_CVS_ID[] = "$g{CVS_ID} ; $cvs_id";
+#endif /* DEBUG */
+
+/*
+ * nssck.api
+ *
+ * This automatically-generated file is used to generate a set of
+ * Cryptoki entry points within the object space of a Module using
+ * the NSS Cryptoki Framework.
+ *
+ * The Module should have a .c file with the following:
+ *
+ * #define MODULE_NAME name
+ * #define INSTANCE_NAME instance
+ * #include "nssck.api"
+ *
+ * where "name" is some module-specific name that can be used to
+ * disambiguate various modules. This included file will then
+ * define the actual Cryptoki routines which pass through to the
+ * Framework calls. All routines, except C_GetFunctionList, will
+ * be prefixed with the name; C_GetFunctionList will be generated
+ * to return an entry-point vector with these routines. The
+ * instance specified should be the basic instance of NSSCKMDInstance.
+ *
+ * If, prior to including nssck.api, the .c file also specifies
+ *
+ * #define DECLARE_STRICT_CRYTPOKI_NAMES
+ *
+ * Then a set of "stub" routines not prefixed with the name will
+ * be included. This would allow the combined module and framework
+ * to be used in applications which are hard-coded to use the
+ * PKCS#11 names (instead of going through the EPV). Please note
+ * that such applications should be careful resolving symbols when
+ * more than one PKCS#11 module is loaded.
+ */
+
+#ifndef MODULE_NAME
+#error "Error: MODULE_NAME must be defined."
+#endif /* MODULE_NAME */
+
+#ifndef INSTANCE_NAME
+#error "Error: INSTANCE_NAME must be defined."
+#endif /* INSTANCE_NAME */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+#ifndef NSSCKFWT_H
+#include "nssckfwt.h"
+#endif /* NSSCKFWT_H */
+
+#ifndef NSSCKFWC_H
+#include "nssckfwc.h"
+#endif /* NSSCKFWC_H */
+
+#ifndef NSSCKEPV_H
+#include "nssckepv.h"
+#endif /* NSSCKEPV_H */
+
+#define __ADJOIN(x,y) x##y
+
+/*
+ * The anchor. This object is used to store an "anchor" pointer in
+ * the Module's object space, so the wrapper functions can relate
+ * back to this instance.
+ */
+
+static NSSCKFWInstance *fwInstance = (NSSCKFWInstance *)0;
+
+CK_RV CK_ENTRY
+__ADJOIN(MODULE_NAME,C_Initialize)
+(
+ CK_VOID_PTR pInitArgs
+)
+{
+ return NSSCKFWC_Initialize(&fwInstance, INSTANCE_NAME, pInitArgs);
+}
+
+#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
+CK_RV CK_ENTRY
+C_Initialize
+(
+ CK_VOID_PTR pInitArgs
+)
+{
+ return __ADJOIN(MODULE_NAME,C_Initialize)(pInitArgs);
+}
+#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
+
+CK_RV CK_ENTRY
+__ADJOIN(MODULE_NAME,C_Finalize)
+(
+ CK_VOID_PTR pReserved
+)
+{
+ return NSSCKFWC_Finalize(&fwInstance);
+}
+
+#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
+CK_RV CK_ENTRY
+C_Finalize
+(
+ CK_VOID_PTR pReserved
+)
+{
+ return __ADJOIN(MODULE_NAME,C_Finalize)(pReserved);
+}
+#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
+
+CK_RV CK_ENTRY
+__ADJOIN(MODULE_NAME,C_GetInfo)
+(
+ CK_INFO_PTR pInfo
+)
+{
+ return NSSCKFWC_GetInfo(fwInstance, pInfo);
+}
+
+#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
+CK_RV CK_ENTRY
+C_GetInfo
+(
+ CK_INFO_PTR pInfo
+)
+{
+ return __ADJOIN(MODULE_NAME,C_GetInfo)(pInfo);
+}
+#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
+
+/*
+ * C_GetFunctionList is defined at the end.
+ */
+
+EOD
+ ;
+
+for( $j = 4; $j <= $count; $j++ ) {
+ print "CK_RV CK_ENTRY\n";
+ print "__ADJOIN(MODULE_NAME,$x[$j]{name})\n";
+ print "(\n";
+ for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
+ print " $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
+ if( $i == ($x[$j]{nargs} - 1) ) {
+ print "\n";
+ } else {
+ print ",\n";
+ }
+ }
+ print ")\n";
+ print "{\n";
+ print " return NSSCKFW$x[$j]{name}(fwInstance, ";
+ for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
+ print "$x[$j]{args}[$i]{name}";
+ if( $i == ($x[$j]{nargs} - 1) ) {
+ print ");\n";
+ } else {
+ print ", ";
+ }
+ }
+ print "}\n\n";
+
+ print "#ifdef DECLARE_STRICT_CRYPTOKI_NAMES\n";
+ print "CK_RV CK_ENTRY\n";
+ print "$x[$j]{name}\n";
+ print "(\n";
+ for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
+ print " $x[$j]{args}[$i]{type} $x[$j]{args}[$i]{name}";
+ if( $i == ($x[$j]{nargs} - 1) ) {
+ print "\n";
+ } else {
+ print ",\n";
+ }
+ }
+ print ")\n";
+ print "{\n";
+ print " return __ADJOIN(MODULE_NAME,$x[$j]{name})(";
+ for( $i = 0; $i < $x[$j]{nargs}; $i++ ) {
+ print "$x[$j]{args}[$i]{name}";
+ if( $i == ($x[$j]{nargs} - 1) ) {
+ print ");\n";
+ } else {
+ print ", ";
+ }
+ }
+ print "}\n";
+ print "#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */\n\n";
+}
+
+print <<EOD
+CK_RV CK_ENTRY
+__ADJOIN(MODULE_NAME,C_GetFunctionList)
+(
+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList
+);
+
+static CK_FUNCTION_LIST FunctionList = {
+ { 2, 1 },
+EOD
+ ;
+
+for( $j = 0; $j <= $count; $j++ ) {
+ print "__ADJOIN(MODULE_NAME,$x[$j]{name})";
+ if( $j < $count ) {
+ print ",\n";
+ } else {
+ print "\n};\n\n";
+ }
+}
+
+print <<EOD
+CK_RV CK_ENTRY
+__ADJOIN(MODULE_NAME,C_GetFunctionList)
+(
+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList
+)
+{
+ *ppFunctionList = &FunctionList;
+ return CKR_OK;
+}
+
+#ifdef DECLARE_STRICT_CRYPTOKI_NAMES
+CK_RV CK_ENTRY
+C_GetFunctionList
+(
+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList
+)
+{
+ return __ADJOIN(MODULE_NAME,C_GetFunctionList)(ppFunctionList);
+}
+#endif /* DECLARE_STRICT_CRYPTOKI_NAMES */
+
+#undef __ADJOIN
+
+EOD
+ ;
+
+select STDOUT;
+
+}
diff --git a/security/nss/lib/ckfw/ckfw.h b/security/nss/lib/ckfw/ckfw.h
new file mode 100644
index 000000000..0e1f754d8
--- /dev/null
+++ b/security/nss/lib/ckfw/ckfw.h
@@ -0,0 +1,1765 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifndef CKFW_H
+#define CKFW_H
+
+#ifdef DEBUG
+static const char CKFW_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * ckfw.h
+ *
+ * This file prototypes the private calls of the NSS Cryptoki Framework.
+ */
+
+#ifndef NSSBASET_H
+#include "nssbaset.h"
+#endif /* NSSBASET_H */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+#ifndef NSSCKFWT_H
+#include "nssckfwt.h"
+#endif /* NSSCKFWT_H */
+
+#ifndef NSSCKMDT_H
+#include "nssckmdt.h"
+#endif /* NSSCKMDT_H */
+
+/*
+ * NSSCKFWInstance
+ *
+ * -- create/destroy --
+ * nssCKFWInstance_Create
+ * nssCKFWInstance_Destroy
+ *
+ * -- implement public accessors --
+ * nssCKFWInstance_GetMDInstance
+ * nssCKFWInstance_GetArena
+ * nssCKFWInstance_MayCreatePthreads
+ * nssCKFWInstance_CreateMutex
+ * nssCKFWInstance_GetConfigurationData
+ *
+ * -- private accessors --
+ * nssCKFWInstance_CreateSessionHandle
+ * nssCKFWInstance_ResolveSessionHandle
+ * nssCKFWInstance_DestroySessionHandle
+ * nssCKFWInstance_FindSessionHandle
+ * nssCKFWInstance_CreateObjectHandle
+ * nssCKFWInstance_ResolveObjectHandle
+ * nssCKFWInstance_DestroyObjectHandle
+ *
+ * -- module fronts --
+ * nssCKFWInstance_GetNSlots
+ * nssCKFWInstance_GetCryptokiVersion
+ * nssCKFWInstance_GetManufacturerID
+ * nssCKFWInstance_GetFlags
+ * nssCKFWInstance_GetLibraryDescription
+ * nssCKFWInstance_GetLibraryVersion
+ * nssCKFWInstance_GetModuleHandlesSessionObjects
+ * nssCKFWInstance_GetSlots
+ * nssCKFWInstance_WaitForSlotEvent
+ *
+ * -- debugging versions only --
+ * nssCKFWInstance_verifyPointer
+ */
+
+/*
+ * nssCKFWInstance_Create
+ *
+ */
+NSS_EXTERN NSSCKFWInstance *
+nssCKFWInstance_Create
+(
+ CK_C_INITIALIZE_ARGS_PTR pInitArgs,
+ NSSCKMDInstance *mdInstance,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWInstance_Destroy
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWInstance_Destroy
+(
+ NSSCKFWInstance *fwInstance
+);
+
+/*
+ * nssCKFWInstance_GetMDInstance
+ *
+ */
+NSS_EXTERN NSSCKMDInstance *
+nssCKFWInstance_GetMDInstance
+(
+ NSSCKFWInstance *fwInstance
+);
+
+/*
+ * nssCKFWInstance_GetArena
+ *
+ */
+NSS_EXTERN NSSArena *
+nssCKFWInstance_GetArena
+(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWInstance_MayCreatePthreads
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWInstance_MayCreatePthreads
+(
+ NSSCKFWInstance *fwInstance
+);
+
+/*
+ * nssCKFWInstance_CreateMutex
+ *
+ */
+NSS_EXTERN NSSCKFWMutex *
+nssCKFWInstance_CreateMutex
+(
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWInstance_GetConfigurationData
+ *
+ */
+NSS_EXTERN NSSUTF8 *
+nssCKFWInstance_GetConfigurationData
+(
+ NSSCKFWInstance *fwInstance
+);
+
+/*
+ * nssCKFWInstance_CreateSessionHandle
+ *
+ */
+NSS_EXTERN CK_SESSION_HANDLE
+nssCKFWInstance_CreateSessionHandle
+(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWInstance_ResolveSessionHandle
+ *
+ */
+NSS_EXTERN NSSCKFWSession *
+nssCKFWInstance_ResolveSessionHandle
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+);
+
+/*
+ * nssCKFWInstance_DestroySessionHandle
+ *
+ */
+NSS_EXTERN void
+nssCKFWInstance_DestroySessionHandle
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+);
+
+/*
+ * nssCKFWInstance_FindSessionHandle
+ *
+ */
+NSS_EXTERN CK_SESSION_HANDLE
+nssCKFWInstance_FindSessionHandle
+(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWSession *fwSession
+);
+
+/*
+ * nssCKFWInstance_CreateObjectHandle
+ *
+ */
+NSS_EXTERN CK_OBJECT_HANDLE
+nssCKFWInstance_CreateObjectHandle
+(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWInstance_FindObjectHandle
+ *
+ */
+NSS_EXTERN CK_OBJECT_HANDLE
+nssCKFWInstance_FindObjectHandle
+(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWObject *fwObject
+);
+
+/*
+ * nssCKFWInstance_ResolveObjectHandle
+ *
+ */
+NSS_EXTERN NSSCKFWObject *
+nssCKFWInstance_ResolveObjectHandle
+(
+ NSSCKFWInstance *fwInstance,
+ CK_OBJECT_HANDLE hObject
+);
+
+/*
+ * nssCKFWInstance_ReassignObjectHandle
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWInstance_ReassignObjectHandle
+(
+ NSSCKFWInstance *fwInstance,
+ CK_OBJECT_HANDLE hObject,
+ NSSCKFWObject *fwObject
+);
+
+/*
+ * nssCKFWInstance_DestroyObjectHandle
+ *
+ */
+NSS_EXTERN void
+nssCKFWInstance_DestroyObjectHandle
+(
+ NSSCKFWInstance *fwInstance,
+ CK_OBJECT_HANDLE hObject
+);
+
+/*
+ * nssCKFWInstance_GetNSlots
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWInstance_GetNSlots
+(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWInstance_GetCryptokiVersion
+ *
+ */
+NSS_EXTERN CK_VERSION
+nssCKFWInstance_GetCryptokiVersion
+(
+ NSSCKFWInstance *fwInstance
+);
+
+/*
+ * nssCKFWInstance_GetManufacturerID
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWInstance_GetManufacturerID
+(
+ NSSCKFWInstance *fwInstance,
+ CK_CHAR manufacturerID[32]
+);
+
+/*
+ * nssCKFWInstance_GetFlags
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWInstance_GetFlags
+(
+ NSSCKFWInstance *fwInstance
+);
+
+/*
+ * nssCKFWInstance_GetLibraryDescription
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWInstance_GetLibraryDescription
+(
+ NSSCKFWInstance *fwInstance,
+ CK_CHAR libraryDescription[32]
+);
+
+/*
+ * nssCKFWInstance_GetLibraryVersion
+ *
+ */
+NSS_EXTERN CK_VERSION
+nssCKFWInstance_GetLibraryVersion
+(
+ NSSCKFWInstance *fwInstance
+);
+
+/*
+ * nssCKFWInstance_GetModuleHandlesSessionObjects
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWInstance_GetModuleHandlesSessionObjects
+(
+ NSSCKFWInstance *fwInstance
+);
+
+/*
+ * nssCKFWInstance_GetSlots
+ *
+ */
+NSS_EXTERN NSSCKFWSlot **
+nssCKFWInstance_GetSlots
+(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWInstance_WaitForSlotEvent
+ *
+ */
+NSS_EXTERN NSSCKFWSlot *
+nssCKFWInstance_WaitForSlotEvent
+(
+ NSSCKFWInstance *fwInstance,
+ CK_BBOOL block,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWInstance_verifyPointer
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWInstance_verifyPointer
+(
+ const NSSCKFWInstance *fwInstance
+);
+
+
+/*
+ * NSSCKFWSlot
+ *
+ * -- create/destroy --
+ * nssCKFWSlot_Create
+ * nssCKFWSlot_Destroy
+ *
+ * -- implement public accessors --
+ * nssCKFWSlot_GetMDSlot
+ * nssCKFWSlot_GetFWInstance
+ * nssCKFWSlot_GetMDInstance
+ *
+ * -- private accessors --
+ * nssCKFWSlot_GetSlotID
+ *
+ * -- module fronts --
+ * nssCKFWSlot_GetSlotDescription
+ * nssCKFWSlot_GetManufacturerID
+ * nssCKFWSlot_GetTokenPresent
+ * nssCKFWSlot_GetRemovableDevice
+ * nssCKFWSlot_GetHardwareSlot
+ * nssCKFWSlot_GetHardwareVersion
+ * nssCKFWSlot_GetFirmwareVersion
+ * nssCKFWSlot_GetToken
+ */
+
+/*
+ * nssCKFWSlot_Create
+ *
+ */
+NSS_EXTERN NSSCKFWSlot *
+nssCKFWSlot_Create
+(
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDSlot *mdSlot,
+ CK_SLOT_ID slotID,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWSlot_Destroy
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSlot_Destroy
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * nssCKFWSlot_GetMDSlot
+ *
+ */
+NSS_EXTERN NSSCKMDSlot *
+nssCKFWSlot_GetMDSlot
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * nssCKFWSlot_GetFWInstance
+ *
+ */
+
+NSS_EXTERN NSSCKFWInstance *
+nssCKFWSlot_GetFWInstance
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * nssCKFWSlot_GetMDInstance
+ *
+ */
+
+NSS_EXTERN NSSCKMDInstance *
+nssCKFWSlot_GetMDInstance
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * nssCKFWSlot_GetSlotID
+ *
+ */
+NSS_EXTERN CK_SLOT_ID
+nssCKFWSlot_GetSlotID
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * nssCKFWSlot_GetSlotDescription
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSlot_GetSlotDescription
+(
+ NSSCKFWSlot *fwSlot,
+ CK_CHAR slotDescription[64]
+);
+
+/*
+ * nssCKFWSlot_GetManufacturerID
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSlot_GetManufacturerID
+(
+ NSSCKFWSlot *fwSlot,
+ CK_CHAR manufacturerID[32]
+);
+
+/*
+ * nssCKFWSlot_GetTokenPresent
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWSlot_GetTokenPresent
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * nssCKFWSlot_GetRemovableDevice
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWSlot_GetRemovableDevice
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * nssCKFWSlot_GetHardwareSlot
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWSlot_GetHardwareSlot
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * nssCKFWSlot_GetHardwareVersion
+ *
+ */
+NSS_EXTERN CK_VERSION
+nssCKFWSlot_GetHardwareVersion
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * nssCKFWSlot_GetFirmwareVersion
+ *
+ */
+NSS_EXTERN CK_VERSION
+nssCKFWSlot_GetFirmwareVersion
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * nssCKFWSlot_GetToken
+ *
+ */
+NSS_EXTERN NSSCKFWToken *
+nssCKFWSlot_GetToken
+(
+ NSSCKFWSlot *fwSlot,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWSlot_ClearToken
+ *
+ */
+NSS_EXTERN void
+nssCKFWSlot_ClearToken
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * NSSCKFWToken
+ *
+ * -- create/destroy --
+ * nssCKFWToken_Create
+ * nssCKFWToken_Destroy
+ *
+ * -- implement public accessors --
+ * nssCKFWToken_GetMDToken
+ * nssCKFWToken_GetFWSlot
+ * nssCKFWToken_GetMDSlot
+ * nssCKFWToken_GetSessionState
+ *
+ * -- private accessors --
+ * nssCKFWToken_SetSessionState
+ * nssCKFWToken_RemoveSession
+ * nssCKFWToken_CloseAllSessions
+ * nssCKFWToken_GetSessionCount
+ * nssCKFWToken_GetRwSessionCount
+ * nssCKFWToken_GetRoSessionCount
+ * nssCKFWToken_GetSessionObjectHash
+ * nssCKFWToken_GetMDObjectHash
+ * nssCKFWToken_GetObjectHandleHash
+ *
+ * -- module fronts --
+ * nssCKFWToken_InitToken
+ * nssCKFWToken_GetLabel
+ * nssCKFWToken_GetManufacturerID
+ * nssCKFWToken_GetModel
+ * nssCKFWToken_GetSerialNumber
+ * nssCKFWToken_GetHasRNG
+ * nssCKFWToken_GetIsWriteProtected
+ * nssCKFWToken_GetLoginRequired
+ * nssCKFWToken_GetUserPinInitialized
+ * nssCKFWToken_GetRestoreKeyNotNeeded
+ * nssCKFWToken_GetHasClockOnToken
+ * nssCKFWToken_GetHasProtectedAuthenticationPath
+ * nssCKFWToken_GetSupportsDualCryptoOperations
+ * nssCKFWToken_GetMaxSessionCount
+ * nssCKFWToken_GetMaxRwSessionCount
+ * nssCKFWToken_GetMaxPinLen
+ * nssCKFWToken_GetMinPinLen
+ * nssCKFWToken_GetTotalPublicMemory
+ * nssCKFWToken_GetFreePublicMemory
+ * nssCKFWToken_GetTotalPrivateMemory
+ * nssCKFWToken_GetFreePrivateMemory
+ * nssCKFWToken_GetHardwareVersion
+ * nssCKFWToken_GetFirmwareVersion
+ * nssCKFWToken_GetUTCTime
+ * nssCKFWToken_OpenSession
+ * nssCKFWToken_GetMechanismCount
+ * nssCKFWToken_GetMechanismTypes
+ * nssCKFWToken_GetMechanism
+ */
+
+/*
+ * nssCKFWToken_Create
+ *
+ */
+NSS_EXTERN NSSCKFWToken *
+nssCKFWToken_Create
+(
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDToken *mdToken,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWToken_Destroy
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWToken_Destroy
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetMDToken
+ *
+ */
+NSS_EXTERN NSSCKMDToken *
+nssCKFWToken_GetMDToken
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetArena
+ *
+ */
+NSS_EXTERN NSSArena *
+nssCKFWToken_GetArena
+(
+ NSSCKFWToken *fwToken,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWToken_GetFWSlot
+ *
+ */
+NSS_EXTERN NSSCKFWSlot *
+nssCKFWToken_GetFWSlot
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetMDSlot
+ *
+ */
+NSS_EXTERN NSSCKMDSlot *
+nssCKFWToken_GetMDSlot
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetSessionState
+ *
+ */
+NSS_EXTERN CK_STATE
+nssCKFWToken_GetSessionState
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_InitToken
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWToken_InitToken
+(
+ NSSCKFWToken *fwToken,
+ NSSItem *pin,
+ NSSUTF8 *label
+);
+
+/*
+ * nssCKFWToken_GetLabel
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWToken_GetLabel
+(
+ NSSCKFWToken *fwToken,
+ CK_CHAR label[32]
+);
+
+/*
+ * nssCKFWToken_GetManufacturerID
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWToken_GetManufacturerID
+(
+ NSSCKFWToken *fwToken,
+ CK_CHAR manufacturerID[32]
+);
+
+/*
+ * nssCKFWToken_GetModel
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWToken_GetModel
+(
+ NSSCKFWToken *fwToken,
+ CK_CHAR model[16]
+);
+
+/*
+ * nssCKFWToken_GetSerialNumber
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWToken_GetSerialNumber
+(
+ NSSCKFWToken *fwToken,
+ CK_CHAR serialNumber[16]
+);
+
+/*
+ * nssCKFWToken_GetHasRNG
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWToken_GetHasRNG
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetIsWriteProtected
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWToken_GetIsWriteProtected
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetLoginRequired
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWToken_GetLoginRequired
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetUserPinInitialized
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWToken_GetUserPinInitialized
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetRestoreKeyNotNeeded
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWToken_GetRestoreKeyNotNeeded
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetHasClockOnToken
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWToken_GetHasClockOnToken
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetHasProtectedAuthenticationPath
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWToken_GetHasProtectedAuthenticationPath
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetSupportsDualCryptoOperations
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWToken_GetSupportsDualCryptoOperations
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetMaxSessionCount
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWToken_GetMaxSessionCount
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetMaxRwSessionCount
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWToken_GetMaxRwSessionCount
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetMaxPinLen
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWToken_GetMaxPinLen
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetMinPinLen
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWToken_GetMinPinLen
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetTotalPublicMemory
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWToken_GetTotalPublicMemory
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetFreePublicMemory
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWToken_GetFreePublicMemory
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetTotalPrivateMemory
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWToken_GetTotalPrivateMemory
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetFreePrivateMemory
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWToken_GetFreePrivateMemory
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetHardwareVersion
+ *
+ */
+NSS_EXTERN CK_VERSION
+nssCKFWToken_GetHardwareVersion
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetFirmwareVersion
+ *
+ */
+NSS_EXTERN CK_VERSION
+nssCKFWToken_GetFirmwareVersion
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetUTCTime
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWToken_GetUTCTime
+(
+ NSSCKFWToken *fwToken,
+ CK_CHAR utcTime[16]
+);
+
+/*
+ * nssCKFWToken_OpenSession
+ *
+ */
+NSS_EXTERN NSSCKFWSession *
+nssCKFWToken_OpenSession
+(
+ NSSCKFWToken *fwToken,
+ CK_BBOOL rw,
+ CK_VOID_PTR pApplication,
+ CK_NOTIFY Notify,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWToken_GetMechanismCount
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWToken_GetMechanismCount
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetMechanismTypes
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWToken_GetMechanismTypes
+(
+ NSSCKFWToken *fwToken,
+ CK_MECHANISM_TYPE types[]
+);
+
+/*
+ * nssCKFWToken_GetMechanism
+ *
+ */
+NSS_EXTERN NSSCKFWMechanism *
+nssCKFWToken_GetMechanism
+(
+ NSSCKFWToken *fwToken,
+ CK_MECHANISM_TYPE which,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWToken_SetSessionState
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWToken_SetSessionState
+(
+ NSSCKFWToken *fwToken,
+ CK_STATE newState
+);
+
+/*
+ * nssCKFWToken_RemoveSession
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWToken_RemoveSession
+(
+ NSSCKFWToken *fwToken,
+ NSSCKFWSession *fwSession
+);
+
+/*
+ * nssCKFWToken_CloseAllSessions
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWToken_CloseAllSessions
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetSessionCount
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWToken_GetSessionCount
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetRwSessionCount
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWToken_GetRwSessionCount
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetRoSessionCount
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWToken_GetRoSessionCount
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetSessionObjectHash
+ *
+ */
+NSS_EXTERN nssCKFWHash *
+nssCKFWToken_GetSessionObjectHash
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetMDObjectHash
+ *
+ */
+NSS_EXTERN nssCKFWHash *
+nssCKFWToken_GetMDObjectHash
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * nssCKFWToken_GetObjectHandleHash
+ *
+ */
+NSS_EXTERN nssCKFWHash *
+nssCKFWToken_GetObjectHandleHash
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * NSSCKFWMechanism
+ *
+ * -- create/destroy --
+ * nssCKFWMechanism_Create
+ * nssCKFWMechanism_Destroy
+ *
+ * -- implement public accessors --
+ * nssCKFWMechanism_GetMDMechanism
+ * nssCKFWMechanism_GetParameter
+ *
+ * -- private accessors --
+ *
+ * -- module fronts --
+ * nssCKFWMechanism_GetMinKeySize
+ * nssCKFWMechanism_GetMaxKeySize
+ * nssCKFWMechanism_GetInHardware
+ */
+
+/*
+ * nssCKFWMechanism_Create
+ *
+ */
+NSS_EXTERN NSSCKFWMechanism *
+nssCKFWMechanism_Create
+(
+ void /* XXX fgmr */
+);
+
+/*
+ * nssCKFWMechanism_Destroy
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWMechanism_Destroy
+(
+ NSSCKFWMechanism *fwMechanism
+);
+
+/*
+ * nssCKFWMechanism_GetMDMechanism
+ *
+ */
+
+NSS_EXTERN NSSCKMDMechanism *
+nssCKFWMechanism_GetMDMechanism
+(
+ NSSCKFWMechanism *fwMechanism
+);
+
+/*
+ * nssCKFWMechanism_GetParameter
+ *
+ * XXX fgmr-- or as an additional parameter to the crypto ops?
+ */
+NSS_EXTERN NSSItem *
+nssCKFWMechanism_GetParameter
+(
+ NSSCKFWMechanism *fwMechanism
+);
+
+/*
+ * nssCKFWMechanism_GetMinKeySize
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWMechanism_GetMinKeySize
+(
+ NSSCKFWMechanism *fwMechanism
+);
+
+/*
+ * nssCKFWMechanism_GetMaxKeySize
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWMechanism_GetMaxKeySize
+(
+ NSSCKFWMechanism *fwMechanism
+);
+
+/*
+ * nssCKFWMechanism_GetInHardware
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWMechanism_GetInHardware
+(
+ NSSCKFWMechanism *fwMechanism
+);
+
+/*
+ * NSSCKFWSession
+ *
+ * -- create/destroy --
+ * nssCKFWSession_Create
+ * nssCKFWSession_Destroy
+ *
+ * -- implement public accessors --
+ * nssCKFWSession_GetMDSession
+ * nssCKFWSession_GetArena
+ * nssCKFWSession_CallNotification
+ * nssCKFWSession_IsRWSession
+ * nssCKFWSession_IsSO
+ *
+ * -- private accessors --
+ * nssCKFWSession_GetFWSlot
+ * nssCKFWSession_GetSessionState
+ * nssCKFWSession_SetFWFindObjects
+ * nssCKFWSession_GetFWFindObjects
+ *
+ * -- module fronts --
+ * nssCKFWSession_GetDeviceError
+ * nssCKFWSession_Login
+ * nssCKFWSession_Logout
+ * nssCKFWSession_InitPIN
+ * nssCKFWSession_SetPIN
+ * nssCKFWSession_GetOperationStateLen
+ * nssCKFWSession_GetOperationState
+ * nssCKFWSession_SetOperationState
+ * nssCKFWSession_CreateObject
+ * nssCKFWSession_CopyObject
+ * nssCKFWSession_FindObjectsInit
+ * nssCKFWSession_SeedRandom
+ * nssCKFWSession_GetRandom
+ */
+
+/*
+ * nssCKFWSession_Create
+ *
+ */
+NSS_EXTERN NSSCKFWSession *
+nssCKFWSession_Create
+(
+ NSSCKFWToken *fwToken,
+ NSSCKMDSession *mdSession,
+ CK_BBOOL rw,
+ CK_VOID_PTR pApplication,
+ CK_NOTIFY Notify,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWSession_Destroy
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSession_Destroy
+(
+ NSSCKFWSession *fwSession,
+ CK_BBOOL removeFromTokenHash
+);
+
+/*
+ * nssCKFWSession_GetMDSession
+ *
+ */
+NSS_EXTERN NSSCKMDSession *
+nssCKFWSession_GetMDSession
+(
+ NSSCKFWSession *fwSession
+);
+
+/*
+ * nssCKFWSession_GetArena
+ *
+ */
+NSS_EXTERN NSSArena *
+nssCKFWSession_GetArena
+(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWSession_CallNotification
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSession_CallNotification
+(
+ NSSCKFWSession *fwSession,
+ CK_NOTIFICATION event
+);
+
+/*
+ * nssCKFWSession_IsRWSession
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWSession_IsRWSession
+(
+ NSSCKFWSession *fwSession
+);
+
+/*
+ * nssCKFWSession_IsSO
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWSession_IsSO
+(
+ NSSCKFWSession *fwSession
+);
+
+/*
+ * nssCKFWSession_GetFWSlot
+ *
+ */
+NSS_EXTERN NSSCKFWSlot *
+nssCKFWSession_GetFWSlot
+(
+ NSSCKFWSession *fwSession
+);
+
+/*
+ * nssCFKWSession_GetSessionState
+ *
+ */
+NSS_EXTERN CK_STATE
+nssCKFWSession_GetSessionState
+(
+ NSSCKFWSession *fwSession
+);
+
+/*
+ * nssCKFWSession_SetFWFindObjects
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSession_SetFWFindObjects
+(
+ NSSCKFWSession *fwSession,
+ NSSCKFWFindObjects *fwFindObjects
+);
+
+/*
+ * nssCKFWSession_GetFWFindObjects
+ *
+ */
+NSS_EXTERN NSSCKFWFindObjects *
+nssCKFWSession_GetFWFindObjects
+(
+ NSSCKFWSession *fwSesssion,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWSession_GetDeviceError
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWSession_GetDeviceError
+(
+ NSSCKFWSession *fwSession
+);
+
+/*
+ * nssCKFWSession_Login
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSession_Login
+(
+ NSSCKFWSession *fwSession,
+ CK_USER_TYPE userType,
+ NSSItem *pin
+);
+
+/*
+ * nssCKFWSession_Logout
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSession_Logout
+(
+ NSSCKFWSession *fwSession
+);
+
+/*
+ * nssCKFWSession_InitPIN
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSession_InitPIN
+(
+ NSSCKFWSession *fwSession,
+ NSSItem *pin
+);
+
+/*
+ * nssCKFWSession_SetPIN
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSession_SetPIN
+(
+ NSSCKFWSession *fwSession,
+ NSSItem *newPin,
+ NSSItem *oldPin
+);
+
+/*
+ * nssCKFWSession_GetOperationStateLen
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWSession_GetOperationStateLen
+(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWSession_GetOperationState
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSession_GetOperationState
+(
+ NSSCKFWSession *fwSession,
+ NSSItem *buffer
+);
+
+/*
+ * nssCKFWSession_SetOperationState
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSession_SetOperationState
+(
+ NSSCKFWSession *fwSession,
+ NSSItem *state,
+ NSSCKFWObject *encryptionKey,
+ NSSCKFWObject *authenticationKey
+);
+
+/*
+ * nssCKFWSession_CreateObject
+ *
+ */
+NSS_EXTERN NSSCKFWObject *
+nssCKFWSession_CreateObject
+(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWSession_CopyObject
+ *
+ */
+NSS_EXTERN NSSCKFWObject *
+nssCKFWSession_CopyObject
+(
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *object,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWSession_FindObjectsInit
+ *
+ */
+NSS_EXTERN NSSCKFWFindObjects *
+nssCKFWSession_FindObjectsInit
+(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWSession_SeedRandom
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSession_SeedRandom
+(
+ NSSCKFWSession *fwSession,
+ NSSItem *seed
+);
+
+/*
+ * nssCKFWSession_GetRandom
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWSession_GetRandom
+(
+ NSSCKFWSession *fwSession,
+ NSSItem *buffer
+);
+
+/*
+ * NSSCKFWObject
+ *
+ * -- create/destroy --
+ * nssCKFWObject_Create
+ * nssCKFWObject_Finalize
+ * nssCKFWObject_Destroy
+ *
+ * -- implement public accessors --
+ * nssCKFWObject_GetMDObject
+ * nssCKFWObject_GetArena
+ *
+ * -- private accessors --
+ *
+ * -- module fronts --
+ * nssCKFWObject_IsTokenObject
+ * nssCKFWObject_GetAttributeCount
+ * nssCKFWObject_GetAttributeTypes
+ * nssCKFWObject_GetAttributeSize
+ * nssCKFWObject_GetAttribute
+ * nssCKFWObject_SetAttribute
+ * nssCKFWObject_GetObjectSize
+ */
+
+/*
+ * nssCKFWObject_Create
+ *
+ */
+NSS_EXTERN NSSCKFWObject *
+nssCKFWObject_Create
+(
+ NSSArena *arena,
+ NSSCKMDObject *mdObject,
+ NSSCKFWSession *fwSession,
+ NSSCKFWToken *fwToken,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWObject_Finalize
+ *
+ */
+NSS_EXTERN void
+nssCKFWObject_Finalize
+(
+ NSSCKFWObject *fwObject
+);
+
+/*
+ * nssCKFWObject_Destroy
+ *
+ */
+NSS_EXTERN void
+nssCKFWObject_Destroy
+(
+ NSSCKFWObject *fwObject
+);
+
+/*
+ * nssCKFWObject_GetMDObject
+ *
+ */
+NSS_EXTERN NSSCKMDObject *
+nssCKFWObject_GetMDObject
+(
+ NSSCKFWObject *fwObject
+);
+
+/*
+ * nssCKFWObject_GetArena
+ *
+ */
+NSS_EXTERN NSSArena *
+nssCKFWObject_GetArena
+(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWObject_IsTokenObject
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWObject_IsTokenObject
+(
+ NSSCKFWObject *fwObject
+);
+
+/*
+ * nssCKFWObject_GetAttributeCount
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWObject_GetAttributeCount
+(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWObject_GetAttributeTypes
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWObject_GetAttributeTypes
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE_PTR typeArray,
+ CK_ULONG ulCount
+);
+
+/*
+ * nssCKFWObject_GetAttributeSize
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWObject_GetAttributeSize
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWObject_GetAttribute
+ *
+ * Usual NSS allocation rules:
+ * If itemOpt is not NULL, it will be returned; otherwise an NSSItem
+ * will be allocated. If itemOpt is not NULL but itemOpt->data is,
+ * the buffer will be allocated; otherwise, the buffer will be used.
+ * Any allocations will come from the optional arena, if one is
+ * specified.
+ */
+NSS_EXTERN NSSItem *
+nssCKFWObject_GetAttribute
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *itemOpt,
+ NSSArena *arenaOpt,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWObject_SetAttribute
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWObject_SetAttribute
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *value
+);
+
+/*
+ * nssCKFWObject_GetObjectSize
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWObject_GetObjectSize
+(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+);
+
+/*
+ * NSSCKFWFindObjects
+ *
+ * -- create/destroy --
+ * nssCKFWFindObjects_Create
+ * nssCKFWFindObjects_Destroy
+ *
+ * -- implement public accessors --
+ * nssCKFWFindObjects_GetMDFindObjects
+ *
+ * -- private accessors --
+ *
+ * -- module fronts --
+ * nssCKFWFindObjects_Next
+ */
+
+/*
+ * nssCKFWFindObjects_Create
+ *
+ */
+NSS_EXTERN NSSCKFWFindObjects *
+nssCKFWFindObjects_Create
+(
+ NSSCKFWSession *fwSession,
+ NSSCKFWToken *fwToken,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDFindObjects *mdFindObjects1,
+ NSSCKMDFindObjects *mdFindObjects2,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWFindObjects_Destroy
+ *
+ */
+NSS_EXTERN void
+nssCKFWFindObjects_Destroy
+(
+ NSSCKFWFindObjects *fwFindObjects
+);
+
+/*
+ * nssCKFWFindObjects_GetMDFindObjects
+ *
+ */
+NSS_EXTERN NSSCKMDFindObjects *
+nssCKFWFindObjects_GetMDFindObjects
+(
+ NSSCKFWFindObjects *fwFindObjects
+);
+
+/*
+ * nssCKFWFindObjects_Next
+ *
+ */
+NSS_EXTERN NSSCKFWObject *
+nssCKFWFindObjects_Next
+(
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSArena *arenaOpt,
+ CK_RV *pError
+);
+
+/*
+ * NSSCKFWMutex
+ *
+ * nssCKFWMutex_Create
+ * nssCKFWMutex_Destroy
+ * nssCKFWMutex_Lock
+ * nssCKFWMutex_Unlock
+ *
+ */
+
+/*
+ * nssCKFWMutex_Create
+ *
+ */
+NSS_EXTERN NSSCKFWMutex *
+nssCKFWMutex_Create
+(
+ CK_C_INITIALIZE_ARGS_PTR pInitArgs,
+ NSSArena *arena,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWMutex_Destroy
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWMutex_Destroy
+(
+ NSSCKFWMutex *mutex
+);
+
+/*
+ * nssCKFWMutex_Lock
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWMutex_Lock
+(
+ NSSCKFWMutex *mutex
+);
+
+/*
+ * nssCKFWMutex_Unlock
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWMutex_Unlock
+(
+ NSSCKFWMutex *mutex
+);
+
+#endif /* CKFW_H */
diff --git a/security/nss/lib/ckfw/ckfwm.h b/security/nss/lib/ckfw/ckfwm.h
new file mode 100644
index 000000000..82fd74830
--- /dev/null
+++ b/security/nss/lib/ckfw/ckfwm.h
@@ -0,0 +1,161 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifndef CKFWM_H
+#define CKFWM_H
+
+#ifdef DEBUG
+static const char CKFWM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * ckfwm.h
+ *
+ * This file prototypes the module-private calls of the NSS Cryptoki Framework.
+ */
+
+#ifndef NSSBASET_H
+#include "nssbaset.h"
+#endif /* NSSBASET_H */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+#ifndef NSSCKFWT_H
+#include "nssckfwt.h"
+#endif /* NSSCKFWT_H */
+
+/*
+ * nssCKFWHash
+ *
+ * nssCKFWHash_Create
+ * nssCKFWHash_Destroy
+ * nssCKFWHash_Add
+ * nssCKFWHash_Remove
+ * nssCKFWHash_Count
+ * nssCKFWHash_Exists
+ * nssCKFWHash_Lookup
+ * nssCKFWHash_Iterate
+ */
+
+/*
+ * nssCKFWHash_Create
+ *
+ */
+NSS_EXTERN nssCKFWHash *
+nssCKFWHash_Create
+(
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError
+);
+
+/*
+ * nssCKFWHash_Destroy
+ *
+ */
+NSS_EXTERN void
+nssCKFWHash_Destroy
+(
+ nssCKFWHash *hash
+);
+
+/*
+ * nssCKFWHash_Add
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWHash_Add
+(
+ nssCKFWHash *hash,
+ const void *key,
+ const void *value
+);
+
+/*
+ * nssCKFWHash_Remove
+ *
+ */
+NSS_EXTERN void
+nssCKFWHash_Remove
+(
+ nssCKFWHash *hash,
+ const void *it
+);
+
+/*
+ * nssCKFWHash_Count
+ *
+ */
+NSS_EXTERN CK_ULONG
+nssCKFWHash_Count
+(
+ nssCKFWHash *hash
+);
+
+/*
+ * nssCKFWHash_Exists
+ *
+ */
+NSS_EXTERN CK_BBOOL
+nssCKFWHash_Exists
+(
+ nssCKFWHash *hash,
+ const void *it
+);
+
+/*
+ * nssCKFWHash_Lookup
+ *
+ */
+NSS_EXTERN void *
+nssCKFWHash_Lookup
+(
+ nssCKFWHash *hash,
+ const void *it
+);
+
+/*
+ * nssCKFWHash_Iterate
+ *
+ */
+NSS_EXTERN void
+nssCKFWHash_Iterate
+(
+ nssCKFWHash *hash,
+ nssCKFWHashIterator fcn,
+ void *closure
+);
+
+#endif /* CKFWM_H */
diff --git a/security/nss/lib/ckfw/ckfwtm.h b/security/nss/lib/ckfw/ckfwtm.h
new file mode 100644
index 000000000..0f631f02d
--- /dev/null
+++ b/security/nss/lib/ckfw/ckfwtm.h
@@ -0,0 +1,56 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifndef CKFWTM_H
+#define CKFWTM_H
+
+#ifdef DEBUG
+static const char CKFWTM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * ckfwtm.h
+ *
+ * This file declares the module-private types of the NSS Cryptoki Framework.
+ */
+
+#ifndef NSSBASET_H
+#include "nssbaset.h"
+#endif /* NSSBASET_H */
+
+struct nssCKFWHashStr;
+typedef struct nssCKFWHashStr nssCKFWHash;
+
+typedef void (PR_CALLBACK *nssCKFWHashIterator)(const void *key, void *value, void *closure);
+
+#endif /* CKFWTM_H */
diff --git a/security/nss/lib/ckfw/ckmd.h b/security/nss/lib/ckfw/ckmd.h
new file mode 100644
index 000000000..5b7f394f5
--- /dev/null
+++ b/security/nss/lib/ckfw/ckmd.h
@@ -0,0 +1,65 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifndef CKMD_H
+#define CKMD_H
+
+#ifdef DEBUG
+static const char CKMD_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * ckmd.h
+ *
+ */
+
+NSS_EXTERN NSSCKMDObject *
+nssCKMDSessionObject_Create
+(
+ NSSCKFWToken *fwToken,
+ NSSArena *arena,
+ CK_ATTRIBUTE_PTR attributes,
+ CK_ULONG ulCount,
+ CK_RV *pError
+);
+
+NSS_EXTERN NSSCKMDFindObjects *
+nssCKMDFindSessionObjects_Create
+(
+ NSSCKFWToken *fwToken,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_RV *pError
+);
+
+#endif /* CKMD_H */
diff --git a/security/nss/lib/ckfw/ckt.h b/security/nss/lib/ckfw/ckt.h
new file mode 100644
index 000000000..9b9a471ca
--- /dev/null
+++ b/security/nss/lib/ckfw/ckt.h
@@ -0,0 +1,196 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifndef CKT_H
+#define CKT_H
+
+#ifdef DEBUG
+static const char CKT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * ckt.h
+ *
+ * This file contains the NSS-specific type definitions for Cryptoki
+ * (PKCS#11).
+ */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+/*
+ * NSSCK_VENDOR_NETSCAPE
+ *
+ * Cryptoki reserves the high half of all the number spaces for
+ * vendor-defined use. I'd like to keep all of our Netscape-
+ * specific values together, but not in the oh-so-obvious
+ * 0x80000001, 0x80000002, etc. area. So I've picked an offset,
+ * and constructed values for the beginnings of our spaces.
+ *
+ * Note that some "historical" Netscape values don't fall within
+ * this range.
+ */
+#define NSSCK_VENDOR_NETSCAPE 0x4E534350 /* NSCP */
+
+/*
+ * Netscape-defined object classes
+ *
+ */
+#define CKO_NETSCAPE (CKO_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
+
+#define CKO_NETSCAPE_CRL (CKO_NETSCAPE + 1)
+#define CKO_NETSCAPE_SMIME (CKO_NETSCAPE + 2)
+#define CKO_NETSCAPE_TRUST (CKO_NETSCAPE + 3)
+
+/*
+ * Netscape-defined key types
+ *
+ */
+#define CKK_NETSCAPE (CKK_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
+
+#define CKK_NETSCAPE_PKCS8 (CKK_NETSCAPE + 1)
+/*
+ * Netscape-defined certificate types
+ *
+ */
+#define CKC_NETSCAPE (CKC_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
+
+/*
+ * Netscape-defined object attributes
+ *
+ */
+#define CKA_NETSCAPE (CKA_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
+
+#define CKA_NETSCAPE_URL (CKA_NETSCAPE + 1)
+#define CKA_NETSCAPE_EMAIL (CKA_NETSCAPE + 2)
+#define CKA_NETSCAPE_SMIME_INFO (CKA_NETSCAPE + 3)
+#define CKA_NETSCAPE_SMIME_TIMESTAMP (CKA_NETSCAPE + 4)
+#define CKA_NETSCAPE_PKCS8_SALT (CKA_NETSCAPE + 5)
+#define CKA_NETSCAPE_PASSWORD_CHECK (CKA_NETSCAPE + 6)
+#define CKA_NETSCAPE_EXPIRES (CKA_NETSCAPE + 7)
+
+/*
+ * Trust attributes:
+ *
+ * If trust goes standard, these probably will too. So I'll
+ * put them all in one place.
+ */
+
+#define CKA_TRUST (CKA_NETSCAPE + 0x2000)
+
+/* "Usage" key information */
+#define CKA_TRUST_DIGITAL_SIGNATURE (CKA_TRUST + 1)
+#define CKA_TRUST_NON_REPUDIATION (CKA_TRUST + 2)
+#define CKA_TRUST_KEY_ENCIPHERMENT (CKA_TRUST + 3)
+#define CKA_TRUST_DATA_ENCIPHERMENT (CKA_TRUST + 4)
+#define CKA_TRUST_KEY_AGREEMENT (CKA_TRUST + 5)
+#define CKA_TRUST_KEY_CERT_SIGN (CKA_TRUST + 6)
+#define CKA_TRUST_CRL_SIGN (CKA_TRUST + 7)
+
+/* "Purpose" trust information */
+#define CKA_TRUST_SERVER_AUTH (CKA_TRUST + 8)
+#define CKA_TRUST_CLIENT_AUTH (CKA_TRUST + 9)
+#define CKA_TRUST_CODE_SIGNING (CKA_TRUST + 10)
+#define CKA_TRUST_EMAIL_PROTECTION (CKA_TRUST + 11)
+#define CKA_TRUST_IPSEC_END_SYSTEM (CKA_TRUST + 12)
+#define CKA_TRUST_IPSEC_TUNNEL (CKA_TRUST + 13)
+#define CKA_TRUST_IPSEC_USER (CKA_TRUST + 14)
+#define CKA_TRUST_TIME_STAMPING (CKA_TRUST + 15)
+
+/* Netscape trust stuff */
+/* XXX fgmr new ones here-- step-up, etc. */
+
+/* HISTORICAL: define used to pass in the database key for DSA private keys */
+#define CKA_NETSCAPE_DB 0xD5A0DB00L
+#define CKA_NETSCAPE_TRUST 0x80000001L
+
+/*
+ * Netscape-defined crypto mechanisms
+ *
+ */
+#define CKM_NETSCAPE (CKM_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
+/*
+ * HISTORICAL:
+ * Do not attempt to use these. They are only used by NETSCAPE's internal
+ * PKCS #11 interface. Most of these are place holders for other mechanism
+ * and will change in the future.
+ */
+#define CKM_NETSCAPE_PBE_KEY_GEN 0x80000001L
+#define CKM_NETSCAPE_PBE_SHA1_DES_CBC 0x80000002L
+#define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC 0x80000003L
+#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC 0x80000004L
+#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC 0x80000005L
+#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 0x80000006L
+#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 0x80000007L
+#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC 0x80000008L
+#define CKM_TLS_MASTER_KEY_DERIVE 0x80000371L
+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x80000372L
+
+/*
+ * Netscape-defined return values
+ *
+ */
+#define CKR_NETSCAPE (CKM_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
+
+/*
+ * Trust info
+ *
+ * This isn't part of the Cryptoki standard (yet), so I'm putting
+ * all the definitions here. Some of this would move to nssckt.h
+ * if trust info were made part of the standard. In view of this
+ * possibility, I'm putting my (Netscape) values in the netscape
+ * vendor space, like everything else.
+ */
+
+typedef CK_ULONG CK_TRUST;
+
+/* The following trust types are defined: */
+#define CKT_VENDOR_DEFINED 0x80000000
+
+#define CKT_NETSCAPE (CKT_VENDOR_DEFINED|NSSCK_VENDOR_NETSCAPE)
+
+/* If trust goes standard, these'll probably drop out of vendor space. */
+#define CKT_NETSCAPE_TRUSTED (CKT_NETSCAPE + 1)
+#define CKT_NETSCAPE_TRUSTED_DELEGATOR (CKT_NETSCAPE + 2)
+#define CKT_NETSCAPE_UNTRUSTED (CKT_NETSCAPE + 3)
+
+/*
+ * These may well remain Netscape-specific; I'm only using them
+ * to cache resolution data.
+ */
+#define CKT_NETSCAPE_VALID (CKT_NETSCAPE + 4)
+#define CKT_NETSCAPE_VALID_DELEGATOR (CKT_NETSCAPE + 5)
+
+
+#endif /* CKT_H */
diff --git a/security/nss/lib/ckfw/config.mk b/security/nss/lib/ckfw/config.mk
new file mode 100644
index 000000000..80b3135f4
--- /dev/null
+++ b/security/nss/lib/ckfw/config.mk
@@ -0,0 +1,37 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+CONFIG_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
+
+ifdef BUILD_IDG
+DEFINES += -DNSSDEBUG
+endif
diff --git a/security/nss/lib/ckfw/find.c b/security/nss/lib/ckfw/find.c
new file mode 100644
index 000000000..434e0a162
--- /dev/null
+++ b/security/nss/lib/ckfw/find.c
@@ -0,0 +1,408 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * find.c
+ *
+ * This file implements the nssCKFWFindObjects type and methods.
+ */
+
+#ifndef CK_H
+#include "ck.h"
+#endif /* CK_H */
+
+/*
+ * NSSCKFWFindObjects
+ *
+ * -- create/destroy --
+ * nssCKFWFindObjects_Create
+ * nssCKFWFindObjects_Destroy
+ *
+ * -- public accessors --
+ * NSSCKFWFindObjects_GetMDFindObjects
+ *
+ * -- implement public accessors --
+ * nssCKFWFindObjects_GetMDFindObjects
+ *
+ * -- private accessors --
+ *
+ * -- module fronts --
+ * nssCKFWFindObjects_Next
+ */
+
+struct NSSCKFWFindObjectsStr {
+ NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */
+ NSSCKMDFindObjects *mdfo1;
+ NSSCKMDFindObjects *mdfo2;
+ NSSCKFWSession *fwSession;
+ NSSCKMDSession *mdSession;
+ NSSCKFWToken *fwToken;
+ NSSCKMDToken *mdToken;
+ NSSCKFWInstance *fwInstance;
+ NSSCKMDInstance *mdInstance;
+
+ NSSCKMDFindObjects *mdFindObjects; /* varies */
+};
+
+#ifdef DEBUG
+/*
+ * But first, the pointer-tracking stuff.
+ *
+ * NOTE: the pointer-tracking support in NSS/base currently relies
+ * upon NSPR's CallOnce support. That, however, relies upon NSPR's
+ * locking, which is tied into the runtime. We need a pointer-tracker
+ * implementation that uses the locks supplied through C_Initialize.
+ * That support, however, can be filled in later. So for now, I'll
+ * just do these routines as no-ops.
+ */
+
+static CK_RV
+findObjects_add_pointer
+(
+ const NSSCKFWFindObjects *fwFindObjects
+)
+{
+ return CKR_OK;
+}
+
+static CK_RV
+findObjects_remove_pointer
+(
+ const NSSCKFWFindObjects *fwFindObjects
+)
+{
+ return CKR_OK;
+}
+
+NSS_IMPLEMENT CK_RV
+nssCKFWFindObjects_verifyPointer
+(
+ const NSSCKFWFindObjects *fwFindObjects
+)
+{
+ return CKR_OK;
+}
+
+#endif /* DEBUG */
+
+/*
+ * nssCKFWFindObjects_Create
+ *
+ */
+NSS_EXTERN NSSCKFWFindObjects *
+nssCKFWFindObjects_Create
+(
+ NSSCKFWSession *fwSession,
+ NSSCKFWToken *fwToken,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDFindObjects *mdFindObjects1,
+ NSSCKMDFindObjects *mdFindObjects2,
+ CK_RV *pError
+)
+{
+ NSSCKFWFindObjects *fwFindObjects;
+ NSSArena *arena;
+ NSSCKMDSession *mdSession;
+ NSSCKMDToken *mdToken;
+ NSSCKMDInstance *mdInstance;
+
+ mdSession = nssCKFWSession_GetMDSession(fwSession);
+ mdToken = nssCKFWToken_GetMDToken(fwToken);
+ mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
+
+ arena = nssCKFWSession_GetArena(fwSession, pError);
+ if( (NSSArena *)NULL == arena ) {
+ goto loser;
+ }
+
+ fwFindObjects = nss_ZNEW(arena, NSSCKFWFindObjects);
+ if( (NSSCKFWFindObjects *)NULL == fwFindObjects ) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ fwFindObjects->mdfo1 = mdFindObjects1;
+ fwFindObjects->mdfo2 = mdFindObjects2;
+ fwFindObjects->fwSession = fwSession;
+ fwFindObjects->mdSession = mdSession;
+ fwFindObjects->fwToken = fwToken;
+ fwFindObjects->mdToken = mdToken;
+ fwFindObjects->fwInstance = fwInstance;
+ fwFindObjects->mdInstance = mdInstance;
+
+ fwFindObjects->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
+ if( (NSSCKFWMutex *)NULL == fwFindObjects->mutex ) {
+ goto loser;
+ }
+
+#ifdef DEBUG
+ *pError = findObjects_add_pointer(fwFindObjects);
+ if( CKR_OK != *pError ) {
+ goto loser;
+ }
+#endif /* DEBUG */
+
+ return fwFindObjects;
+
+ loser:
+ nss_ZFreeIf(fwFindObjects);
+
+ if( (NSSCKMDFindObjects *)NULL != mdFindObjects1 ) {
+ if( (void *)NULL != (void *)mdFindObjects1->Final ) {
+ fwFindObjects->mdFindObjects = mdFindObjects1;
+ mdFindObjects1->Final(mdFindObjects1, fwFindObjects, mdSession,
+ fwSession, mdToken, fwToken, mdInstance, fwInstance);
+ }
+ }
+
+ if( (NSSCKMDFindObjects *)NULL != mdFindObjects2 ) {
+ if( (void *)NULL != (void *)mdFindObjects2->Final ) {
+ fwFindObjects->mdFindObjects = mdFindObjects2;
+ mdFindObjects2->Final(mdFindObjects2, fwFindObjects, mdSession,
+ fwSession, mdToken, fwToken, mdInstance, fwInstance);
+ }
+ }
+
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+
+ return (NSSCKFWFindObjects *)NULL;
+}
+
+
+/*
+ * nssCKFWFindObjects_Destroy
+ *
+ */
+NSS_EXTERN void
+nssCKFWFindObjects_Destroy
+(
+ NSSCKFWFindObjects *fwFindObjects
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) {
+ return;
+ }
+#endif /* NSSDEBUG */
+
+ (void)nssCKFWMutex_Destroy(fwFindObjects->mutex);
+
+ if( (NSSCKMDFindObjects *)NULL != fwFindObjects->mdfo1 ) {
+ if( (void *)NULL != (void *)fwFindObjects->mdfo1->Final ) {
+ fwFindObjects->mdFindObjects = fwFindObjects->mdfo1;
+ fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects,
+ fwFindObjects->mdSession, fwFindObjects->fwSession,
+ fwFindObjects->mdToken, fwFindObjects->fwToken,
+ fwFindObjects->mdInstance, fwFindObjects->fwInstance);
+ }
+ }
+
+ if( (NSSCKMDFindObjects *)NULL != fwFindObjects->mdfo2 ) {
+ if( (void *)NULL != (void *)fwFindObjects->mdfo2->Final ) {
+ fwFindObjects->mdFindObjects = fwFindObjects->mdfo2;
+ fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects,
+ fwFindObjects->mdSession, fwFindObjects->fwSession,
+ fwFindObjects->mdToken, fwFindObjects->fwToken,
+ fwFindObjects->mdInstance, fwFindObjects->fwInstance);
+ }
+ }
+
+ nss_ZFreeIf(fwFindObjects);
+
+#ifdef DEBUG
+ (void)findObjects_remove_pointer(fwFindObjects);
+#endif /* DEBUG */
+
+ return;
+}
+
+/*
+ * nssCKFWFindObjects_GetMDFindObjects
+ *
+ */
+NSS_EXTERN NSSCKMDFindObjects *
+nssCKFWFindObjects_GetMDFindObjects
+(
+ NSSCKFWFindObjects *fwFindObjects
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) {
+ return (NSSCKMDFindObjects *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwFindObjects->mdFindObjects;
+}
+
+/*
+ * nssCKFWFindObjects_Next
+ *
+ */
+NSS_EXTERN NSSCKFWObject *
+nssCKFWFindObjects_Next
+(
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSArena *arenaOpt,
+ CK_RV *pError
+)
+{
+ NSSCKMDObject *mdObject;
+ NSSCKFWObject *fwObject = (NSSCKFWObject *)NULL;
+ NSSArena *objArena;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWObject *)NULL;
+ }
+
+ *pError = nssCKFWFindObjects_verifyPointer(fwFindObjects);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWObject *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ *pError = nssCKFWMutex_Lock(fwFindObjects->mutex);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWObject *)NULL;
+ }
+
+ if( (NSSCKMDFindObjects *)NULL != fwFindObjects->mdfo1 ) {
+ if( (void *)NULL != (void *)fwFindObjects->mdfo1->Next ) {
+ fwFindObjects->mdFindObjects = fwFindObjects->mdfo1;
+ mdObject = fwFindObjects->mdfo1->Next(fwFindObjects->mdfo1,
+ fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession,
+ fwFindObjects->mdToken, fwFindObjects->fwToken,
+ fwFindObjects->mdInstance, fwFindObjects->fwInstance,
+ arenaOpt, pError);
+ if( (NSSCKMDObject *)NULL == mdObject ) {
+ if( CKR_OK != *pError ) {
+ goto done;
+ }
+
+ /* All done. */
+ fwFindObjects->mdfo1->Final(fwFindObjects->mdfo1, fwFindObjects,
+ fwFindObjects->mdSession, fwFindObjects->fwSession,
+ fwFindObjects->mdToken, fwFindObjects->fwToken,
+ fwFindObjects->mdInstance, fwFindObjects->fwInstance);
+ fwFindObjects->mdfo1 = (NSSCKMDFindObjects *)NULL;
+ } else {
+ goto wrap;
+ }
+ }
+ }
+
+ if( (NSSCKMDFindObjects *)NULL != fwFindObjects->mdfo2 ) {
+ if( (void *)NULL != (void *)fwFindObjects->mdfo2->Next ) {
+ fwFindObjects->mdFindObjects = fwFindObjects->mdfo2;
+ mdObject = fwFindObjects->mdfo2->Next(fwFindObjects->mdfo2,
+ fwFindObjects, fwFindObjects->mdSession, fwFindObjects->fwSession,
+ fwFindObjects->mdToken, fwFindObjects->fwToken,
+ fwFindObjects->mdInstance, fwFindObjects->fwInstance,
+ arenaOpt, pError);
+ if( (NSSCKMDObject *)NULL == mdObject ) {
+ if( CKR_OK != *pError ) {
+ goto done;
+ }
+
+ /* All done. */
+ fwFindObjects->mdfo2->Final(fwFindObjects->mdfo2, fwFindObjects,
+ fwFindObjects->mdSession, fwFindObjects->fwSession,
+ fwFindObjects->mdToken, fwFindObjects->fwToken,
+ fwFindObjects->mdInstance, fwFindObjects->fwInstance);
+ fwFindObjects->mdfo2 = (NSSCKMDFindObjects *)NULL;
+ } else {
+ goto wrap;
+ }
+ }
+ }
+
+ /* No more objects */
+ *pError = CKR_OK;
+ goto done;
+
+ wrap:
+ /*
+ * This is less than ideal-- we should determine if it's a token
+ * object or a session object, and use the appropriate arena.
+ * But that duplicates logic in nssCKFWObject_IsTokenObject.
+ * Worry about that later. For now, be conservative, and use
+ * the token arena.
+ */
+ objArena = nssCKFWToken_GetArena(fwFindObjects->fwToken, pError);
+ if( (NSSArena *)NULL == objArena ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_HOST_MEMORY;
+ }
+ goto done;
+ }
+
+ fwObject = nssCKFWObject_Create(objArena, mdObject,
+ fwFindObjects->fwSession, fwFindObjects->fwToken,
+ fwFindObjects->fwInstance, pError);
+ if( (NSSCKFWObject *)NULL == fwObject ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ }
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwFindObjects->mutex);
+ return fwObject;
+}
+
+/*
+ * NSSCKFWFindObjects_GetMDFindObjects
+ *
+ */
+
+NSS_EXTERN NSSCKMDFindObjects *
+NSSCKFWFindObjects_GetMDFindObjects
+(
+ NSSCKFWFindObjects *fwFindObjects
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWFindObjects_verifyPointer(fwFindObjects) ) {
+ return (NSSCKMDFindObjects *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWFindObjects_GetMDFindObjects(fwFindObjects);
+}
diff --git a/security/nss/lib/ckfw/hash.c b/security/nss/lib/ckfw/hash.c
new file mode 100644
index 000000000..f9790493b
--- /dev/null
+++ b/security/nss/lib/ckfw/hash.c
@@ -0,0 +1,334 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * hash.c
+ *
+ * This is merely a couple wrappers around NSPR's PLHashTable, using
+ * the identity hash and arena-aware allocators. The reason I did
+ * this is that hash tables are used in a few places throughout the
+ * NSS Cryptoki Framework in a fairly stereotyped way, and this allows
+ * me to pull the commonalities into one place. Should we ever want
+ * to change the implementation, it's all right here.
+ */
+
+#ifndef CK_T
+#include "ck.h"
+#endif /* CK_T */
+
+/*
+ * nssCKFWHash
+ *
+ * nssCKFWHash_Create
+ * nssCKFWHash_Destroy
+ * nssCKFWHash_Add
+ * nssCKFWHash_Remove
+ * nssCKFWHash_Count
+ * nssCKFWHash_Exists
+ * nssCKFWHash_Lookup
+ * nssCKFWHash_Iterate
+ */
+
+struct nssCKFWHashStr {
+ NSSCKFWMutex *mutex;
+
+ /*
+ * The invariant that mutex protects is:
+ * The count accurately reflects the hashtable state.
+ */
+
+ PLHashTable *plHashTable;
+ CK_ULONG count;
+};
+
+static PLHashNumber
+nss_ckfw_identity_hash
+(
+ const void *key
+)
+{
+ PRUint32 i = (PRUint32)key;
+ PR_ASSERT(sizeof(PLHashNumber) == sizeof(PRUint32));
+ return (PLHashNumber)i;
+}
+
+/*
+ * nssCKFWHash_Create
+ *
+ */
+NSS_IMPLEMENT nssCKFWHash *
+nssCKFWHash_Create
+(
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError
+)
+{
+ nssCKFWHash *rv;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (nssCKFWHash *)NULL;
+ }
+
+ if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
+ *pError = CKR_ARGUMENTS_BAD;
+ return (nssCKFWHash *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ rv = nss_ZNEW(arena, nssCKFWHash);
+ if( (nssCKFWHash *)NULL == rv ) {
+ *pError = CKR_HOST_MEMORY;
+ return (nssCKFWHash *)NULL;
+ }
+
+ rv->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
+ if( (NSSCKFWMutex *)NULL == rv->mutex ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (nssCKFWHash *)NULL;
+ }
+
+ rv->plHashTable = PL_NewHashTable(0, nss_ckfw_identity_hash,
+ PL_CompareValues, PL_CompareValues, &nssArenaHashAllocOps, arena);
+ if( (PLHashTable *)NULL == rv->plHashTable ) {
+ (void)nssCKFWMutex_Destroy(rv->mutex);
+ (void)nss_ZFreeIf(rv);
+ *pError = CKR_HOST_MEMORY;
+ return (nssCKFWHash *)NULL;
+ }
+
+ rv->count = 0;
+
+ return rv;
+}
+
+/*
+ * nssCKFWHash_Destroy
+ *
+ */
+NSS_IMPLEMENT void
+nssCKFWHash_Destroy
+(
+ nssCKFWHash *hash
+)
+{
+ (void)nssCKFWMutex_Destroy(hash->mutex);
+ PL_HashTableDestroy(hash->plHashTable);
+ (void)nss_ZFreeIf(hash);
+}
+
+/*
+ * nssCKFWHash_Add
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWHash_Add
+(
+ nssCKFWHash *hash,
+ const void *key,
+ const void *value
+)
+{
+ CK_RV error = CKR_OK;
+ PLHashEntry *he;
+
+ error = nssCKFWMutex_Lock(hash->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ he = PL_HashTableAdd(hash->plHashTable, key, (void *)value);
+ if( (PLHashEntry *)NULL == he ) {
+ error = CKR_HOST_MEMORY;
+ } else {
+ hash->count++;
+ }
+
+ (void)nssCKFWMutex_Unlock(hash->mutex);
+
+ return error;
+}
+
+/*
+ * nssCKFWHash_Remove
+ *
+ */
+NSS_IMPLEMENT void
+nssCKFWHash_Remove
+(
+ nssCKFWHash *hash,
+ const void *it
+)
+{
+ PRBool found;
+
+ if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
+ return;
+ }
+
+ found = PL_HashTableRemove(hash->plHashTable, it);
+ if( found ) {
+ hash->count--;
+ }
+
+ (void)nssCKFWMutex_Unlock(hash->mutex);
+ return;
+}
+
+/*
+ * nssCKFWHash_Count
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWHash_Count
+(
+ nssCKFWHash *hash
+)
+{
+ CK_ULONG count;
+
+ if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
+ return (CK_ULONG)0;
+ }
+
+ count = hash->count;
+
+ (void)nssCKFWMutex_Unlock(hash->mutex);
+
+ return count;
+}
+
+/*
+ * nssCKFWHash_Exists
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWHash_Exists
+(
+ nssCKFWHash *hash,
+ const void *it
+)
+{
+ void *value;
+
+ if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
+ return CK_FALSE;
+ }
+
+ value = PL_HashTableLookup(hash->plHashTable, it);
+
+ (void)nssCKFWMutex_Unlock(hash->mutex);
+
+ if( (void *)NULL == value ) {
+ return CK_FALSE;
+ } else {
+ return CK_TRUE;
+ }
+}
+
+/*
+ * nssCKFWHash_Lookup
+ *
+ */
+NSS_IMPLEMENT void *
+nssCKFWHash_Lookup
+(
+ nssCKFWHash *hash,
+ const void *it
+)
+{
+ void *rv;
+
+ if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
+ return (void *)NULL;
+ }
+
+ rv = PL_HashTableLookup(hash->plHashTable, it);
+
+ (void)nssCKFWMutex_Unlock(hash->mutex);
+
+ return rv;
+}
+
+struct arg_str {
+ nssCKFWHashIterator fcn;
+ void *closure;
+};
+
+static PRIntn
+nss_ckfwhash_enumerator
+(
+ PLHashEntry *he,
+ PRIntn index,
+ void *arg
+)
+{
+ struct arg_str *as = (struct arg_str *)arg;
+ as->fcn(he->key, he->value, as->closure);
+ return HT_ENUMERATE_NEXT;
+}
+
+/*
+ * nssCKFWHash_Iterate
+ *
+ * NOTE that the iteration function will be called with the hashtable locked.
+ */
+NSS_IMPLEMENT void
+nssCKFWHash_Iterate
+(
+ nssCKFWHash *hash,
+ nssCKFWHashIterator fcn,
+ void *closure
+)
+{
+ struct arg_str as;
+ as.fcn = fcn;
+ as.closure = closure;
+
+ if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
+ return;
+ }
+
+ PL_HashTableEnumerateEntries(hash->plHashTable, nss_ckfwhash_enumerator, &as);
+
+ (void)nssCKFWMutex_Unlock(hash->mutex);
+
+ return;
+}
diff --git a/security/nss/lib/ckfw/instance.c b/security/nss/lib/ckfw/instance.c
new file mode 100644
index 000000000..eb25793d9
--- /dev/null
+++ b/security/nss/lib/ckfw/instance.c
@@ -0,0 +1,1273 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * instance.c
+ *
+ * This file implements the NSSCKFWInstance type and methods.
+ */
+
+#ifndef CK_T
+#include "ck.h"
+#endif /* CK_T */
+
+/*
+ * NSSCKFWInstance
+ *
+ * -- create/destroy --
+ * nssCKFWInstance_Create
+ * nssCKFWInstance_Destroy
+ *
+ * -- public accessors --
+ * NSSCKFWInstance_GetMDInstance
+ * NSSCKFWInstance_GetArena
+ * NSSCKFWInstance_MayCreatePthreads
+ * NSSCKFWInstance_CreateMutex
+ * NSSCKFWInstance_GetConfigurationData
+ *
+ * -- implement public accessors --
+ * nssCKFWInstance_GetMDInstance
+ * nssCKFWInstance_GetArena
+ * nssCKFWInstance_MayCreatePthreads
+ * nssCKFWInstance_CreateMutex
+ * nssCKFWInstance_GetConfigurationData
+ *
+ * -- private accessors --
+ * nssCKFWInstance_CreateSessionHandle
+ * nssCKFWInstance_ResolveSessionHandle
+ * nssCKFWInstance_DestroySessionHandle
+ * nssCKFWInstance_FindSessionHandle
+ * nssCKFWInstance_CreateObjectHandle
+ * nssCKFWInstance_ResolveObjectHandle
+ * nssCKFWInstance_DestroyObjectHandle
+ *
+ * -- module fronts --
+ * nssCKFWInstance_GetNSlots
+ * nssCKFWInstance_GetCryptokiVersion
+ * nssCKFWInstance_GetManufacturerID
+ * nssCKFWInstance_GetFlags
+ * nssCKFWInstance_GetLibraryDescription
+ * nssCKFWInstance_GetLibraryVersion
+ * nssCKFWInstance_GetModuleHandlesSessionObjects
+ * nssCKFWInstance_GetSlots
+ * nssCKFWInstance_WaitForSlotEvent
+ *
+ * -- debugging versions only --
+ * nssCKFWInstance_verifyPointer
+ */
+
+struct NSSCKFWInstanceStr {
+ NSSCKFWMutex *mutex;
+ NSSArena *arena;
+ NSSCKMDInstance *mdInstance;
+ CK_C_INITIALIZE_ARGS_PTR pInitArgs;
+ CK_BBOOL mayCreatePthreads;
+ NSSUTF8 *configurationData;
+ CK_ULONG nSlots;
+ NSSCKFWSlot **fwSlotList;
+ NSSCKMDSlot **mdSlotList;
+ CK_BBOOL moduleHandlesSessionObjects;
+
+ /*
+ * Everything above is set at creation time, and then not modified.
+ * The invariants the mutex protects are:
+ *
+ * 1) Each of the cached descriptions (versions, etc.) are in an
+ * internally consistant state.
+ *
+ * 2) The session handle hashes and count are consistant
+ *
+ * 3) The object handle hashes and count are consistant.
+ *
+ * I could use multiple locks, but let's wait to see if that's
+ * really necessary.
+ *
+ * Note that the calls accessing the cached descriptions will
+ * call the NSSCKMDInstance methods with the mutex locked. Those
+ * methods may then call the public NSSCKFWInstance routines.
+ * Those public routines only access the constant data above, so
+ * there's no problem. But be careful if you add to this object;
+ * mutexes are in general not reentrant, so don't create deadlock
+ * situations.
+ */
+
+ CK_VERSION cryptokiVersion;
+ NSSUTF8 *manufacturerID;
+ NSSUTF8 *libraryDescription;
+ CK_VERSION libraryVersion;
+
+ CK_ULONG lastSessionHandle;
+ nssCKFWHash *sessionHandleHash;
+ nssCKFWHash *sessionHandleReverseHash;
+
+ CK_ULONG lastObjectHandle;
+ nssCKFWHash *objectHandleHash;
+};
+
+#ifdef DEBUG
+/*
+ * But first, the pointer-tracking stuff.
+ *
+ * NOTE: the pointer-tracking support in NSS/base currently relies
+ * upon NSPR's CallOnce support. That, however, relies upon NSPR's
+ * locking, which is tied into the runtime. We need a pointer-tracker
+ * implementation that uses the locks supplied through C_Initialize.
+ * That support, however, can be filled in later. So for now, I'll
+ * just do this routines as no-ops.
+ */
+
+static CK_RV
+instance_add_pointer
+(
+ const NSSCKFWInstance *fwInstance
+)
+{
+ return CKR_OK;
+}
+
+static CK_RV
+instance_remove_pointer
+(
+ const NSSCKFWInstance *fwInstance
+)
+{
+ return CKR_OK;
+}
+
+NSS_IMPLEMENT CK_RV
+nssCKFWInstance_verifyPointer
+(
+ const NSSCKFWInstance *fwInstance
+)
+{
+ return CKR_OK;
+}
+
+#endif /* DEBUG */
+
+/*
+ * nssCKFWInstance_Create
+ *
+ */
+NSS_IMPLEMENT NSSCKFWInstance *
+nssCKFWInstance_Create
+(
+ CK_C_INITIALIZE_ARGS_PTR pInitArgs,
+ NSSCKMDInstance *mdInstance,
+ CK_RV *pError
+)
+{
+ NSSCKFWInstance *fwInstance;
+ NSSArena *arena = (NSSArena *)NULL;
+ CK_ULONG i;
+ CK_BBOOL called_Initialize = CK_FALSE;
+
+#ifdef NSSDEBUG
+ if( (CK_RV)NULL == pError ) {
+ return (NSSCKFWInstance *)NULL;
+ }
+
+ if( (NSSCKMDInstance *)NULL == mdInstance ) {
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSCKFWInstance *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ arena = NSSArena_Create();
+ if( (NSSArena *)NULL == arena ) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKFWInstance *)NULL;
+ }
+
+ fwInstance = nss_ZNEW(arena, NSSCKFWInstance);
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ goto nomem;
+ }
+
+ fwInstance->arena = arena;
+ fwInstance->mdInstance = mdInstance;
+ fwInstance->pInitArgs = pInitArgs;
+
+ if( (CK_C_INITIALIZE_ARGS_PTR)NULL != pInitArgs ) {
+ if( pInitArgs->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS ) {
+ fwInstance->mayCreatePthreads = CK_FALSE;
+ } else {
+ fwInstance->mayCreatePthreads = CK_TRUE;
+ }
+ fwInstance->configurationData = (NSSUTF8 *)(pInitArgs->pReserved);
+ } else {
+ fwInstance->mayCreatePthreads = CK_TRUE;
+ }
+
+ fwInstance->mutex = nssCKFWMutex_Create(pInitArgs, arena, pError);
+ if( (NSSCKFWMutex *)NULL == fwInstance->mutex ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ goto loser;
+ }
+
+ if( (void *)NULL != (void *)mdInstance->Initialize ) {
+ *pError = mdInstance->Initialize(mdInstance, fwInstance, fwInstance->configurationData);
+ if( CKR_OK != *pError ) {
+ goto loser;
+ }
+
+ called_Initialize = CK_TRUE;
+ }
+
+ if( (void *)NULL != (void *)mdInstance->ModuleHandlesSessionObjects ) {
+ fwInstance->moduleHandlesSessionObjects =
+ mdInstance->ModuleHandlesSessionObjects(mdInstance, fwInstance);
+ } else {
+ fwInstance->moduleHandlesSessionObjects = CK_FALSE;
+ }
+
+ if( (void *)NULL == (void *)mdInstance->GetNSlots ) {
+ /* That routine is required */
+ *pError = CKR_GENERAL_ERROR;
+ goto loser;
+ }
+
+ fwInstance->nSlots = mdInstance->GetNSlots(mdInstance, fwInstance, pError);
+ if( (CK_ULONG)0 == fwInstance->nSlots ) {
+ if( CKR_OK == *pError ) {
+ /* Zero is not a legitimate answer */
+ *pError = CKR_GENERAL_ERROR;
+ }
+ goto loser;
+ }
+
+ fwInstance->fwSlotList = nss_ZNEWARRAY(arena, NSSCKFWSlot *, fwInstance->nSlots);
+ if( (NSSCKFWSlot **)NULL == fwInstance->fwSlotList ) {
+ goto nomem;
+ }
+
+ fwInstance->mdSlotList = nss_ZNEWARRAY(arena, NSSCKMDSlot *, fwInstance->nSlots);
+ if( (NSSCKMDSlot **)NULL == fwInstance->mdSlotList ) {
+ goto nomem;
+ }
+
+ fwInstance->sessionHandleHash = nssCKFWHash_Create(fwInstance,
+ fwInstance->arena, pError);
+ if( (nssCKFWHash *)NULL == fwInstance->sessionHandleHash ) {
+ goto loser;
+ }
+
+ fwInstance->sessionHandleReverseHash = nssCKFWHash_Create(fwInstance,
+ fwInstance->arena, pError);
+ if( (nssCKFWHash *)NULL == fwInstance->sessionHandleReverseHash ) {
+ goto loser;
+ }
+
+ fwInstance->objectHandleHash = nssCKFWHash_Create(fwInstance,
+ fwInstance->arena, pError);
+ if( (nssCKFWHash *)NULL == fwInstance->objectHandleHash ) {
+ goto loser;
+ }
+
+ if( (void *)NULL != (void *)mdInstance->GetSlots ) {
+ /* That routine is required */
+ *pError = CKR_GENERAL_ERROR;
+ goto loser;
+ }
+
+ *pError = mdInstance->GetSlots(mdInstance, fwInstance, fwInstance->mdSlotList);
+ if( CKR_OK != *pError ) {
+ goto loser;
+ }
+
+ for( i = 0; i < fwInstance->nSlots; i++ ) {
+ NSSCKMDSlot *mdSlot = fwInstance->mdSlotList[i];
+
+ if( (NSSCKMDSlot *)NULL == mdSlot ) {
+ *pError = CKR_GENERAL_ERROR;
+ goto loser;
+ }
+
+ fwInstance->fwSlotList[i] = nssCKFWSlot_Create(fwInstance, mdSlot, i, pError);
+ if( CKR_OK != *pError ) {
+ CK_ULONG j;
+
+ for( j = 0; j < i; j++ ) {
+ (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[j]);
+ }
+
+ for( j = i; j < fwInstance->nSlots; j++ ) {
+ NSSCKMDSlot *mds = fwInstance->mdSlotList[j];
+ if( (void *)NULL != (void *)mds->Destroy ) {
+ mds->Destroy(mds, (NSSCKFWSlot *)NULL, mdInstance, fwInstance);
+ }
+ }
+
+ goto loser;
+ }
+ }
+
+#ifdef DEBUG
+ *pError = instance_add_pointer(fwInstance);
+ if( CKR_OK != *pError ) {
+ for( i = 0; i < fwInstance->nSlots; i++ ) {
+ (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]);
+ }
+
+ goto loser;
+ }
+#endif /* DEBUG */
+
+ *pError = CKR_OK;
+ return fwInstance;
+
+ nomem:
+ *pError = CKR_HOST_MEMORY;
+ /*FALLTHROUGH*/
+ loser:
+
+ if( CK_TRUE == called_Initialize ) {
+ if( (void *)NULL != (void *)mdInstance->Finalize ) {
+ mdInstance->Finalize(mdInstance, fwInstance);
+ }
+ }
+
+ (void)NSSArena_Destroy(arena);
+ return (NSSCKFWInstance *)NULL;
+}
+
+/*
+ * nssCKFWInstance_Destroy
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWInstance_Destroy
+(
+ NSSCKFWInstance *fwInstance
+)
+{
+ CK_RV error = CKR_OK;
+ CK_ULONG i;
+
+#ifdef NSSDEBUG
+ error = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ nssCKFWMutex_Destroy(fwInstance->mutex);
+
+ for( i = 0; i < fwInstance->nSlots; i++ ) {
+ (void)nssCKFWSlot_Destroy(fwInstance->fwSlotList[i]);
+ }
+
+ if( (void *)NULL != (void *)fwInstance->mdInstance->Finalize ) {
+ fwInstance->mdInstance->Finalize(fwInstance->mdInstance, fwInstance);
+ }
+
+#ifdef DEBUG
+ (void)instance_remove_pointer(fwInstance);
+#endif /* DEBUG */
+
+ (void)NSSArena_Destroy(fwInstance->arena);
+ return CKR_OK;
+}
+
+/*
+ * nssCKFWInstance_GetMDInstance
+ *
+ */
+NSS_IMPLEMENT NSSCKMDInstance *
+nssCKFWInstance_GetMDInstance
+(
+ NSSCKFWInstance *fwInstance
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return (NSSCKMDInstance *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwInstance->mdInstance;
+}
+
+/*
+ * nssCKFWInstance_GetArena
+ *
+ */
+NSS_IMPLEMENT NSSArena *
+nssCKFWInstance_GetArena
+(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != *pError ) {
+ return (NSSArena *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ *pError = CKR_OK;
+ return fwInstance->arena;
+}
+
+/*
+ * nssCKFWInstance_MayCreatePthreads
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWInstance_MayCreatePthreads
+(
+ NSSCKFWInstance *fwInstance
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ return fwInstance->mayCreatePthreads;
+}
+
+/*
+ * nssCKFWInstance_CreateMutex
+ *
+ */
+NSS_IMPLEMENT NSSCKFWMutex *
+nssCKFWInstance_CreateMutex
+(
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError
+)
+{
+ NSSCKFWMutex *mutex;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWMutex *)NULL;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWMutex *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ if( (NSSArena *)NULL == arena ) {
+ arena = fwInstance->arena;
+ }
+
+ mutex = nssCKFWMutex_Create(fwInstance->pInitArgs, arena, pError);
+ if( (NSSCKFWMutex *)NULL == mutex ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+
+ return (NSSCKFWMutex *)NULL;
+ }
+
+ return mutex;
+}
+
+/*
+ * nssCKFWInstance_GetConfigurationData
+ *
+ */
+NSS_IMPLEMENT NSSUTF8 *
+nssCKFWInstance_GetConfigurationData
+(
+ NSSCKFWInstance *fwInstance
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return (NSSUTF8 *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwInstance->configurationData;
+}
+
+/*
+ * nssCKFWInstance_CreateSessionHandle
+ *
+ */
+NSS_IMPLEMENT CK_SESSION_HANDLE
+nssCKFWInstance_CreateSessionHandle
+(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+)
+{
+ CK_SESSION_HANDLE hSession;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (CK_SESSION_HANDLE)0;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != *pError ) {
+ return (CK_SESSION_HANDLE)0;
+ }
+#endif /* NSSDEBUG */
+
+ *pError = nssCKFWMutex_Lock(fwInstance->mutex);
+ if( CKR_OK != *pError ) {
+ return (CK_SESSION_HANDLE)0;
+ }
+
+ hSession = ++(fwInstance->lastSessionHandle);
+ *pError = nssCKFWHash_Add(fwInstance->sessionHandleHash,
+ (const void *)hSession, (const void *)fwSession);
+ if( CKR_OK != *pError ) {
+ hSession = (CK_SESSION_HANDLE)0;
+ goto done;
+ }
+
+ *pError = nssCKFWHash_Add(fwInstance->sessionHandleReverseHash,
+ (const void *)fwSession, (const void *)hSession);
+ if( CKR_OK != *pError ) {
+ nssCKFWHash_Remove(fwInstance->sessionHandleHash, (const void *)hSession);
+ hSession = (CK_SESSION_HANDLE)0;
+ }
+
+ done:
+ nssCKFWMutex_Unlock(fwInstance->mutex);
+ return hSession;
+}
+
+/*
+ * nssCKFWInstance_ResolveSessionHandle
+ *
+ */
+NSS_IMPLEMENT NSSCKFWSession *
+nssCKFWInstance_ResolveSessionHandle
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+)
+{
+ NSSCKFWSession *fwSession;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return (NSSCKFWSession *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
+ return (NSSCKFWSession *)NULL;
+ }
+
+ fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup(
+ fwInstance->sessionHandleHash, (const void *)hSession);
+
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+
+ return fwSession;
+}
+
+/*
+ * nssCKFWInstance_DestroySessionHandle
+ *
+ */
+NSS_IMPLEMENT void
+nssCKFWInstance_DestroySessionHandle
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+)
+{
+ NSSCKFWSession *fwSession;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
+ return;
+ }
+
+ fwSession = (NSSCKFWSession *)nssCKFWHash_Lookup(
+ fwInstance->sessionHandleHash, (const void *)hSession);
+
+ nssCKFWHash_Remove(fwInstance->sessionHandleHash, (const void *)hSession);
+ nssCKFWHash_Remove(fwInstance->sessionHandleReverseHash, (const void *)fwSession);
+
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+
+ return;
+}
+
+/*
+ * nssCKFWInstance_FindSessionHandle
+ *
+ */
+NSS_IMPLEMENT CK_SESSION_HANDLE
+nssCKFWInstance_FindSessionHandle
+(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWSession *fwSession
+)
+{
+ CK_SESSION_HANDLE hSession;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return (CK_SESSION_HANDLE)0;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
+ return (CK_SESSION_HANDLE)0;
+ }
+
+ hSession = (CK_SESSION_HANDLE)nssCKFWHash_Lookup(
+ fwInstance->sessionHandleReverseHash, (const void *)fwSession);
+
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+
+ return hSession;
+}
+
+/*
+ * nssCKFWInstance_CreateObjectHandle
+ *
+ */
+NSS_IMPLEMENT CK_OBJECT_HANDLE
+nssCKFWInstance_CreateObjectHandle
+(
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+)
+{
+ CK_OBJECT_HANDLE hObject;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (CK_OBJECT_HANDLE)0;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != *pError ) {
+ return (CK_OBJECT_HANDLE)0;
+ }
+#endif /* NSSDEBUG */
+
+ *pError = nssCKFWMutex_Lock(fwInstance->mutex);
+ if( CKR_OK != *pError ) {
+ return (CK_OBJECT_HANDLE)0;
+ }
+
+ hObject = ++(fwInstance->lastObjectHandle);
+ *pError = nssCKFWHash_Add(fwInstance->objectHandleHash,
+ (const void *)hObject, (const void *)fwObject);
+ if( CKR_OK != *pError ) {
+ hObject = (CK_OBJECT_HANDLE)0;
+ goto done;
+ }
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return hObject;
+}
+
+/*
+ * nssCKFWInstance_ResolveObjectHandle
+ *
+ */
+NSS_IMPLEMENT NSSCKFWObject *
+nssCKFWInstance_ResolveObjectHandle
+(
+ NSSCKFWInstance *fwInstance,
+ CK_OBJECT_HANDLE hObject
+)
+{
+ NSSCKFWObject *fwObject;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return (NSSCKFWObject *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
+ return (NSSCKFWObject *)NULL;
+ }
+
+ fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
+ fwInstance->objectHandleHash, (const void *)hObject);
+
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return fwObject;
+}
+
+/*
+ * nssCKFWInstance_ReassignObjectHandle
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWInstance_ReassignObjectHandle
+(
+ NSSCKFWInstance *fwInstance,
+ CK_OBJECT_HANDLE hObject,
+ NSSCKFWObject *fwObject
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwInstance->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ nssCKFWHash_Remove(fwInstance->objectHandleHash, (const void *)hObject);
+ error = nssCKFWHash_Add(fwInstance->objectHandleHash,
+ (const void *)hObject, (const void *)fwObject);
+
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return error;
+}
+
+/*
+ * nssCKFWInstance_DestroyObjectHandle
+ *
+ */
+NSS_IMPLEMENT void
+nssCKFWInstance_DestroyObjectHandle
+(
+ NSSCKFWInstance *fwInstance,
+ CK_OBJECT_HANDLE hObject
+)
+{
+ NSSCKFWObject *fwObject;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
+ return;
+ }
+
+ fwObject = (NSSCKFWObject *)nssCKFWHash_Lookup(
+ fwInstance->objectHandleHash, (const void *)hObject);
+
+ nssCKFWHash_Remove(fwInstance->objectHandleHash, (const void *)hObject);
+
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return;
+}
+
+/*
+ * nssCKFWInstance_GetNSlots
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWInstance_GetNSlots
+(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (CK_ULONG)0;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != *pError ) {
+ return (CK_ULONG)0;
+ }
+#endif /* NSSDEBUG */
+
+ *pError = CKR_OK;
+ return fwInstance->nSlots;
+}
+
+/*
+ * nssCKFWInstance_GetCryptokiVersion
+ *
+ */
+NSS_IMPLEMENT CK_VERSION
+nssCKFWInstance_GetCryptokiVersion
+(
+ NSSCKFWInstance *fwInstance
+)
+{
+ CK_VERSION rv;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ rv.major = rv.minor = 0;
+ return rv;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
+ rv.major = rv.minor = 0;
+ return rv;
+ }
+
+ if( (0 != fwInstance->cryptokiVersion.major) ||
+ (0 != fwInstance->cryptokiVersion.minor) ) {
+ rv = fwInstance->cryptokiVersion;
+ goto done;
+ }
+
+ if( (void *)NULL != (void *)fwInstance->mdInstance->GetCryptokiVersion ) {
+ fwInstance->cryptokiVersion = fwInstance->mdInstance->GetCryptokiVersion(
+ fwInstance->mdInstance, fwInstance);
+ } else {
+ fwInstance->cryptokiVersion.major = 2;
+ fwInstance->cryptokiVersion.minor = 1;
+ }
+
+ rv = fwInstance->cryptokiVersion;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWInstance_GetManufacturerID
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWInstance_GetManufacturerID
+(
+ NSSCKFWInstance *fwInstance,
+ CK_CHAR manufacturerID[32]
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ if( (CK_CHAR_PTR)NULL == manufacturerID ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ error = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwInstance->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (NSSUTF8 *)NULL == fwInstance->manufacturerID ) {
+ if( (void *)NULL != (void *)fwInstance->mdInstance->GetManufacturerID ) {
+ fwInstance->manufacturerID = fwInstance->mdInstance->GetManufacturerID(
+ fwInstance->mdInstance, fwInstance, &error);
+ if( ((NSSUTF8 *)NULL == fwInstance->manufacturerID) && (CKR_OK != error) ) {
+ goto done;
+ }
+ } else {
+ fwInstance->manufacturerID = "";
+ }
+ }
+
+ (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->manufacturerID, manufacturerID, 32, ' ');
+ error = CKR_OK;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return error;
+}
+
+/*
+ * nssCKFWInstance_GetFlags
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWInstance_GetFlags
+(
+ NSSCKFWInstance *fwInstance
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return (CK_ULONG)0;
+ }
+#endif /* NSSDEBUG */
+
+ /* No "instance flags" are yet defined by Cryptoki. */
+ return (CK_ULONG)0;
+}
+
+/*
+ * nssCKFWInstance_GetLibraryDescription
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWInstance_GetLibraryDescription
+(
+ NSSCKFWInstance *fwInstance,
+ CK_CHAR libraryDescription[32]
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ if( (CK_CHAR_PTR)NULL == libraryDescription ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ error = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwInstance->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (NSSUTF8 *)NULL == fwInstance->libraryDescription ) {
+ if( (void *)NULL != (void *)fwInstance->mdInstance->GetLibraryDescription ) {
+ fwInstance->libraryDescription = fwInstance->mdInstance->GetLibraryDescription(
+ fwInstance->mdInstance, fwInstance, &error);
+ if( ((NSSUTF8 *)NULL == fwInstance->libraryDescription) && (CKR_OK != error) ) {
+ goto done;
+ }
+ } else {
+ fwInstance->libraryDescription = "";
+ }
+ }
+
+ (void)nssUTF8_CopyIntoFixedBuffer(fwInstance->libraryDescription, libraryDescription, 32, ' ');
+ error = CKR_OK;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return error;
+}
+
+/*
+ * nssCKFWInstance_GetLibraryVersion
+ *
+ */
+NSS_IMPLEMENT CK_VERSION
+nssCKFWInstance_GetLibraryVersion
+(
+ NSSCKFWInstance *fwInstance
+)
+{
+ CK_VERSION rv;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ rv.major = rv.minor = 0;
+ return rv;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwInstance->mutex) ) {
+ rv.major = rv.minor = 0;
+ return rv;
+ }
+
+ if( (0 != fwInstance->libraryVersion.major) ||
+ (0 != fwInstance->libraryVersion.minor) ) {
+ rv = fwInstance->libraryVersion;
+ goto done;
+ }
+
+ if( (void *)NULL != (void *)fwInstance->mdInstance->GetLibraryVersion ) {
+ fwInstance->libraryVersion = fwInstance->mdInstance->GetLibraryVersion(
+ fwInstance->mdInstance, fwInstance);
+ } else {
+ fwInstance->libraryVersion.major = 0;
+ fwInstance->libraryVersion.minor = 1;
+ }
+
+ rv = fwInstance->libraryVersion;
+ done:
+ (void)nssCKFWMutex_Unlock(fwInstance->mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWInstance_GetModuleHandlesSessionObjects
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWInstance_GetModuleHandlesSessionObjects
+(
+ NSSCKFWInstance *fwInstance
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ return fwInstance->moduleHandlesSessionObjects;
+}
+
+/*
+ * nssCKFWInstance_GetSlots
+ *
+ */
+NSS_IMPLEMENT NSSCKFWSlot **
+nssCKFWInstance_GetSlots
+(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWSlot **)NULL;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWSlot **)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwInstance->fwSlotList;
+}
+
+/*
+ * nssCKFWInstance_WaitForSlotEvent
+ *
+ */
+NSS_IMPLEMENT NSSCKFWSlot *
+nssCKFWInstance_WaitForSlotEvent
+(
+ NSSCKFWInstance *fwInstance,
+ CK_BBOOL block,
+ CK_RV *pError
+)
+{
+ NSSCKFWSlot *fwSlot = (NSSCKFWSlot *)NULL;
+ NSSCKMDSlot *mdSlot;
+ CK_ULONG i, n;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWSlot *)NULL;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWSlot *)NULL;
+ }
+
+ switch( block ) {
+ case CK_TRUE:
+ case CK_FALSE:
+ break;
+ default:
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSCKFWSlot *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwInstance->mdInstance->WaitForSlotEvent ) {
+ *pError = CKR_NO_EVENT;
+ return (NSSCKFWSlot *)NULL;
+ }
+
+ mdSlot = fwInstance->mdInstance->WaitForSlotEvent(
+ fwInstance->mdInstance,
+ fwInstance,
+ block,
+ pError
+ );
+
+ if( (NSSCKMDSlot *)NULL == mdSlot ) {
+ return (NSSCKFWSlot *)NULL;
+ }
+
+ n = nssCKFWInstance_GetNSlots(fwInstance, pError);
+ if( ((CK_ULONG)0 == n) && (CKR_OK != *pError) ) {
+ return (NSSCKFWSlot *)NULL;
+ }
+
+ for( i = 0; i < n; i++ ) {
+ if( fwInstance->mdSlotList[i] == mdSlot ) {
+ fwSlot = fwInstance->fwSlotList[i];
+ break;
+ }
+ }
+
+ if( (NSSCKFWSlot *)NULL == fwSlot ) {
+ /* Internal error */
+ *pError = CKR_GENERAL_ERROR;
+ return (NSSCKFWSlot *)NULL;
+ }
+
+ return fwSlot;
+}
+
+/*
+ * NSSCKFWInstance_GetMDInstance
+ *
+ */
+NSS_IMPLEMENT NSSCKMDInstance *
+NSSCKFWInstance_GetMDInstance
+(
+ NSSCKFWInstance *fwInstance
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return (NSSCKMDInstance *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWInstance_GetMDInstance(fwInstance);
+}
+
+/*
+ * NSSCKFWInstance_GetArena
+ *
+ */
+NSS_IMPLEMENT NSSArena *
+NSSCKFWInstance_GetArena
+(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+#ifdef DEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != *pError ) {
+ return (NSSArena *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWInstance_GetArena(fwInstance, pError);
+}
+
+/*
+ * NSSCKFWInstance_MayCreatePthreads
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+NSSCKFWInstance_MayCreatePthreads
+(
+ NSSCKFWInstance *fwInstance
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return CK_FALSE;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWInstance_MayCreatePthreads(fwInstance);
+}
+
+/*
+ * NSSCKFWInstance_CreateMutex
+ *
+ */
+NSS_IMPLEMENT NSSCKFWMutex *
+NSSCKFWInstance_CreateMutex
+(
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError
+)
+{
+#ifdef DEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWMutex *)NULL;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWMutex *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
+}
+
+/*
+ * NSSCKFWInstance_GetConfigurationData
+ *
+ */
+NSS_IMPLEMENT NSSUTF8 *
+NSSCKFWInstance_GetConfigurationData
+(
+ NSSCKFWInstance *fwInstance
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWInstance_verifyPointer(fwInstance) ) {
+ return (NSSUTF8 *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWInstance_GetConfigurationData(fwInstance);
+}
diff --git a/security/nss/lib/ckfw/manifest.mn b/security/nss/lib/ckfw/manifest.mn
new file mode 100644
index 000000000..ee1896d3a
--- /dev/null
+++ b/security/nss/lib/ckfw/manifest.mn
@@ -0,0 +1,76 @@
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Netscape security libraries.
+#
+# The Initial Developer of the Original Code is Netscape
+# Communications Corporation. Portions created by Netscape are
+# Copyright (C) 1994-2000 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the
+# terms of the GNU General Public License Version 2 or later (the
+# "GPL"), in which case the provisions of the GPL are applicable
+# instead of those above. If you wish to allow use of your
+# version of this file only under the terms of the GPL and not to
+# allow others to use your version of this file under the MPL,
+# indicate your decision by deleting the provisions above and
+# replace them with the notice and other provisions required by
+# the GPL. If you do not delete the provisions above, a recipient
+# may use your version of this file under either the MPL or the
+# GPL.
+#
+MANIFEST_CVS_ID = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"
+
+CORE_DEPTH = ../../..
+
+PRIVATE_EXPORTS = \
+ ck.h \
+ ckfw.h \
+ ckfwm.h \
+ ckfwtm.h \
+ ckt.h \
+ $(NULL)
+
+EXPORTS = \
+ nssck.api \
+ nssckepv.h \
+ nssckft.h \
+ nssckfw.h \
+ nssckfwc.h \
+ nssckfwt.h \
+ nssckg.h \
+ nssckmdt.h \
+ nssckp.h \
+ nssckt.h \
+ nsscku.h \
+ $(NULL)
+
+MODULE = security
+
+CSRCS = \
+ find.c \
+ hash.c \
+ instance.c \
+ mutex.c \
+ object.c \
+ session.c \
+ sessobj.c \
+ slot.c \
+ token.c \
+ wrap.c \
+ $(NULL)
+
+REQUIRES = security nspr
+
+LIBRARY_NAME = nssckfw
diff --git a/security/nss/lib/ckfw/mutex.c b/security/nss/lib/ckfw/mutex.c
new file mode 100644
index 000000000..e4c363f31
--- /dev/null
+++ b/security/nss/lib/ckfw/mutex.c
@@ -0,0 +1,346 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * mutex.c
+ *
+ * This file implements a mutual-exclusion locking facility for Modules
+ * using the NSS Cryptoki Framework.
+ */
+
+#ifndef CK_T
+#include "ck.h"
+#endif /* CK_T */
+
+/*
+ * NSSCKFWMutex
+ *
+ * NSSCKFWMutex_Destroy
+ * NSSCKFWMutex_Lock
+ * NSSCKFWMutex_Unlock
+ *
+ * nssCKFWMutex_Create
+ * nssCKFWMutex_Destroy
+ * nssCKFWMutex_Lock
+ * nssCKFWMutex_Unlock
+ *
+ * -- debugging versions only --
+ * nssCKFWMutex_verifyPointer
+ *
+ */
+
+struct NSSCKFWMutexStr {
+ CK_VOID_PTR etc;
+
+ CK_DESTROYMUTEX Destroy;
+ CK_LOCKMUTEX Lock;
+ CK_UNLOCKMUTEX Unlock;
+};
+
+#ifdef DEBUG
+/*
+ * But first, the pointer-tracking stuff.
+ *
+ * NOTE: the pointer-tracking support in NSS/base currently relies
+ * upon NSPR's CallOnce support. That, however, relies upon NSPR's
+ * locking, which is tied into the runtime. We need a pointer-tracker
+ * implementation that uses the locks supplied through C_Initialize.
+ * That support, however, can be filled in later. So for now, I'll
+ * just do this routines as no-ops.
+ */
+
+static CK_RV
+mutex_add_pointer
+(
+ const NSSCKFWMutex *fwMutex
+)
+{
+ return CKR_OK;
+}
+
+static CK_RV
+mutex_remove_pointer
+(
+ const NSSCKFWMutex *fwMutex
+)
+{
+ return CKR_OK;
+}
+
+NSS_IMPLEMENT CK_RV
+nssCKFWMutex_verifyPointer
+(
+ const NSSCKFWMutex *fwMutex
+)
+{
+ return CKR_OK;
+}
+
+#endif /* DEBUG */
+
+static CK_RV
+mutex_noop
+(
+ CK_VOID_PTR pMutex
+)
+{
+ return CKR_OK;
+}
+
+/*
+ * nssCKFWMutex_Create
+ *
+ */
+NSS_EXTERN NSSCKFWMutex *
+nssCKFWMutex_Create
+(
+ CK_C_INITIALIZE_ARGS_PTR pInitArgs,
+ NSSArena *arena,
+ CK_RV *pError
+)
+{
+ NSSCKFWMutex *mutex;
+ CK_ULONG count = (CK_ULONG)0;
+ CK_BBOOL os_ok = CK_FALSE;
+ CK_VOID_PTR pMutex = (CK_VOID_PTR)NULL;
+
+ if( (CK_C_INITIALIZE_ARGS_PTR)NULL != pInitArgs ) {
+ if( (CK_CREATEMUTEX )NULL != pInitArgs->CreateMutex ) count++;
+ if( (CK_DESTROYMUTEX)NULL != pInitArgs->DestroyMutex ) count++;
+ if( (CK_LOCKMUTEX )NULL != pInitArgs->LockMutex ) count++;
+ if( (CK_UNLOCKMUTEX )NULL != pInitArgs->UnlockMutex ) count++;
+ os_ok = (pInitArgs->flags & CKF_OS_LOCKING_OK) ? CK_TRUE : CK_FALSE;
+
+ if( (0 != count) && (4 != count) ) {
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSCKFWMutex *)NULL;
+ }
+ }
+
+ if( (0 == count) && (CK_TRUE == os_ok) ) {
+ /*
+ * This is case #2 in the description of C_Initialize:
+ * The library will be called in a multithreaded way, but
+ * no routines were specified: os locking calls should be
+ * used. Unfortunately, this can be hard.. like, I think
+ * I may have to dynamically look up the entry points in
+ * the instance of NSPR already going in the application.
+ *
+ * I know that *we* always specify routines, so this only
+ * comes up if someone is using NSS to create their own
+ * PCKS#11 modules for other products. Oh, heck, I'll
+ * worry about this then.
+ */
+ *pError = CKR_CANT_LOCK;
+ return (NSSCKFWMutex *)NULL;
+ }
+
+ mutex = nss_ZNEW(arena, NSSCKFWMutex);
+ if( (NSSCKFWMutex *)NULL == mutex ) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKFWMutex *)NULL;
+ }
+
+ if( 0 == count ) {
+ /*
+ * With the above test out of the way, we know this is case
+ * #1 in the description of C_Initialize: this library will
+ * not be called in a multithreaded way. I'll just return
+ * an object with noop calls.
+ */
+
+ mutex->Destroy = (CK_DESTROYMUTEX)mutex_noop;
+ mutex->Lock = (CK_LOCKMUTEX )mutex_noop;
+ mutex->Unlock = (CK_UNLOCKMUTEX )mutex_noop;
+ } else {
+ /*
+ * We know that we're in either case #3 or #4 in the description
+ * of C_Initialize. Case #3 says we should use the specified
+ * functions, case #4 cays we can use either the specified ones
+ * or the OS ones. I'll use the specified ones.
+ */
+
+ mutex->Destroy = pInitArgs->DestroyMutex;
+ mutex->Lock = pInitArgs->LockMutex;
+ mutex->Unlock = pInitArgs->UnlockMutex;
+
+ *pError = pInitArgs->CreateMutex(&mutex->etc);
+ if( CKR_OK != *pError ) {
+ (void)nss_ZFreeIf(mutex);
+ return (NSSCKFWMutex *)NULL;
+ }
+ }
+
+#ifdef DEBUG
+ *pError = mutex_add_pointer(mutex);
+ if( CKR_OK != *pError ) {
+ (void)nss_ZFreeIf(mutex);
+ return (NSSCKFWMutex *)NULL;
+ }
+#endif /* DEBUG */
+
+ return mutex;
+}
+
+/*
+ * nssCKFWMutex_Destroy
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWMutex_Destroy
+(
+ NSSCKFWMutex *mutex
+)
+{
+ CK_RV rv = CKR_OK;
+
+#ifdef NSSDEBUG
+ rv = nssCKFWMutex_verifyPointer(mutex);
+ if( CKR_OK != rv ) {
+ return rv;
+ }
+#endif /* NSSDEBUG */
+
+ rv = mutex->Destroy(mutex->etc);
+
+#ifdef DEBUG
+ (void)mutex_remove_pointer(mutex);
+#endif /* DEBUG */
+
+ (void)nss_ZFreeIf(mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWMutex_Lock
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWMutex_Lock
+(
+ NSSCKFWMutex *mutex
+)
+{
+#ifdef NSSDEBUG
+ CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
+ if( CKR_OK != rv ) {
+ return rv;
+ }
+#endif /* NSSDEBUG */
+
+ return mutex->Lock(mutex->etc);
+}
+
+/*
+ * nssCKFWMutex_Unlock
+ *
+ */
+NSS_EXTERN CK_RV
+nssCKFWMutex_Unlock
+(
+ NSSCKFWMutex *mutex
+)
+{
+#ifdef NSSDEBUG
+ CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
+ if( CKR_OK != rv ) {
+ return rv;
+ }
+#endif /* NSSDEBUG */
+
+ return mutex->Unlock(mutex->etc);
+}
+
+/*
+ * NSSCKFWMutex_Destroy
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWMutex_Destroy
+(
+ NSSCKFWMutex *mutex
+)
+{
+#ifdef DEBUG
+ CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
+ if( CKR_OK != rv ) {
+ return rv;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWMutex_Destroy(mutex);
+}
+
+/*
+ * NSSCKFWMutex_Lock
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWMutex_Lock
+(
+ NSSCKFWMutex *mutex
+)
+{
+#ifdef DEBUG
+ CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
+ if( CKR_OK != rv ) {
+ return rv;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWMutex_Lock(mutex);
+}
+
+/*
+ * NSSCKFWMutex_Unlock
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWMutex_Unlock
+(
+ NSSCKFWMutex *mutex
+)
+{
+#ifdef DEBUG
+ CK_RV rv = nssCKFWMutex_verifyPointer(mutex);
+ if( CKR_OK != rv ) {
+ return rv;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWMutex_Unlock(mutex);
+}
diff --git a/security/nss/lib/ckfw/nssckfw.h b/security/nss/lib/ckfw/nssckfw.h
new file mode 100644
index 000000000..ce16f2b7b
--- /dev/null
+++ b/security/nss/lib/ckfw/nssckfw.h
@@ -0,0 +1,499 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifndef NSSCKFW_H
+#define NSSCKFW_H
+
+#ifdef DEBUG
+static const char NSSCKFW_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * nssckfw.h
+ *
+ * This file prototypes the publicly available calls of the
+ * NSS Cryptoki Framework.
+ */
+
+#ifndef NSSBASET_H
+#include "nssbaset.h"
+#endif /* NSSBASET_H */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+#ifndef NSSCKFWT_H
+#include "nssckfwt.h"
+#endif /* NSSCKFWT_H */
+
+/*
+ * NSSCKFWInstance
+ *
+ * NSSCKFWInstance_GetMDInstance
+ * NSSCKFWInstance_GetArena
+ * NSSCKFWInstance_MayCreatePthreads
+ * NSSCKFWInstance_CreateMutex
+ * NSSCKFWInstance_GetConfigurationData
+ */
+
+/*
+ * NSSCKFWInstance_GetMDInstance
+ *
+ */
+
+NSS_EXTERN NSSCKMDInstance *
+NSSCKFWInstance_GetMDInstance
+(
+ NSSCKFWInstance *fwInstance
+);
+
+/*
+ * NSSCKFWInstance_GetArena
+ *
+ */
+
+NSS_EXTERN NSSArena *
+NSSCKFWInstance_GetArena
+(
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+);
+
+/*
+ * NSSCKFWInstance_MayCreatePthreads
+ *
+ */
+
+NSS_EXTERN CK_BBOOL
+NSSCKFWInstance_MayCreatePthreads
+(
+ NSSCKFWInstance *fwInstance
+);
+
+/*
+ * NSSCKFWInstance_CreateMutex
+ *
+ */
+
+NSS_EXTERN NSSCKFWMutex *
+NSSCKFWInstance_CreateMutex
+(
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError
+);
+
+/*
+ * NSSCKFWInstance_GetConfigurationData
+ *
+ */
+
+NSS_EXTERN NSSUTF8 *
+NSSCKFWInstance_GetConfigurationData
+(
+ NSSCKFWInstance *fwInstance
+);
+
+/*
+ * NSSCKFWSlot
+ *
+ * NSSCKFWSlot_GetMDSlot
+ * NSSCKFWSlot_GetFWInstance
+ * NSSCKFWSlot_GetMDInstance
+ *
+ */
+
+/*
+ * NSSCKFWSlot_GetMDSlot
+ *
+ */
+
+NSS_EXTERN NSSCKMDSlot *
+NSSCKFWSlot_GetMDSlot
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * NSSCKFWSlot_GetFWInstance
+ *
+ */
+
+NSS_EXTERN NSSCKFWInstance *
+NSSCKFWSlot_GetFWInstance
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * NSSCKFWSlot_GetMDInstance
+ *
+ */
+
+NSS_EXTERN NSSCKMDInstance *
+NSSCKFWSlot_GetMDInstance
+(
+ NSSCKFWSlot *fwSlot
+);
+
+/*
+ * NSSCKFWToken
+ *
+ * NSSCKFWToken_GetMDToken
+ * NSSCKFWToken_GetFWSlot
+ * NSSCKFWToken_GetMDSlot
+ * NSSCKFWToken_GetSessionState
+ *
+ */
+
+/*
+ * NSSCKFWToken_GetMDToken
+ *
+ */
+
+NSS_EXTERN NSSCKMDToken *
+NSSCKFWToken_GetMDToken
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * NSSCKFWToken_GetArena
+ *
+ */
+
+NSS_EXTERN NSSArena *
+NSSCKFWToken_GetArena
+(
+ NSSCKFWToken *fwToken,
+ CK_RV *pError
+);
+
+/*
+ * NSSCKFWToken_GetFWSlot
+ *
+ */
+
+NSS_EXTERN NSSCKFWSlot *
+NSSCKFWToken_GetFWSlot
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * NSSCKFWToken_GetMDSlot
+ *
+ */
+
+NSS_EXTERN NSSCKMDSlot *
+NSSCKFWToken_GetMDSlot
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * NSSCKFWToken_GetSessionState
+ *
+ */
+
+NSS_EXTERN CK_STATE
+NSSCKFWSession_GetSessionState
+(
+ NSSCKFWToken *fwToken
+);
+
+/*
+ * NSSCKFWMechanism
+ *
+ * NSSKCFWMechanism_GetMDMechanism
+ * NSSCKFWMechanism_GetParameter
+ *
+ */
+
+/*
+ * NSSKCFWMechanism_GetMDMechanism
+ *
+ */
+
+NSS_EXTERN NSSCKMDMechanism *
+NSSCKFWMechanism_GetMDMechanism
+(
+ NSSCKFWMechanism *fwMechanism
+);
+
+/*
+ * NSSCKFWMechanism_GetParameter
+ *
+ */
+
+NSS_EXTERN NSSItem *
+NSSCKFWMechanism_GetParameter
+(
+ NSSCKFWMechanism *fwMechanism
+);
+
+/*
+ * NSSCKFWSession
+ *
+ * NSSCKFWSession_GetMDSession
+ * NSSCKFWSession_GetArena
+ * NSSCKFWSession_CallNotification
+ * NSSCKFWSession_IsRWSession
+ * NSSCKFWSession_IsSO
+ *
+ */
+
+/*
+ * NSSCKFWSession_GetMDSession
+ *
+ */
+
+NSS_EXTERN NSSCKMDSession *
+NSSCKFWSession_GetMDSession
+(
+ NSSCKFWSession *fwSession
+);
+
+/*
+ * NSSCKFWSession_GetArena
+ *
+ */
+
+NSS_EXTERN NSSArena *
+NSSCKFWSession_GetArena
+(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+);
+
+/*
+ * NSSCKFWSession_CallNotification
+ *
+ */
+
+NSS_EXTERN CK_RV
+NSSCKFWSession_CallNotification
+(
+ NSSCKFWSession *fwSession,
+ CK_NOTIFICATION event
+);
+
+/*
+ * NSSCKFWSession_IsRWSession
+ *
+ */
+
+NSS_EXTERN CK_BBOOL
+NSSCKFWSession_IsRWSession
+(
+ NSSCKFWSession *fwSession
+);
+
+/*
+ * NSSCKFWSession_IsSO
+ *
+ */
+
+NSS_EXTERN CK_BBOOL
+NSSCKFWSession_IsSO
+(
+ NSSCKFWSession *fwSession
+);
+
+/*
+ * NSSCKFWObject
+ *
+ * NSSCKFWObject_GetMDObject
+ * NSSCKFWObject_GetArena
+ * NSSCKFWObject_IsTokenObject
+ * NSSCKFWObject_GetAttributeCount
+ * NSSCKFWObject_GetAttributeTypes
+ * NSSCKFWObject_GetAttributeSize
+ * NSSCKFWObject_GetAttribute
+ * NSSCKFWObject_GetObjectSize
+ */
+
+/*
+ * NSSCKFWObject_GetMDObject
+ *
+ */
+NSS_EXTERN NSSCKMDObject *
+NSSCKFWObject_GetMDObject
+(
+ NSSCKFWObject *fwObject
+);
+
+/*
+ * NSSCKFWObject_GetArena
+ *
+ */
+NSS_EXTERN NSSArena *
+NSSCKFWObject_GetArena
+(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+);
+
+/*
+ * NSSCKFWObject_IsTokenObject
+ *
+ */
+NSS_EXTERN CK_BBOOL
+NSSCKFWObject_IsTokenObject
+(
+ NSSCKFWObject *fwObject
+);
+
+/*
+ * NSSCKFWObject_GetAttributeCount
+ *
+ */
+NSS_EXTERN CK_ULONG
+NSSCKFWObject_GetAttributeCount
+(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+);
+
+/*
+ * NSSCKFWObject_GetAttributeTypes
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWObject_GetAttributeTypes
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE_PTR typeArray,
+ CK_ULONG ulCount
+);
+
+/*
+ * NSSCKFWObject_GetAttributeSize
+ *
+ */
+NSS_EXTERN CK_ULONG
+NSSCKFWObject_GetAttributeSize
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+);
+
+/*
+ * NSSCKFWObject_GetAttribute
+ *
+ */
+NSS_EXTERN NSSItem *
+NSSCKFWObject_GetAttribute
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *itemOpt,
+ NSSArena *arenaOpt,
+ CK_RV *pError
+);
+
+/*
+ * NSSCKFWObject_GetObjectSize
+ *
+ */
+NSS_EXTERN CK_ULONG
+NSSCKFWObject_GetObjectSize
+(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+);
+
+/*
+ * NSSCKFWFindObjects
+ *
+ * NSSCKFWFindObjects_GetMDFindObjects
+ *
+ */
+
+/*
+ * NSSCKFWFindObjects_GetMDFindObjects
+ *
+ */
+
+NSS_EXTERN NSSCKMDFindObjects *
+NSSCKFWFindObjects_GetMDFindObjects
+(
+ NSSCKFWFindObjects *
+);
+
+/*
+ * NSSCKFWMutex
+ *
+ * NSSCKFWMutex_Destroy
+ * NSSCKFWMutex_Lock
+ * NSSCKFWMutex_Unlock
+ *
+ */
+
+/*
+ * NSSCKFWMutex_Destroy
+ *
+ */
+
+NSS_EXTERN CK_RV
+NSSCKFWMutex_Destroy
+(
+ NSSCKFWMutex *mutex
+);
+
+/*
+ * NSSCKFWMutex_Lock
+ *
+ */
+
+NSS_EXTERN CK_RV
+NSSCKFWMutex_Lock
+(
+ NSSCKFWMutex *mutex
+);
+
+/*
+ * NSSCKFWMutex_Unlock
+ *
+ */
+
+NSS_EXTERN CK_RV
+NSSCKFWMutex_Unlock
+(
+ NSSCKFWMutex *mutex
+);
+
+#endif /* NSSCKFW_H */
+
diff --git a/security/nss/lib/ckfw/nssckfwc.h b/security/nss/lib/ckfw/nssckfwc.h
new file mode 100644
index 000000000..02b15ec35
--- /dev/null
+++ b/security/nss/lib/ckfw/nssckfwc.h
@@ -0,0 +1,1046 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifndef NSSCKFWC_H
+#define NSSCKFWC_H
+
+#ifdef DEBUG
+static const char NSSCKFWC_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * nssckfwc.h
+ *
+ * This file prototypes all of the NSS Cryptoki Framework "wrapper"
+ * which implement the PKCS#11 API. Technically, these are public
+ * routines (with capital "NSS" prefixes), since they are called
+ * from (generated) code within a Module using the Framework.
+ * However, they should not be called except from those generated
+ * calls. Hence, the prototypes have been split out into this file.
+ */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+#ifndef NSSCKFWT_H
+#include "nssckfwt.h"
+#endif /* NSSCKFWT_H */
+
+#ifndef NSSCKMDT_H
+#include "nssckmdt.h"
+#endif /* NSSCKMDT_H */
+
+/*
+ * NSSCKFWC_Initialize
+ * NSSCKFWC_Finalize
+ * NSSCKFWC_GetInfo
+ * -- NSSCKFWC_GetFunctionList -- see the API insert file
+ * NSSCKFWC_GetSlotList
+ * NSSCKFWC_GetSlotInfo
+ * NSSCKFWC_GetTokenInfo
+ * NSSCKFWC_WaitForSlotEvent
+ * NSSCKFWC_GetMechanismList
+ * NSSCKFWC_GetMechanismInfo
+ * NSSCKFWC_InitToken
+ * NSSCKFWC_InitPIN
+ * NSSCKFWC_SetPIN
+ * NSSCKFWC_OpenSession
+ * NSSCKFWC_CloseSession
+ * NSSCKFWC_CloseAllSessions
+ * NSSCKFWC_GetSessionInfo
+ * NSSCKFWC_GetOperationState
+ * NSSCKFWC_SetOperationState
+ * NSSCKFWC_Login
+ * NSSCKFWC_Logout
+ * NSSCKFWC_CreateObject
+ * NSSCKFWC_CopyObject
+ * NSSCKFWC_DestroyObject
+ * NSSCKFWC_GetObjectSize
+ * NSSCKFWC_GetAttributeValue
+ * NSSCKFWC_SetAttributeValue
+ * NSSCKFWC_FindObjectsInit
+ * NSSCKFWC_FindObjects
+ * NSSCKFWC_FindObjectsFinal
+ * NSSCKFWC_EncryptInit
+ * NSSCKFWC_Encrypt
+ * NSSCKFWC_EncryptUpdate
+ * NSSCKFWC_EncryptFinal
+ * NSSCKFWC_DecryptInit
+ * NSSCKFWC_Decrypt
+ * NSSCKFWC_DecryptUpdate
+ * NSSCKFWC_DecryptFinal
+ * NSSCKFWC_DigestInit
+ * NSSCKFWC_Digest
+ * NSSCKFWC_DigestUpdate
+ * NSSCKFWC_DigestKey
+ * NSSCKFWC_DigestFinal
+ * NSSCKFWC_SignInit
+ * NSSCKFWC_Sign
+ * NSSCKFWC_SignUpdate
+ * NSSCKFWC_SignFinal
+ * NSSCKFWC_SignRecoverInit
+ * NSSCKFWC_SignRecover
+ * NSSCKFWC_VerifyInit
+ * NSSCKFWC_Verify
+ * NSSCKFWC_VerifyUpdate
+ * NSSCKFWC_VerifyFinal
+ * NSSCKFWC_VerifyRecoverInit
+ * NSSCKFWC_VerifyRecover
+ * NSSCKFWC_DigestEncryptUpdate
+ * NSSCKFWC_DecryptDigestUpdate
+ * NSSCKFWC_SignEncryptUpdate
+ * NSSCKFWC_DecryptVerifyUpdate
+ * NSSCKFWC_GenerateKey
+ * NSSCKFWC_GenerateKeyPair
+ * NSSCKFWC_WrapKey
+ * NSSCKFWC_UnwrapKey
+ * NSSCKFWC_DeriveKey
+ * NSSCKFWC_SeedRandom
+ * NSSCKFWC_GenerateRandom
+ * NSSCKFWC_GetFunctionStatus
+ * NSSCKFWC_CancelFunction
+ */
+
+/*
+ * NSSCKFWC_Initialize
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_Initialize
+(
+ NSSCKFWInstance **pFwInstance,
+ NSSCKMDInstance *mdInstance,
+ CK_VOID_PTR pInitArgs
+);
+
+/*
+ * NSSCKFWC_Finalize
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_Finalize
+(
+ NSSCKFWInstance **pFwInstance
+);
+
+/*
+ * NSSCKFWC_GetInfo
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GetInfo
+(
+ NSSCKFWInstance *fwInstance,
+ CK_INFO_PTR pInfo
+);
+
+/*
+ * C_GetFunctionList is implemented entirely in the Module's file which
+ * includes the Framework API insert file. It requires no "actual"
+ * NSSCKFW routine.
+ */
+
+/*
+ * NSSCKFWC_GetSlotList
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GetSlotList
+(
+ NSSCKFWInstance *fwInstance,
+ CK_BBOOL tokenPresent,
+ CK_SLOT_ID_PTR pSlotList,
+ CK_ULONG_PTR pulCount
+);
+
+/*
+ * NSSCKFWC_GetSlotInfo
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GetSlotInfo
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID,
+ CK_SLOT_INFO_PTR pInfo
+);
+
+/*
+ * NSSCKFWC_GetTokenInfo
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GetTokenInfo
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID,
+ CK_TOKEN_INFO_PTR pInfo
+);
+
+/*
+ * NSSCKFWC_WaitForSlotEvent
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_WaitForSlotEvent
+(
+ NSSCKFWInstance *fwInstance,
+ CK_FLAGS flags,
+ CK_SLOT_ID_PTR pSlot,
+ CK_VOID_PTR pReserved
+);
+
+/*
+ * NSSCKFWC_GetMechanismList
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GetMechanismList
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID,
+ CK_MECHANISM_TYPE_PTR pMechanismList,
+ CK_ULONG_PTR pulCount
+);
+
+/*
+ * NSSCKFWC_GetMechanismInfo
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GetMechanismInfo
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID,
+ CK_MECHANISM_TYPE type,
+ CK_MECHANISM_INFO_PTR pInfo
+);
+
+/*
+ * NSSCKFWC_InitToken
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_InitToken
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID,
+ CK_CHAR_PTR pPin,
+ CK_ULONG ulPinLen,
+ CK_CHAR_PTR pLabel
+);
+
+/*
+ * NSSCKFWC_InitPIN
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_InitPIN
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_CHAR_PTR pPin,
+ CK_ULONG ulPinLen
+);
+
+/*
+ * NSSCKFWC_SetPIN
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_SetPIN
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_CHAR_PTR pOldPin,
+ CK_ULONG ulOldLen,
+ CK_CHAR_PTR pNewPin,
+ CK_ULONG ulNewLen
+);
+
+/*
+ * NSSCKFWC_OpenSession
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_OpenSession
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID,
+ CK_FLAGS flags,
+ CK_VOID_PTR pApplication,
+ CK_NOTIFY Notify,
+ CK_SESSION_HANDLE_PTR phSession
+);
+
+/*
+ * NSSCKFWC_CloseSession
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_CloseSession
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+);
+
+/*
+ * NSSCKFWC_CloseAllSessions
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_CloseAllSessions
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID
+);
+
+/*
+ * NSSCKFWC_GetSessionInfo
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GetSessionInfo
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_SESSION_INFO_PTR pInfo
+);
+
+/*
+ * NSSCKFWC_GetOperationState
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GetOperationState
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pOperationState,
+ CK_ULONG_PTR pulOperationStateLen
+);
+
+/*
+ * NSSCKFWC_SetOperationState
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_SetOperationState
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pOperationState,
+ CK_ULONG ulOperationStateLen,
+ CK_OBJECT_HANDLE hEncryptionKey,
+ CK_OBJECT_HANDLE hAuthenticationKey
+);
+
+/*
+ * NSSCKFWC_Login
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_Login
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_USER_TYPE userType,
+ CK_CHAR_PTR pPin,
+ CK_ULONG ulPinLen
+);
+
+/*
+ * NSSCKFWC_Logout
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_Logout
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+);
+
+/*
+ * NSSCKFWC_CreateObject
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_CreateObject
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phObject
+);
+
+/*
+ * NSSCKFWC_CopyObject
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_CopyObject
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phNewObject
+);
+
+/*
+ * NSSCKFWC_DestroyObject
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_DestroyObject
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject
+);
+
+/*
+ * NSSCKFWC_GetObjectSize
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GetObjectSize
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ULONG_PTR pulSize
+);
+
+/*
+ * NSSCKFWC_GetAttributeValue
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GetAttributeValue
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount
+);
+
+/*
+ * NSSCKFWC_SetAttributeValue
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_SetAttributeValue
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount
+);
+
+/*
+ * NSSCKFWC_FindObjectsInit
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_FindObjectsInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount
+);
+
+/*
+ * NSSCKFWC_FindObjects
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_FindObjects
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE_PTR phObject,
+ CK_ULONG ulMaxObjectCount,
+ CK_ULONG_PTR pulObjectCount
+);
+
+/*
+ * NSSCKFWC_FindObjectsFinal
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_FindObjectsFinal
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+);
+
+/*
+ * NSSCKFWC_EncryptInit
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_EncryptInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey
+);
+
+/*
+ * NSSCKFWC_Encrypt
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_Encrypt
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pEncryptedData,
+ CK_ULONG_PTR pulEncryptedDataLen
+);
+
+/*
+ * NSSCKFWC_EncryptUpdate
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_EncryptUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG_PTR pulEncryptedPartLen
+);
+
+/*
+ * NSSCKFWC_EncryptFinal
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_EncryptFinal
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pLastEncryptedPart,
+ CK_ULONG_PTR pulLastEncryptedPartLen
+);
+
+/*
+ * NSSCKFWC_DecryptInit
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_DecryptInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey
+);
+
+/*
+ * NSSCKFWC_Decrypt
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_Decrypt
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pEncryptedData,
+ CK_ULONG ulEncryptedDataLen,
+ CK_BYTE_PTR pData,
+ CK_ULONG_PTR pulDataLen
+);
+
+/*
+ * NSSCKFWC_DecryptUpdate
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_DecryptUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG ulEncryptedPartLen,
+ CK_BYTE_PTR pPart,
+ CK_ULONG_PTR pulPartLen
+);
+
+/*
+ * NSSCKFWC_DecryptFinal
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_DecryptFinal
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pLastPart,
+ CK_ULONG_PTR pulLastPartLen
+);
+
+/*
+ * NSSCKFWC_DigestInit
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_DigestInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism
+);
+
+/*
+ * NSSCKFWC_Digest
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_Digest
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pDigest,
+ CK_ULONG_PTR pulDigestLen
+);
+
+/*
+ * NSSCKFWC_DigestUpdate
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_DigestUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen
+);
+
+/*
+ * NSSCKFWC_DigestKey
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_DigestKey
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hKey
+);
+
+/*
+ * NSSCKFWC_DigestFinal
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_DigestFinal
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pDigest,
+ CK_ULONG_PTR pulDigestLen
+);
+
+/*
+ * NSSCKFWC_SignInit
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_SignInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey
+);
+
+/*
+ * NSSCKFWC_Sign
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_Sign
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen
+);
+
+/*
+ * NSSCKFWC_SignUpdate
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_SignUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen
+);
+
+/*
+ * NSSCKFWC_SignFinal
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_SignFinal
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen
+);
+
+/*
+ * NSSCKFWC_SignRecoverInit
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_SignRecoverInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey
+);
+
+/*
+ * NSSCKFWC_SignRecover
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_SignRecover
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen
+);
+
+/*
+ * NSSCKFWC_VerifyInit
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_VerifyInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey
+);
+
+/*
+ * NSSCKFWC_Verify
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_Verify
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen
+);
+
+/*
+ * NSSCKFWC_VerifyUpdate
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_VerifyUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen
+);
+
+/*
+ * NSSCKFWC_VerifyFinal
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_VerifyFinal
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen
+);
+
+/*
+ * NSSCKFWC_VerifyRecoverInit
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_VerifyRecoverInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey
+);
+
+/*
+ * NSSCKFWC_VerifyRecover
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_VerifyRecover
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen,
+ CK_BYTE_PTR pData,
+ CK_ULONG_PTR pulDataLen
+);
+
+/*
+ * NSSCKFWC_DigestEncryptUpdate
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_DigestEncryptUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG_PTR pulEncryptedPartLen
+);
+
+/*
+ * NSSCKFWC_DecryptDigestUpdate
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_DecryptDigestUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG ulEncryptedPartLen,
+ CK_BYTE_PTR pPart,
+ CK_ULONG_PTR pulPartLen
+);
+
+/*
+ * NSSCKFWC_SignEncryptUpdate
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_SignEncryptUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG_PTR pulEncryptedPartLen
+);
+
+/*
+ * NSSCKFWC_DecryptVerifyUpdate
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_DecryptVerifyUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG ulEncryptedPartLen,
+ CK_BYTE_PTR pPart,
+ CK_ULONG_PTR pulPartLen
+);
+
+/*
+ * NSSCKFWC_GenerateKey
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GenerateKey
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phKey
+);
+
+/*
+ * NSSCKFWC_GenerateKeyPair
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GenerateKeyPair
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate,
+ CK_ULONG ulPublicKeyAttributeCount,
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
+ CK_ULONG ulPrivateKeyAttributeCount,
+ CK_OBJECT_HANDLE_PTR phPublicKey,
+ CK_OBJECT_HANDLE_PTR phPrivateKey
+);
+
+/*
+ * NSSCKFWC_WrapKey
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_WrapKey
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hWrappingKey,
+ CK_OBJECT_HANDLE hKey,
+ CK_BYTE_PTR pWrappedKey,
+ CK_ULONG_PTR pulWrappedKeyLen
+);
+
+/*
+ * NSSCKFWC_UnwrapKey
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_UnwrapKey
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hUnwrappingKey,
+ CK_BYTE_PTR pWrappedKey,
+ CK_ULONG ulWrappedKeyLen,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey
+);
+
+/*
+ * NSSCKFWC_DeriveKey
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_DeriveKey
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hBaseKey,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey
+);
+
+/*
+ * NSSCKFWC_SeedRandom
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_SeedRandom
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSeed,
+ CK_ULONG ulSeedLen
+);
+
+/*
+ * NSSCKFWC_GenerateRandom
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GenerateRandom
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pRandomData,
+ CK_ULONG ulRandomLen
+);
+
+/*
+ * NSSCKFWC_GetFunctionStatus
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_GetFunctionStatus
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+);
+
+/*
+ * NSSCKFWC_CancelFunction
+ *
+ */
+NSS_EXTERN CK_RV
+NSSCKFWC_CancelFunction
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+);
+
+#endif /* NSSCKFWC_H */
diff --git a/security/nss/lib/ckfw/nssckfwt.h b/security/nss/lib/ckfw/nssckfwt.h
new file mode 100644
index 000000000..13be0f325
--- /dev/null
+++ b/security/nss/lib/ckfw/nssckfwt.h
@@ -0,0 +1,111 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifndef NSSCKFWT_H
+#define NSSCKFWT_H
+
+#ifdef DEBUG
+static const char NSSCKFWT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * nssckfwt.h
+ *
+ * This file declares the public types used by the NSS Cryptoki Framework.
+ */
+
+/*
+ * NSSCKFWInstance
+ *
+ */
+
+struct NSSCKFWInstanceStr;
+typedef struct NSSCKFWInstanceStr NSSCKFWInstance;
+
+/*
+ * NSSCKFWSlot
+ *
+ */
+
+struct NSSCKFWSlotStr;
+typedef struct NSSCKFWSlotStr NSSCKFWSlot;
+
+/*
+ * NSSCKFWToken
+ *
+ */
+
+struct NSSCKFWTokenStr;
+typedef struct NSSCKFWTokenStr NSSCKFWToken;
+
+/*
+ * NSSCKFWMechanism
+ *
+ */
+
+struct NSSCKFWMechanismStr;
+typedef struct NSSCKFWMechanismStr NSSCKFWMechanism;
+
+/*
+ * NSSCKFWSession
+ *
+ */
+
+struct NSSCKFWSessionStr;
+typedef struct NSSCKFWSessionStr NSSCKFWSession;
+
+/*
+ * NSSCKFWObject
+ *
+ */
+
+struct NSSCKFWObjectStr;
+typedef struct NSSCKFWObjectStr NSSCKFWObject;
+
+/*
+ * NSSCKFWFindObjects
+ *
+ */
+
+struct NSSCKFWFindObjectsStr;
+typedef struct NSSCKFWFindObjectsStr NSSCKFWFindObjects;
+
+/*
+ * NSSCKFWMutex
+ *
+ */
+
+struct NSSCKFWMutexStr;
+typedef struct NSSCKFWMutexStr NSSCKFWMutex;
+
+#endif /* NSSCKFWT_H */
diff --git a/security/nss/lib/ckfw/nssckmdt.h b/security/nss/lib/ckfw/nssckmdt.h
new file mode 100644
index 000000000..d45a089d2
--- /dev/null
+++ b/security/nss/lib/ckfw/nssckmdt.h
@@ -0,0 +1,2014 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifndef NSSCKMDT_H
+#define NSSCKMDT_H
+
+#ifdef DEBUG
+static const char NSSCKMDT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * nssckmdt.h
+ *
+ * This file specifies the basic types that must be implemented by
+ * any Module using the NSS Cryptoki Framework.
+ */
+
+#ifndef NSSBASET_H
+#include "nssbaset.h"
+#endif /* NSSBASET_H */
+
+#ifndef NSSCKT_H
+#include "nssckt.h"
+#endif /* NSSCKT_H */
+
+#ifndef NSSCKFWT_H
+#include "nssckfwt.h"
+#endif /* NSSCKFWT_H */
+
+typedef struct NSSCKMDInstanceStr NSSCKMDInstance;
+typedef struct NSSCKMDSlotStr NSSCKMDSlot;
+typedef struct NSSCKMDTokenStr NSSCKMDToken;
+typedef struct NSSCKMDSessionStr NSSCKMDSession;
+typedef struct NSSCKMDFindObjectsStr NSSCKMDFindObjects;
+typedef struct NSSCKMDMechanismStr NSSCKMDMechanism;
+typedef struct NSSCKMDObjectStr NSSCKMDObject;
+
+/*
+ * NSSCKMDInstance
+ *
+ * This is the basic handle for an instance of a PKCS#11 Module.
+ * It is returned by the Module's CreateInstance routine, and
+ * may be obtained from the corresponding NSSCKFWInstance object.
+ * It contains a pointer for use by the Module, to store any
+ * instance-related data, and it contains the EPV for a set of
+ * routines which the Module may implement for use by the Framework.
+ * Some of these routines are optional; others are mandatory.
+ */
+
+struct NSSCKMDInstanceStr {
+ /*
+ * The Module may use this pointer for its own purposes.
+ */
+ void *etc;
+
+ /*
+ * This routine is called by the Framework to initialize
+ * the Module. This routine is optional; if unimplemented,
+ * it won't be called. If this routine returns an error,
+ * then the initialization will fail.
+ */
+ CK_RV (PR_CALLBACK *Initialize)(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSUTF8 *configurationData
+ );
+
+ /*
+ * This routine is called when the Framework is finalizing
+ * the PKCS#11 Module. It is the last thing called before
+ * the NSSCKFWInstance's NSSArena is destroyed. This routine
+ * is optional; if unimplemented, it merely won't be called.
+ */
+ void (PR_CALLBACK *Finalize)(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine gets the number of slots. This value must
+ * never change, once the instance is initialized. This
+ * routine must be implemented. It may return zero on error.
+ */
+ CK_ULONG (PR_CALLBACK *GetNSlots)(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine returns the version of the Cryptoki standard
+ * to which this Module conforms. This routine is optional;
+ * if unimplemented, the Framework uses the version to which
+ * ~it~ was implemented.
+ */
+ CK_VERSION (PR_CALLBACK *GetCryptokiVersion)(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns a pointer to a UTF8-encoded string
+ * containing the manufacturer ID for this Module. Only
+ * the characters completely encoded in the first thirty-
+ * two bytes are significant. This routine is optional.
+ * The string returned is never freed; if dynamically generated,
+ * the space for it should be allocated from the NSSArena
+ * that may be obtained from the NSSCKFWInstance. This
+ * routine may return NULL upon error; however if *pError
+ * is CKR_OK, the NULL will be considered the valid response.
+ */
+ NSSUTF8 *(PR_CALLBACK *GetManufacturerID)(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine returns a pointer to a UTF8-encoded string
+ * containing a description of this Module library. Only
+ * the characters completely encoded in the first thirty-
+ * two bytes are significant. This routine is optional.
+ * The string returned is never freed; if dynamically generated,
+ * the space for it should be allocated from the NSSArena
+ * that may be obtained from the NSSCKFWInstance. This
+ * routine may return NULL upon error; however if *pError
+ * is CKR_OK, the NULL will be considered the valid response.
+ */
+ NSSUTF8 *(PR_CALLBACK *GetLibraryDescription)(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine returns the version of this Module library.
+ * This routine is optional; if unimplemented, the Framework
+ * will assume a Module library version of 0.1.
+ */
+ CK_VERSION (PR_CALLBACK *GetLibraryVersion)(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns CK_TRUE if the Module wishes to
+ * handle session objects. This routine is optional.
+ * If this routine is NULL, or if it exists but returns
+ * CK_FALSE, the Framework will assume responsibility
+ * for managing session objects.
+ */
+ CK_BBOOL (PR_CALLBACK *ModuleHandlesSessionObjects)(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine stuffs pointers to NSSCKMDSlot objects into
+ * the specified array; one for each slot supported by this
+ * instance. The Framework will determine the size needed
+ * for the array by calling GetNSlots. This routine is
+ * required.
+ */
+ CK_RV (PR_CALLBACK *GetSlots)(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDSlot *slots[]
+ );
+
+ /*
+ * This call returns a pointer to the slot in which an event
+ * has occurred. If the block argument is CK_TRUE, the call
+ * should block until a slot event occurs; if CK_FALSE, it
+ * should check to see if an event has occurred, occurred,
+ * but return NULL (and set *pError to CK_NO_EVENT) if one
+ * hasn't. This routine is optional; if unimplemented, the
+ * Framework will assume that no event has happened. This
+ * routine may return NULL upon error.
+ */
+ NSSCKMDSlot *(PR_CALLBACK *WaitForSlotEvent)(
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_BBOOL block,
+ CK_RV *pError
+ );
+
+ /*
+ * This object may be extended in future versions of the
+ * NSS Cryptoki Framework. To allow for some flexibility
+ * in the area of binary compatibility, this field should
+ * be NULL.
+ */
+ void *null;
+};
+
+
+/*
+ * NSSCKMDSlot
+ *
+ * This is the basic handle for a PKCS#11 Module Slot. It is
+ * created by the NSSCKMDInstance->GetSlots call, and may be
+ * obtained from the Framework's corresponding NSSCKFWSlot
+ * object. It contains a pointer for use by the Module, to
+ * store any slot-related data, and it contains the EPV for
+ * a set of routines which the Module may implement for use
+ * by the Framework. Some of these routines are optional.
+ */
+
+struct NSSCKMDSlotStr {
+ /*
+ * The Module may use this pointer for its own purposes.
+ */
+ void *etc;
+
+ /*
+ * This routine is called during the Framework initialization
+ * step, after the Framework Instance has obtained the list
+ * of slots (by calling NSSCKMDInstance->GetSlots). Any slot-
+ * specific initialization can be done here. This routine is
+ * optional; if unimplemented, it won't be called. Note that
+ * if this routine returns an error, the entire Framework
+ * initialization for this Module will fail.
+ */
+ CK_RV (PR_CALLBACK *Initialize)(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine is called when the Framework is finalizing
+ * the PKCS#11 Module. This call (for each of the slots)
+ * is the last thing called before NSSCKMDInstance->Finalize.
+ * This routine is optional; if unimplemented, it merely
+ * won't be called. Note: In the rare circumstance that
+ * the Framework initialization cannot complete (due to,
+ * for example, memory limitations), this can be called with
+ * a NULL value for fwSlot.
+ */
+ void (PR_CALLBACK *Destroy)(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns a pointer to a UTF8-encoded string
+ * containing a description of this slot. Only the characters
+ * completely encoded in the first sixty-four bytes are
+ * significant. This routine is optional. The string
+ * returned is never freed; if dynamically generated,
+ * the space for it should be allocated from the NSSArena
+ * that may be obtained from the NSSCKFWInstance. This
+ * routine may return NULL upon error; however if *pError
+ * is CKR_OK, the NULL will be considered the valid response.
+ */
+ NSSUTF8 *(PR_CALLBACK *GetSlotDescription)(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine returns a pointer to a UTF8-encoded string
+ * containing a description of the manufacturer of this slot.
+ * Only the characters completely encoded in the first thirty-
+ * two bytes are significant. This routine is optional.
+ * The string returned is never freed; if dynamically generated,
+ * the space for it should be allocated from the NSSArena
+ * that may be obtained from the NSSCKFWInstance. This
+ * routine may return NULL upon error; however if *pError
+ * is CKR_OK, the NULL will be considered the valid response.
+ */
+ NSSUTF8 *(PR_CALLBACK *GetManufacturerID)(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine returns CK_TRUE if a token is present in this
+ * slot. This routine is optional; if unimplemented, CK_TRUE
+ * is assumed.
+ */
+ CK_BBOOL (PR_CALLBACK *GetTokenPresent)(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns CK_TRUE if the slot supports removable
+ * tokens. This routine is optional; if unimplemented, CK_FALSE
+ * is assumed.
+ */
+ CK_BBOOL (PR_CALLBACK *GetRemovableDevice)(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns CK_TRUE if this slot is a hardware
+ * device, or CK_FALSE if this slot is a software device. This
+ * routine is optional; if unimplemented, CK_FALSE is assumed.
+ */
+ CK_BBOOL (PR_CALLBACK *GetHardwareSlot)(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns the version of this slot's hardware.
+ * This routine is optional; if unimplemented, the Framework
+ * will assume a hardware version of 0.1.
+ */
+ CK_VERSION (PR_CALLBACK *GetHardwareVersion)(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns the version of this slot's firmware.
+ * This routine is optional; if unimplemented, the Framework
+ * will assume a hardware version of 0.1.
+ */
+ CK_VERSION (PR_CALLBACK *GetFirmwareVersion)(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine should return a pointer to an NSSCKMDToken
+ * object corresponding to the token in the specified slot.
+ * The NSSCKFWToken object passed in has an NSSArena
+ * available which is dedicated for this token. This routine
+ * must be implemented. This routine may return NULL upon
+ * error.
+ */
+ NSSCKMDToken *(PR_CALLBACK *GetToken)(
+ NSSCKMDSlot *mdSlot,
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This object may be extended in future versions of the
+ * NSS Cryptoki Framework. To allow for some flexibility
+ * in the area of binary compatibility, this field should
+ * be NULL.
+ */
+ void *null;
+};
+
+/*
+ * NSSCKMDToken
+ *
+ * This is the basic handle for a PKCS#11 Token. It is created by
+ * the NSSCKMDSlot->GetToken call, and may be obtained from the
+ * Framework's corresponding NSSCKFWToken object. It contains a
+ * pointer for use by the Module, to store any token-related
+ * data, and it contains the EPV for a set of routines which the
+ * Module may implement for use by the Framework. Some of these
+ * routines are optional.
+ */
+
+struct NSSCKMDTokenStr {
+ /*
+ * The Module may use this pointer for its own purposes.
+ */
+ void *etc;
+
+ /*
+ * This routine is used to prepare a Module token object for
+ * use. It is called after the NSSCKMDToken object is obtained
+ * from NSSCKMDSlot->GetToken. It is named "Setup" here because
+ * Cryptoki already defines "InitToken" to do the process of
+ * wiping out any existing state on a token and preparing it for
+ * a new use. This routine is optional; if unimplemented, it
+ * merely won't be called.
+ */
+ CK_RV (PR_CALLBACK *Setup)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine is called by the Framework whenever it notices
+ * that the token object is invalid. (Typically this is when a
+ * routine indicates an error such as CKR_DEVICE_REMOVED). This
+ * call is the last thing called before the NSSArena in the
+ * corresponding NSSCKFWToken is destroyed. This routine is
+ * optional; if unimplemented, it merely won't be called.
+ */
+ void (PR_CALLBACK *Invalidate)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine initialises the token in the specified slot.
+ * This routine is optional; if unimplemented, the Framework
+ * will fail this operation with an error of CKR_DEVICE_ERROR.
+ */
+
+ CK_RV (PR_CALLBACK *InitToken)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *pin,
+ NSSUTF8 *label
+ );
+
+ /*
+ * This routine returns a pointer to a UTF8-encoded string
+ * containing this token's label. Only the characters
+ * completely encoded in the first thirty-two bytes are
+ * significant. This routine is optional. The string
+ * returned is never freed; if dynamically generated,
+ * the space for it should be allocated from the NSSArena
+ * that may be obtained from the NSSCKFWInstance. This
+ * routine may return NULL upon error; however if *pError
+ * is CKR_OK, the NULL will be considered the valid response.
+ */
+ NSSUTF8 *(PR_CALLBACK *GetLabel)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine returns a pointer to a UTF8-encoded string
+ * containing this token's manufacturer ID. Only the characters
+ * completely encoded in the first thirty-two bytes are
+ * significant. This routine is optional. The string
+ * returned is never freed; if dynamically generated,
+ * the space for it should be allocated from the NSSArena
+ * that may be obtained from the NSSCKFWInstance. This
+ * routine may return NULL upon error; however if *pError
+ * is CKR_OK, the NULL will be considered the valid response.
+ */
+ NSSUTF8 *(PR_CALLBACK *GetManufacturerID)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine returns a pointer to a UTF8-encoded string
+ * containing this token's model name. Only the characters
+ * completely encoded in the first thirty-two bytes are
+ * significant. This routine is optional. The string
+ * returned is never freed; if dynamically generated,
+ * the space for it should be allocated from the NSSArena
+ * that may be obtained from the NSSCKFWInstance. This
+ * routine may return NULL upon error; however if *pError
+ * is CKR_OK, the NULL will be considered the valid response.
+ */
+ NSSUTF8 *(PR_CALLBACK *GetModel)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine returns a pointer to a UTF8-encoded string
+ * containing this token's serial number. Only the characters
+ * completely encoded in the first thirty-two bytes are
+ * significant. This routine is optional. The string
+ * returned is never freed; if dynamically generated,
+ * the space for it should be allocated from the NSSArena
+ * that may be obtained from the NSSCKFWInstance. This
+ * routine may return NULL upon error; however if *pError
+ * is CKR_OK, the NULL will be considered the valid response.
+ */
+ NSSUTF8 *(PR_CALLBACK *GetSerialNumber)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine returns CK_TRUE if the token has its own
+ * random number generator. This routine is optional; if
+ * unimplemented, CK_FALSE is assumed.
+ */
+ CK_BBOOL (PR_CALLBACK *GetHasRNG)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns CK_TRUE if this token is write-protected.
+ * This routine is optional; if unimplemented, CK_FALSE is
+ * assumed.
+ */
+ CK_BBOOL (PR_CALLBACK *GetIsWriteProtected)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns CK_TRUE if this token requires a login.
+ * This routine is optional; if unimplemented, CK_FALSE is
+ * assumed.
+ */
+ CK_BBOOL (PR_CALLBACK *GetLoginRequired)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns CK_TRUE if the normal user's PIN on this
+ * token has been initialised. This routine is optional; if
+ * unimplemented, CK_FALSE is assumed.
+ */
+ CK_BBOOL (PR_CALLBACK *GetUserPinInitialized)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns CK_TRUE if a successful save of a
+ * session's cryptographic operations state ~always~ contains
+ * all keys needed to restore the state of the session. This
+ * routine is optional; if unimplemented, CK_FALSE is assumed.
+ */
+ CK_BBOOL (PR_CALLBACK *GetRestoreKeyNotNeeded)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns CK_TRUE if the token has its own
+ * hardware clock. This routine is optional; if unimplemented,
+ * CK_FALSE is assumed.
+ */
+ CK_BBOOL (PR_CALLBACK *GetHasClockOnToken)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns CK_TRUE if the token has a protected
+ * authentication path. This routine is optional; if
+ * unimplemented, CK_FALSE is assumed.
+ */
+ CK_BBOOL (PR_CALLBACK *GetHasProtectedAuthenticationPath)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns CK_TRUE if the token supports dual
+ * cryptographic operations within a single session. This
+ * routine is optional; if unimplemented, CK_FALSE is assumed.
+ */
+ CK_BBOOL (PR_CALLBACK *GetSupportsDualCryptoOperations)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * XXX fgmr-- should we have a call to return all the flags
+ * at once, for folks who already know about Cryptoki?
+ */
+
+ /*
+ * This routine returns the maximum number of sessions that
+ * may be opened on this token. This routine is optional;
+ * if unimplemented, the special value CK_UNAVAILABLE_INFORMATION
+ * is assumed. XXX fgmr-- or CK_EFFECTIVELY_INFINITE?
+ */
+ CK_ULONG (PR_CALLBACK *GetMaxSessionCount)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns the maximum number of read/write
+ * sesisons that may be opened on this token. This routine
+ * is optional; if unimplemented, the special value
+ * CK_UNAVAILABLE_INFORMATION is assumed. XXX fgmr-- or
+ * CK_EFFECTIVELY_INFINITE?
+ */
+ CK_ULONG (PR_CALLBACK *GetMaxRwSessionCount)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns the maximum PIN code length that is
+ * supported on this token. This routine is optional;
+ * if unimplemented, the special value CK_UNAVAILABLE_INFORMATION
+ * is assumed.
+ */
+ CK_ULONG (PR_CALLBACK *GetMaxPinLen)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns the minimum PIN code length that is
+ * supported on this token. This routine is optional; if
+ * unimplemented, the special value CK_UNAVAILABLE_INFORMATION
+ * is assumed. XXX fgmr-- or 0?
+ */
+ CK_ULONG (PR_CALLBACK *GetMinPinLen)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns the total amount of memory on the token
+ * in which public objects may be stored. This routine is
+ * optional; if unimplemented, the special value
+ * CK_UNAVAILABLE_INFORMATION is assumed.
+ */
+ CK_ULONG (PR_CALLBACK *GetTotalPublicMemory)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns the amount of unused memory on the
+ * token in which public objects may be stored. This routine
+ * is optional; if unimplemented, the special value
+ * CK_UNAVAILABLE_INFORMATION is assumed.
+ */
+ CK_ULONG (PR_CALLBACK *GetFreePublicMemory)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns the total amount of memory on the token
+ * in which private objects may be stored. This routine is
+ * optional; if unimplemented, the special value
+ * CK_UNAVAILABLE_INFORMATION is assumed.
+ */
+ CK_ULONG (PR_CALLBACK *GetTotalPrivateMemory)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns the amount of unused memory on the
+ * token in which private objects may be stored. This routine
+ * is optional; if unimplemented, the special value
+ * CK_UNAVAILABLE_INFORMATION is assumed.
+ */
+ CK_ULONG (PR_CALLBACK *GetFreePrivateMemory)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns the version number of this token's
+ * hardware. This routine is optional; if unimplemented,
+ * the value 0.1 is assumed.
+ */
+ CK_VERSION (PR_CALLBACK *GetHardwareVersion)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns the version number of this token's
+ * firmware. This routine is optional; if unimplemented,
+ * the value 0.1 is assumed.
+ */
+ CK_VERSION (PR_CALLBACK *GetFirmwareVersion)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine stuffs the current UTC time, as obtained from
+ * the token, into the sixteen-byte buffer in the form
+ * YYYYMMDDhhmmss00. This routine need only be implemented
+ * by token which indicate that they have a real-time clock.
+ * XXX fgmr-- think about time formats.
+ */
+ CK_RV (PR_CALLBACK *GetUTCTime)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_CHAR utcTime[16]
+ );
+
+ /*
+ * This routine creates a session on the token, and returns
+ * the corresponding NSSCKMDSession object. The value of
+ * rw will be CK_TRUE if the session is to be a read/write
+ * session, or CK_FALSE otherwise. An NSSArena dedicated to
+ * the new session is available from the specified NSSCKFWSession.
+ * This routine may return NULL upon error.
+ */
+ NSSCKMDSession *(PR_CALLBACK *OpenSession)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWSession *fwSession,
+ CK_BBOOL rw,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine returns the number of PKCS#11 Mechanisms
+ * supported by this token. This routine is optional; if
+ * unimplemented, zero is assumed.
+ */
+ CK_ULONG (PR_CALLBACK *GetMechanismCount)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine stuffs into the specified array the types
+ * of the mechanisms supported by this token. The Framework
+ * determines the size of the array by calling GetMechanismCount.
+ */
+ CK_RV (PR_CALLBACK *GetMechanismTypes)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_MECHANISM_TYPE types[]
+ );
+
+ /*
+ * This routine returns a pointer to a Module mechanism
+ * object corresponding to a specified type. This routine
+ * need only exist for tokens implementing at least one
+ * mechanism.
+ */
+ NSSCKMDMechanism *(PR_CALLBACK *GetMechanism)(
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWMechanism *fwMechanism,
+ CK_MECHANISM_TYPE which
+ );
+
+ /*
+ * This object may be extended in future versions of the
+ * NSS Cryptoki Framework. To allow for some flexibility
+ * in the area of binary compatibility, this field should
+ * be NULL.
+ */
+ void *null;
+};
+
+/*
+ * NSSCKMDSession
+ *
+ * This is the basic handle for a session on a PKCS#11 Token. It
+ * is created by NSSCKMDToken->OpenSession, and may be obtained
+ * from the Framework's corresponding NSSCKFWSession object. It
+ * contains a pointer for use by the Module, to store any session-
+ * realted data, and it contains the EPV for a set of routines
+ * which the Module may implement for use by the Framework. Some
+ * of these routines are optional.
+ */
+
+struct NSSCKMDSessionStr {
+ /*
+ * The Module may use this pointer for its own purposes.
+ */
+ void *etc;
+
+ /*
+ * This routine is called by the Framework when a session is
+ * closed. This call is the last thing called before the
+ * NSSArena in the correspoinding NSSCKFWSession is destroyed.
+ * This routine is optional; if unimplemented, it merely won't
+ * be called.
+ */
+ void (PR_CALLBACK *Close)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine is used to get any device-specific error.
+ * This routine is optional.
+ */
+ CK_ULONG (PR_CALLBACK *GetDeviceError)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine is used to log in a user to the token. This
+ * routine is optional, since the Framework's NSSCKFWSession
+ * object keeps track of the login state.
+ */
+ CK_RV (PR_CALLBACK *Login)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_USER_TYPE userType,
+ NSSItem *pin,
+ CK_STATE oldState,
+ CK_STATE newState
+ );
+
+ /*
+ * This routine is used to log out a user from the token. This
+ * routine is optional, since the Framework's NSSCKFWSession
+ * object keeps track of the login state.
+ */
+ CK_RV (PR_CALLBACK *Logout)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_STATE oldState,
+ CK_STATE newState
+ );
+
+ /*
+ * This routine is used to initialize the normal user's PIN or
+ * password. This will only be called in the "read/write
+ * security officer functions" state. If this token has a
+ * protected authentication path, then the pin argument will
+ * be NULL. This routine is optional; if unimplemented, the
+ * Framework will return the error CKR_TOKEN_WRITE_PROTECTED.
+ */
+ CK_RV (PR_CALLBACK *InitPIN)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *pin
+ );
+
+ /*
+ * This routine is used to modify a user's PIN or password. This
+ * routine will only be called in the "read/write security officer
+ * functions" or "read/write user functions" state. If this token
+ * has a protected authentication path, then the pin arguments
+ * will be NULL. This routine is optional; if unimplemented, the
+ * Framework will return the error CKR_TOKEN_WRITE_PROTECTED.
+ */
+ CK_RV (PR_CALLBACK *SetPIN)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *oldPin,
+ NSSItem *newPin
+ );
+
+ /*
+ * This routine is used to find out how much space would be required
+ * to save the current operational state. This routine is optional;
+ * if unimplemented, the Framework will reject any attempts to save
+ * the operational state with the error CKR_STATE_UNSAVEABLE. This
+ * routine may return zero on error.
+ */
+ CK_ULONG (PR_CALLBACK *GetOperationStateLen)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine is used to store the current operational state. This
+ * routine is only required if GetOperationStateLen is implemented
+ * and can return a nonzero value. The buffer in the specified item
+ * will be pre-allocated, and the length will specify the amount of
+ * space available (which may be more than GetOperationStateLen
+ * asked for, but which will not be smaller).
+ */
+ CK_RV (PR_CALLBACK *GetOperationState)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *buffer
+ );
+
+ /*
+ * This routine is used to restore an operational state previously
+ * obtained with GetOperationState. The Framework will take pains
+ * to be sure that the state is (or was at one point) valid; if the
+ * Module notices that the state is invalid, it should return an
+ * error, but it is not required to be paranoid about the issue.
+ * [XXX fgmr-- should (can?) the framework verify the keys match up?]
+ * This routine is required only if GetOperationState is implemented.
+ */
+ CK_RV (PR_CALLBACK *SetOperationState)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *state,
+ NSSCKMDObject *mdEncryptionKey,
+ NSSCKFWObject *fwEncryptionKey,
+ NSSCKMDObject *mdAuthenticationKey,
+ NSSCKFWObject *fwAuthenticationKey
+ );
+
+ /*
+ * This routine is used to create an object. The specified template
+ * will only specify a session object if the Module has indicated
+ * that it wishes to handle its own session objects. This routine
+ * is optional; if unimplemented, the Framework will reject the
+ * operation with the error CKR_TOKEN_WRITE_PROTECTED. Space for
+ * token objects should come from the NSSArena available from the
+ * NSSCKFWToken object; space for session objects (if supported)
+ * should come from the NSSArena available from the NSSCKFWSession
+ * object. The appropriate NSSArena pointer will, as a convenience,
+ * be passed as the handyArenaPointer argument. This routine may
+ * return NULL upon error.
+ */
+ NSSCKMDObject *(PR_CALLBACK *CreateObject)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSArena *handyArenaPointer,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine is used to make a copy of an object. It is entirely
+ * optional; if unimplemented, the Framework will try to use
+ * CreateObject instead. If the Module has indicated that it does
+ * not wish to handle session objects, then this routine will only
+ * be called to copy a token object to another token object.
+ * Otherwise, either the original object or the new may be of
+ * either the token or session variety. As with CreateObject, the
+ * handyArenaPointer will point to the appropriate arena for the
+ * new object. This routine may return NULL upon error.
+ */
+ NSSCKMDObject *(PR_CALLBACK *CopyObject)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdOldObject,
+ NSSCKFWObject *fwOldObject,
+ NSSArena *handyArenaPointer,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine is used to begin an object search. This routine may
+ * be unimplemented only if the Module does not handle session
+ * objects, and if none of its tokens have token objects. The
+ * NSSCKFWFindObjects pointer has an NSSArena that may be used for
+ * storage for the life of this "find" operation. This routine may
+ * return NULL upon error. If the Module can determine immediately
+ * that the search will not find any matching objects, it may return
+ * NULL, and specify CKR_OK as the error.
+ */
+ NSSCKMDFindObjects *(PR_CALLBACK *FindObjectsInit)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine seeds the random-number generator. It is
+ * optional, even if GetRandom is implemented. If unimplemented,
+ * the Framework will issue the error CKR_RANDOM_SEED_NOT_SUPPORTED.
+ */
+ CK_RV (PR_CALLBACK *SeedRandom)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *seed
+ );
+
+ /*
+ * This routine gets random data. It is optional. If unimplemented,
+ * the Framework will issue the error CKR_RANDOM_NO_RNG.
+ */
+ CK_RV (PR_CALLBACK *GetRandom)(
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *buffer
+ );
+
+ /*
+ * This object may be extended in future versions of the
+ * NSS Cryptoki Framework. To allow for some flexibility
+ * in the area of binary compatibility, this field should
+ * be NULL.
+ */
+ void *null;
+};
+
+/*
+ * NSSCKMDFindObjects
+ *
+ * This is the basic handle for an object search. It is
+ * created by NSSCKMDSession->FindObjectsInit, and may be
+ * obtained from the Framework's corresponding object.
+ * It contains a pointer for use by the Module, to store
+ * any search-related data, and it contains the EPV for a
+ * set of routines which the Module may implement for use
+ * by the Framework. Some of these routines are optional.
+ */
+
+struct NSSCKMDFindObjectsStr {
+ /*
+ * The Module may use this pointer for its own purposes.
+ */
+ void *etc;
+
+ /*
+ * This routine is called by the Framework to finish a
+ * search operation. Note that the Framework may finish
+ * a search before it has completed. This routine is
+ * optional; if unimplemented, it merely won't be called.
+ */
+ void (PR_CALLBACK *Final)(
+ NSSCKMDFindObjects *mdFindObjects,
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine is used to obtain another pointer to an
+ * object matching the search criteria. This routine is
+ * required. If no (more) objects match the search, it
+ * should return NULL and set the error to CKR_OK.
+ */
+ NSSCKMDObject *(PR_CALLBACK *Next)(
+ NSSCKMDFindObjects *mdFindObjects,
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError
+ );
+
+ /*
+ * This object may be extended in future versions of the
+ * NSS Cryptoki Framework. To allow for some flexibility
+ * in the area of binary compatibility, this field should
+ * be NULL.
+ */
+ void *null;
+};
+
+/*
+ * NSSCKMDMechanism
+ *
+ */
+
+struct NSSCKMDMechanismStr {
+ /*
+ * The Module may use this pointer for its own purposes.
+ */
+ void *etc;
+
+ /*
+ * This routine returns the minimum key size allowed for
+ * this mechanism. This routine is optional; if unimplemented,
+ * zero will be assumed. This routine may return zero on
+ * error; if the error is CKR_OK, zero will be accepted as
+ * a valid response.
+ */
+ CK_ULONG (PR_CALLBACK *GetMinKeySize)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine returns the maximum key size allowed for
+ * this mechanism. This routine is optional; if unimplemented,
+ * zero will be assumed. This routine may return zero on
+ * error; if the error is CKR_OK, zero will be accepted as
+ * a valid response.
+ */
+ CK_ULONG (PR_CALLBACK *GetMaxKeySize)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine is called to determine if the mechanism is
+ * implemented in hardware or software. It returns CK_TRUE
+ * if it is done in hardware.
+ */
+ CK_BBOOL (PR_CALLBACK *GetInHardware)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * The crypto routines themselves. Most crypto operations may
+ * be performed in two ways, streaming and single-part. The
+ * streaming operations involve the use of (typically) three
+ * calls-- an Init method to set up the operation, an Update
+ * method to feed data to the operation, and a Final method to
+ * obtain the final result. Single-part operations involve
+ * one method, to perform the crypto operation all at once.
+ * The NSS Cryptoki Framework can implement the single-part
+ * operations in terms of the streaming operations on behalf
+ * of the Module. There are a few variances.
+ *
+ * For simplicity, the routines are listed in summary here:
+ *
+ * EncryptInit, EncryptUpdate, EncryptFinal; Encrypt
+ * DecryptInit, DecryptUpdate, DecryptFinal; Decrypt
+ * DigestInit, DigestUpdate, DigestKey, DigestFinal; Digest
+ * SignInit, SignUpdate, SignFinal; Sign
+ * SignRecoverInit; SignRecover
+ * VerifyInit, VerifyUpdate, VerifyFinal; Verify
+ * VerifyRecoverInit; VerifyRecover
+ *
+ * Also, there are some combined-operation calls:
+ *
+ * DigestEncryptUpdate
+ * DecryptDigestUpdate
+ * SignEncryptUpdate
+ * DecryptVerifyUpdate
+ *
+ * The key-management routines are
+ *
+ * GenerateKey
+ * GenerateKeyPair
+ * WrapKey
+ * UnwrapKey
+ * DeriveKey
+ *
+ * All of these routines based directly on the Cryptoki API;
+ * see PKCS#11 for further information.
+ */
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *EncryptInit)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdKey,
+ NSSCKFWObject *fwKey
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *EncryptUpdate)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *EncryptFinal)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *Encrypt)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdKey,
+ NSSCKFWObject *fwKey,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *DecryptInit)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdKey,
+ NSSCKFWObject *fwKey
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *DecryptUpdate)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *DecryptFinal)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *Decrypt)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdKey,
+ NSSCKFWObject *fwKey,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *DigestInit)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *DigestUpdate)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *data
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *DigestKey)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdKey,
+ NSSCKFWObject *fwKey
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *DigestFinal)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *Digest)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *SignInit)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdKey,
+ NSSCKFWObject *fwKey
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *SignUpdate)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *SignFinal)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *Sign)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdKey,
+ NSSCKFWObject *fwKey,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *VerifyInit)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWObject *key
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *VerifyUpdate)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *data
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *VerifyFinish)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *Verify)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKFWObject *key,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *SignRecover)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdKey,
+ NSSCKFWObject *fwKey,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *VerifyRecover)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdKey,
+ NSSCKFWObject *fwKey,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *DigestEncryptUpdate)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *DecryptDigestUpdate)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *SignEncryptUpdate)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ */
+ CK_RV (PR_CALLBACK *DecryptVerifyUpdate)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSItem *data,
+ NSSItem *buffer
+ );
+
+ /*
+ * Key management operations.
+ */
+
+ /*
+ * This routine generates a key. This routine may return NULL
+ * upon error.
+ */
+ NSSCKMDObject *(PR_CALLBACK *GenerateKey)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine generates a key pair.
+ */
+ CK_RV (PR_CALLBACK *GenerateKeyPair)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate,
+ CK_ULONG ulPublicKeyAttributeCount,
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
+ CK_ULONG ulPrivateKeyAttributeCount,
+ NSSCKMDObject **pPublicKey,
+ NSSCKMDObject **pPrivateKey
+ );
+
+ /*
+ * This routine wraps a key.
+ */
+ CK_RV (PR_CALLBACK *WrapKey)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdWrappingKey,
+ NSSCKFWObject *fwWrappingKey,
+ NSSCKMDObject *mdWrappedKey,
+ NSSCKFWObject *fwWrappedKey,
+ NSSItem *buffer
+ );
+
+ /*
+ * This routine unwraps a key. This routine may return NULL
+ * upon error.
+ */
+ NSSCKMDObject *(PR_CALLBACK *UnwrapKey)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdWrappingKey,
+ NSSCKFWObject *fwWrappingKey,
+ NSSItem *wrappedKey,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine derives a key. This routine may return NULL
+ * upon error.
+ */
+ NSSCKMDObject *(PR_CALLBACK *DeriveKey)(
+ NSSCKMDMechanism *mdMechanism,
+ NSSCKFWMechanism *fwMechanism,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDObject *mdBaseKey,
+ NSSCKFWObject *fwBaseKey,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+ );
+
+ /*
+ * This object may be extended in future versions of the
+ * NSS Cryptoki Framework. To allow for some flexibility
+ * in the area of binary compatibility, this field should
+ * be NULL.
+ */
+ void *null;
+};
+
+/*
+ * NSSCKMDObject
+ *
+ * This is the basic handle for any object used by a PKCS#11 Module.
+ * Modules must implement it if they support their own objects, and
+ * the Framework supports it for Modules that do not handle session
+ * objects. This type contains a pointer for use by the implementor,
+ * to store any object-specific data, and it contains an EPV for a
+ * set of routines used to access the object.
+ */
+
+struct NSSCKMDObjectStr {
+ /*
+ * The implementation my use this pointer for its own purposes.
+ */
+ void *etc;
+
+ /*
+ * This routine is called by the Framework when it is letting
+ * go of an object handle. It can be used by the Module to
+ * free any resources tied up by an object "in use." It is
+ * optional.
+ */
+ void (PR_CALLBACK *Finalize)(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine is used to completely destroy an object.
+ * It is optional. The parameter fwObject might be NULL
+ * if the framework runs out of memory at the wrong moment.
+ */
+ CK_RV (PR_CALLBACK *Destroy)(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This helper routine is used by the Framework, and is especially
+ * useful when it is managing session objects on behalf of the
+ * Module. This routine is optional; if unimplemented, the
+ * Framework will actually look up the CKA_TOKEN attribute. In the
+ * event of an error, just make something up-- the Framework will
+ * find out soon enough anyway.
+ */
+ CK_BBOOL (PR_CALLBACK *IsTokenObject)(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+ );
+
+ /*
+ * This routine returns the number of attributes of which this
+ * object consists. It is mandatory. It can return zero on
+ * error.
+ */
+ CK_ULONG (PR_CALLBACK *GetAttributeCount)(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine stuffs the attribute types into the provided array.
+ * The array size (as obtained from GetAttributeCount) is passed in
+ * as a check; return CKR_BUFFER_TOO_SMALL if the count is wrong
+ * (either too big or too small).
+ */
+ CK_RV (PR_CALLBACK *GetAttributeTypes)(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE_PTR typeArray,
+ CK_ULONG ulCount
+ );
+
+ /*
+ * This routine returns the size (in bytes) of the specified
+ * attribute. It can return zero on error.
+ */
+ CK_ULONG (PR_CALLBACK *GetAttributeSize)(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine returns the specified attribute. It can return
+ * NULL upon error. The pointer in the item will not be freed;
+ * any host memory required should come from the object's arena
+ * (which is likely the Framework's token or session arena).
+ * It may return NULL on error.
+ */
+ NSSItem *(PR_CALLBACK *GetAttribute)(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+ );
+
+ /*
+ * This routine changes the specified attribute. If unimplemented,
+ * the object will be considered read-only.
+ */
+ CK_RV (PR_CALLBACK *SetAttribute)(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *value
+ );
+
+ /*
+ * This routine returns the storage requirements of this object,
+ * in bytes. Cryptoki doesn't strictly define the definition,
+ * but it should relate to the values returned by the "Get Memory"
+ * routines of the NSSCKMDToken. This routine is optional; if
+ * unimplemented, the Framework will consider this information
+ * sensitive. This routine may return zero on error. If the
+ * specified error is CKR_OK, zero will be accepted as a valid
+ * response.
+ */
+ CK_ULONG (PR_CALLBACK *GetObjectSize)(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+ );
+
+ /*
+ * This object may be extended in future versions of the
+ * NSS Cryptoki Framework. To allow for some flexibility
+ * in the area of binary compatibility, this field should
+ * be NULL.
+ */
+ void *null;
+};
+
+
+#endif /* NSSCKMDT_H */
diff --git a/security/nss/lib/ckfw/nssckp.h b/security/nss/lib/ckfw/nssckp.h
new file mode 100644
index 000000000..502e18408
--- /dev/null
+++ b/security/nss/lib/ckfw/nssckp.h
@@ -0,0 +1,66 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+/*
+ * This file is in part derived from a file "pkcs11t.h" made available
+ * by RSA Security at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/pkcs11t.h
+ */
+
+#ifndef NSSCKP_H
+#define NSSCKP_H
+
+#ifdef DEBUG
+static const char NSSCKP_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+#endif /* NSSCKP_H */
+
+/*
+ * These platform-dependent packing rules are required by all PKCS#11
+ * modules, to be binary compatible. These rules have been placed in
+ * separate header files (nssckp.h to enable the packing, nsscku.h to
+ * disable) for consistancy. These files can be included many times,
+ * so the bodies should *NOT* be in the multiple-inclusion-preventing
+ * #ifndef/#endif area above.
+ */
+
+/*
+ * WIN32 is defined (when appropriate) in NSPR's prcpucfg.h.
+ */
+
+#ifdef WIN32
+#pragma warning(disable:4103)
+#pragma pack(push, cryptoki, 1)
+#endif /* WIN32 */
+
+/* End of nssckp.h */
diff --git a/security/nss/lib/ckfw/nssckt.h b/security/nss/lib/ckfw/nssckt.h
new file mode 100644
index 000000000..c7d98297a
--- /dev/null
+++ b/security/nss/lib/ckfw/nssckt.h
@@ -0,0 +1,1117 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+/*
+ * This file is in part derived from a file "pkcs11t.h" made available
+ * by RSA Security at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/pkcs11t.h
+ *
+ * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
+ * is granted provided that it is identified as "RSA Security Inc Public-Key
+ * Cryptography Standards (PKCS)" in all material mentioning or referencing
+ * this document.
+ *
+ */
+
+#ifndef NSSCKT_H
+#define NSSCKT_H
+
+#ifdef DEBUG
+static const char NSSCKT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+#include "nspr.h"
+
+/*
+ * nssckt.h
+ *
+ * This file contains the type definitions for Cryptoki (PKCS#11).
+ * These definitions are taken from the RSA Standard.
+ *
+ * NOTE: Unlike most things in NSS, there are public types and
+ * preprocessor definitions which do *NOT* begin with NSS-- rather,
+ * they begin with CK, as per the standard.
+ */
+
+#ifndef CK_FALSE
+#define CK_FALSE 0
+#endif
+
+#ifndef CK_TRUE
+#define CK_TRUE (!CK_FALSE)
+#endif
+
+#define CK_PTR *
+#define CK_NULL_PTR 0
+#define CK_CALLBACK_FUNCTION(rv,func) rv (PR_CALLBACK * func)
+#define CK_DECLARE_FUNCTION(rv,func) NSS_EXTERN rv func
+#define CK_DECLARE_FUNCTION_POINTER(rv,func) rv (PR_CALLBACK * func)
+
+/* an unsigned 8-bit value */
+typedef unsigned char CK_BYTE;
+
+/* an unsigned 8-bit character */
+typedef CK_BYTE CK_CHAR;
+
+/* 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_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
+
+#define CK_ENTRY
+
+/* pack */
+#include "nssckp.h"
+
+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 {
+ CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
+ CK_CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags; /* must be zero */
+
+ /* libraryDescription and libraryVersion are new for v2.0 */
+ CK_CHAR 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
+
+
+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 {
+ CK_CHAR slotDescription[64]; /* blank padded */
+ CK_CHAR 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 {
+ CK_CHAR label[32]; /* blank padded */
+ CK_CHAR manufacturerID[32]; /* blank padded */
+ CK_CHAR 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
+
+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
+
+
+/* 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: */
+#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_VENDOR_DEFINED 0x80000000
+
+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
+
+
+/* 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 */
+
+/* Cryptoki V2.01 probably won't actually have ECDSA in it */
+#define CKK_ECDSA 0x00000003
+
+#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
+#define CKK_CAST5 0x00000018
+#define CKK_CAST128 0x00000018 /* CAST128=CAST5 */
+#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_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: */
+#define CKC_X_509 0x00000000
+#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;
+
+typedef CK_ATTRIBUTE_TYPE CK_PTR CK_ATTRIBUTE_TYPE_PTR;
+
+/* 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
+#define CKA_CERTIFICATE_TYPE 0x00000080
+#define CKA_ISSUER 0x00000081
+#define CKA_SERIAL_NUMBER 0x00000082
+#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
+#define CKA_VALUE_BITS 0x00000160
+#define CKA_VALUE_LEN 0x00000161
+
+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
+ * CKA_ALWAYS_SENSITIVE, and CKA_MODIFIABLE are new for v2.0 */
+#define CKA_EXTRACTABLE 0x00000162
+#define CKA_LOCAL 0x00000163
+#define CKA_NEVER_EXTRACTABLE 0x00000164
+#define CKA_ALWAYS_SENSITIVE 0x00000165
+#define CKA_MODIFIABLE 0x00000170
+
+#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
+
+#define CKM_DSA_KEY_PAIR_GEN 0x00000010
+#define CKM_DSA 0x00000011
+#define CKM_DSA_SHA1 0x00000012
+#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
+#define CKM_DH_PKCS_DERIVE 0x00000021
+#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 */
+#define CKM_DES3_MAC_GENERAL 0x00000135
+#define CKM_DES3_CBC_PAD 0x00000136
+#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
+
+#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
+
+/* 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
+#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
+#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
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
+#define CKM_KEY_WRAP_LYNKS 0x00000400
+#define CKM_KEY_WRAP_SET_OAEP 0x00000401
+
+/* 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
+
+/* Cryptoki V2.01 probably won't actually have ECDSA in it */
+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
+#define CKM_ECDSA 0x00001041
+#define CKM_ECDSA_SHA1 0x00001042
+
+#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
+
+#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
+
+#define CKF_EXTENSION 0x80000000 /* FALSE for 2.01 */
+
+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
+#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
+#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
+#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
+
+#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;
+#ifdef FGMR
+ CK_BYTE_PTR pConfig;
+ CK_ULONG ulConfigLen;
+#endif /* FGMR */
+ 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_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_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_CHAR_PTR pInitVector;
+ CK_CHAR_PTR pPassword;
+ CK_ULONG ulPasswordLen;
+ CK_CHAR_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;
+
+
+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;
+
+/* undo packing */
+#include "nsscku.h"
+
+#endif /* NSSCKT_H */
diff --git a/security/nss/lib/ckfw/nsscku.h b/security/nss/lib/ckfw/nsscku.h
new file mode 100644
index 000000000..dcc18162b
--- /dev/null
+++ b/security/nss/lib/ckfw/nsscku.h
@@ -0,0 +1,72 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+/*
+ * This file is in part derived from a file "pkcs11t.h" made available
+ * by RSA Security at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-11/pkcs11t.h
+ *
+ * Copyright (C) 1994-1999 RSA Security Inc. Licence to copy this document
+ * is granted provided that it is identified as "RSA Security Inc. Public-Key
+ * Cryptography Standards (PKCS)" in all material mentioning or referencing
+ * this document.
+ */
+ */
+
+#ifndef NSSCKU_H
+#define NSSCKU_H
+
+#ifdef DEBUG
+static const char NSSCKU_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+#endif /* NSSCKU_H */
+
+/*
+ * These platform-dependent packing rules are required by all PKCS#11
+ * modules, to be binary compatible. These rules have been placed in
+ * separate header files (nssckp.h to enable the packing, nsscku.h to
+ * disable) for consistancy. These files can be included many times,
+ * so the bodies should *NOT* be in the multiple-inclusion-preventing
+ * #ifndef/#endif area above.
+ */
+
+/*
+ * WIN32 is defined (when appropriate) in NSPR's prcpucfg.h.
+ */
+
+#ifdef WIN32
+#pragma warning(disable:4103)
+#pragma pack(pop, cryptoki)
+#endif /* WIN32 */
+
+/* End of nsscku.h */
diff --git a/security/nss/lib/ckfw/object.c b/security/nss/lib/ckfw/object.c
new file mode 100644
index 000000000..46b11e54a
--- /dev/null
+++ b/security/nss/lib/ckfw/object.c
@@ -0,0 +1,957 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * object.c
+ *
+ * This file implements the NSSCKFWObject type and methods.
+ */
+
+#ifndef CK_T
+#include "ck.h"
+#endif /* CK_T */
+
+/*
+ * NSSCKFWObject
+ *
+ * -- create/destroy --
+ * nssCKFWObject_Create
+ * nssCKFWObject_Finalize
+ * nssCKFWObject_Destroy
+ *
+ * -- public accessors --
+ * NSSCKFWObject_GetMDObject
+ * NSSCKFWObject_GetArena
+ * NSSCKFWObject_IsTokenObject
+ * NSSCKFWObject_GetAttributeCount
+ * NSSCKFWObject_GetAttributeTypes
+ * NSSCKFWObject_GetAttributeSize
+ * NSSCKFWObject_GetAttribute
+ * NSSCKFWObject_SetAttribute
+ * NSSCKFWObject_GetObjectSize
+ *
+ * -- implement public accessors --
+ * nssCKFWObject_GetMDObject
+ * nssCKFWObject_GetArena
+ *
+ * -- private accessors --
+ *
+ * -- module fronts --
+ * nssCKFWObject_IsTokenObject
+ * nssCKFWObject_GetAttributeCount
+ * nssCKFWObject_GetAttributeTypes
+ * nssCKFWObject_GetAttributeSize
+ * nssCKFWObject_GetAttribute
+ * nssCKFWObject_SetAttribute
+ * nssCKFWObject_GetObjectSize
+ */
+
+struct NSSCKFWObjectStr {
+ NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */
+ NSSArena *arena;
+ NSSCKMDObject *mdObject;
+ NSSCKMDSession *mdSession;
+ NSSCKFWSession *fwSession;
+ NSSCKMDToken *mdToken;
+ NSSCKFWToken *fwToken;
+ NSSCKMDInstance *mdInstance;
+ NSSCKFWInstance *fwInstance;
+};
+
+#ifdef DEBUG
+/*
+ * But first, the pointer-tracking stuff.
+ *
+ * NOTE: the pointer-tracking support in NSS/base currently relies
+ * upon NSPR's CallOnce support. That, however, relies upon NSPR's
+ * locking, which is tied into the runtime. We need a pointer-tracker
+ * implementation that uses the locks supplied through C_Initialize.
+ * That support, however, can be filled in later. So for now, I'll
+ * just do this routines as no-ops.
+ */
+
+static CK_RV
+object_add_pointer
+(
+ const NSSCKFWObject *fwObject
+)
+{
+ return CKR_OK;
+}
+
+static CK_RV
+object_remove_pointer
+(
+ const NSSCKFWObject *fwObject
+)
+{
+ return CKR_OK;
+}
+
+NSS_IMPLEMENT CK_RV
+nssCKFWObject_verifyPointer
+(
+ const NSSCKFWObject *fwObject
+)
+{
+ return CKR_OK;
+}
+
+#endif /* DEBUG */
+
+
+/*
+ * nssCKFWObject_Create
+ *
+ */
+NSS_IMPLEMENT NSSCKFWObject *
+nssCKFWObject_Create
+(
+ NSSArena *arena,
+ NSSCKMDObject *mdObject,
+ NSSCKFWSession *fwSession,
+ NSSCKFWToken *fwToken,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ NSSCKFWObject *fwObject;
+ nssCKFWHash *mdObjectHash;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWObject *)NULL;
+ }
+
+ if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSCKFWObject *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ mdObjectHash = nssCKFWToken_GetMDObjectHash(fwToken);
+ if( (nssCKFWHash *)NULL == mdObjectHash ) {
+ *pError = CKR_GENERAL_ERROR;
+ return (NSSCKFWObject *)NULL;
+ }
+
+ if( nssCKFWHash_Exists(mdObjectHash, mdObject) ) {
+ fwObject = nssCKFWHash_Lookup(mdObjectHash, mdObject);
+ return fwObject;
+ }
+
+ fwObject = nss_ZNEW(arena, NSSCKFWObject);
+ if( (NSSCKFWObject *)NULL == fwObject ) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKFWObject *)NULL;
+ }
+
+ fwObject->arena = arena;
+ fwObject->mdObject = mdObject;
+ fwObject->fwSession = fwSession;
+
+ if( (NSSCKFWSession *)NULL != fwSession ) {
+ fwObject->mdSession = nssCKFWSession_GetMDSession(fwSession);
+ }
+
+ fwObject->fwToken = fwToken;
+
+ if( (NSSCKFWToken *)NULL != fwToken ) {
+ fwObject->mdToken = nssCKFWToken_GetMDToken(fwToken);
+ }
+
+ fwObject->fwInstance = fwInstance;
+ fwObject->mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
+ fwObject->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
+ if( (NSSCKFWMutex *)NULL == fwObject->mutex ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWObject *)NULL;
+ }
+
+ *pError = nssCKFWHash_Add(mdObjectHash, mdObject, fwObject);
+ if( CKR_OK != *pError ) {
+ nss_ZFreeIf(fwObject);
+ return (NSSCKFWObject *)NULL;
+ }
+
+#ifdef DEBUG
+ *pError = object_add_pointer(fwObject);
+ if( CKR_OK != *pError ) {
+ nssCKFWHash_Remove(mdObjectHash, mdObject);
+ nss_ZFreeIf(fwObject);
+ return (NSSCKFWObject *)NULL;
+ }
+#endif /* DEBUG */
+
+ *pError = CKR_OK;
+ return fwObject;
+}
+
+/*
+ * nssCKFWObject_Finalize
+ *
+ */
+NSS_IMPLEMENT void
+nssCKFWObject_Finalize
+(
+ NSSCKFWObject *fwObject
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
+ return;
+ }
+#endif /* NSSDEBUG */
+
+ (void)nssCKFWMutex_Destroy(fwObject->mutex);
+
+ if( (void *)NULL != (void *)fwObject->mdObject->Finalize ) {
+ fwObject->mdObject->Finalize(fwObject->mdObject, fwObject,
+ fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
+ fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
+ }
+
+ nss_ZFreeIf(fwObject);
+
+#ifdef DEBUG
+ (void)object_remove_pointer(fwObject);
+#endif /* DEBUG */
+
+ return;
+}
+
+/*
+ * nssCKFWObject_Destroy
+ *
+ */
+NSS_IMPLEMENT void
+nssCKFWObject_Destroy
+(
+ NSSCKFWObject *fwObject
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
+ return;
+ }
+#endif /* NSSDEBUG */
+
+ (void)nssCKFWMutex_Destroy(fwObject->mutex);
+
+ if( (void *)NULL != (void *)fwObject->mdObject->Destroy ) {
+ fwObject->mdObject->Finalize(fwObject->mdObject, fwObject,
+ fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
+ fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
+ }
+
+ nss_ZFreeIf(fwObject);
+
+#ifdef DEBUG
+ (void)object_remove_pointer(fwObject);
+#endif /* DEBUG */
+
+ return;
+}
+
+/*
+ * nssCKFWObject_GetMDObject
+ *
+ */
+NSS_IMPLEMENT NSSCKMDObject *
+nssCKFWObject_GetMDObject
+(
+ NSSCKFWObject *fwObject
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
+ return (NSSCKMDObject *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwObject->mdObject;
+}
+
+/*
+ * nssCKFWObject_GetArena
+ *
+ */
+NSS_IMPLEMENT NSSArena *
+nssCKFWObject_GetArena
+(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+)
+{
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != *pError ) {
+ return (NSSArena *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwObject->arena;
+}
+
+/*
+ * nssCKFWObject_IsTokenObject
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWObject_IsTokenObject
+(
+ NSSCKFWObject *fwObject
+)
+{
+ CK_BBOOL b = CK_FALSE;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwObject->mutex) ) {
+ return CK_FALSE;
+ }
+
+ if( (void *)NULL == (void *)fwObject->mdObject->IsTokenObject ) {
+ NSSItem item;
+ NSSItem *pItem;
+ CK_RV rv = CKR_OK;
+
+ item.data = (void *)&b;
+ item.size = sizeof(b);
+
+ pItem = nssCKFWObject_GetAttribute(fwObject, CKA_TOKEN, &item,
+ (NSSArena *)NULL, &rv);
+ if( (NSSItem *)NULL == pItem ) {
+ /* Error of some type */
+ b = CK_FALSE;
+ goto done;
+ }
+
+ goto done;
+ }
+
+ b = fwObject->mdObject->IsTokenObject(fwObject->mdObject, fwObject,
+ fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
+ fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+ return b;
+}
+
+/*
+ * nssCKFWObject_GetAttributeCount
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWObject_GetAttributeCount
+(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+)
+{
+ CK_ULONG rv;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (CK_ULONG)0;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != *pError ) {
+ return (CK_ULONG)0;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwObject->mdObject->GetAttributeCount ) {
+ *pError = CKR_GENERAL_ERROR;
+ return (CK_ULONG)0;
+ }
+
+ *pError = nssCKFWMutex_Lock(fwObject->mutex);
+ if( CKR_OK != *pError ) {
+ return (CK_ULONG)0;
+ }
+
+ rv = fwObject->mdObject->GetAttributeCount(fwObject->mdObject, fwObject,
+ fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
+ fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
+ pError);
+
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWObject_GetAttributeTypes
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWObject_GetAttributeTypes
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE_PTR typeArray,
+ CK_ULONG ulCount
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwObject->mdObject->GetAttributeTypes ) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ error = nssCKFWMutex_Lock(fwObject->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ error = fwObject->mdObject->GetAttributeTypes(fwObject->mdObject, fwObject,
+ fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
+ fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
+ typeArray, ulCount);
+
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+ return error;
+}
+
+/*
+ * nssCKFWObject_GetAttributeSize
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWObject_GetAttributeSize
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+)
+{
+ CK_ULONG rv;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (CK_ULONG)0;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != *pError ) {
+ return (CK_ULONG)0;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwObject->mdObject->GetAttributeSize ) {
+ *pError = CKR_GENERAL_ERROR;
+ return (CK_ULONG )0;
+ }
+
+ *pError = nssCKFWMutex_Lock(fwObject->mutex);
+ if( CKR_OK != *pError ) {
+ return (CK_ULONG)0;
+ }
+
+ rv = fwObject->mdObject->GetAttributeSize(fwObject->mdObject, fwObject,
+ fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
+ fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
+ attribute, pError);
+
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWObject_GetAttribute
+ *
+ * Usual NSS allocation rules:
+ * If itemOpt is not NULL, it will be returned; otherwise an NSSItem
+ * will be allocated. If itemOpt is not NULL but itemOpt->data is,
+ * the buffer will be allocated; otherwise, the buffer will be used.
+ * Any allocations will come from the optional arena, if one is
+ * specified.
+ */
+NSS_IMPLEMENT NSSItem *
+nssCKFWObject_GetAttribute
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *itemOpt,
+ NSSArena *arenaOpt,
+ CK_RV *pError
+)
+{
+ NSSItem *rv = (NSSItem *)NULL;
+ NSSItem *mdItem;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSItem *)NULL;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != *pError ) {
+ return (NSSItem *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwObject->mdObject->GetAttributeSize ) {
+ *pError = CKR_GENERAL_ERROR;
+ return (NSSItem *)NULL;
+ }
+
+ *pError = nssCKFWMutex_Lock(fwObject->mutex);
+ if( CKR_OK != *pError ) {
+ return (NSSItem *)NULL;
+ }
+
+ mdItem = fwObject->mdObject->GetAttribute(fwObject->mdObject, fwObject,
+ fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
+ fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
+ attribute, pError);
+
+ if( (NSSItem *)NULL == mdItem ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+
+ goto done;
+ }
+
+ if( (NSSItem *)NULL == itemOpt ) {
+ rv = nss_ZNEW(arenaOpt, NSSItem);
+ if( (NSSItem *)NULL == rv ) {
+ *pError = CKR_HOST_MEMORY;
+ goto done;
+ }
+ } else {
+ rv = itemOpt;
+ }
+
+ if( (void *)NULL == rv->data ) {
+ rv->size = mdItem->size;
+ rv->data = nss_ZAlloc(arenaOpt, rv->size);
+ if( (void *)NULL == rv->data ) {
+ *pError = CKR_HOST_MEMORY;
+ if( (NSSItem *)NULL == itemOpt ) {
+ nss_ZFreeIf(rv);
+ }
+ rv = (NSSItem *)NULL;
+ goto done;
+ }
+ } else {
+ if( rv->size >= mdItem->size ) {
+ rv->size = mdItem->size;
+ } else {
+ *pError = CKR_BUFFER_TOO_SMALL;
+ /* Should we set rv->size to mdItem->size? */
+ /* rv can't have been allocated */
+ rv = (NSSItem *)NULL;
+ goto done;
+ }
+ }
+
+ (void)nsslibc_memcpy(rv->data, mdItem->data, rv->size);
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWObject_SetAttribute
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWObject_SetAttribute
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *value
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKA_TOKEN == attribute ) {
+ /*
+ * We're changing from a session object to a token object or
+ * vice-versa.
+ */
+
+ CK_ATTRIBUTE a;
+ NSSCKFWObject *newFwObject;
+ NSSCKFWObject swab;
+
+ a.type = CKA_TOKEN;
+ a.pValue = value->data;
+ a.ulValueLen = value->size;
+
+ newFwObject = nssCKFWSession_CopyObject(fwObject->fwSession, fwObject,
+ &a, 1, &error);
+ if( (NSSCKFWObject *)NULL == newFwObject ) {
+ if( CKR_OK == error ) {
+ error = CKR_GENERAL_ERROR;
+ }
+ return error;
+ }
+
+ /*
+ * Actually, I bet the locking is worse than this.. this part of
+ * the code could probably use some scrutiny and reworking.
+ */
+ error = nssCKFWMutex_Lock(fwObject->mutex);
+ if( CKR_OK != error ) {
+ nssCKFWObject_Destroy(newFwObject);
+ return error;
+ }
+
+ error = nssCKFWMutex_Lock(newFwObject->mutex);
+ if( CKR_OK != error ) {
+ nssCKFWMutex_Unlock(fwObject->mutex);
+ nssCKFWObject_Destroy(newFwObject);
+ return error;
+ }
+
+ /*
+ * Now, we have our new object, but it has a new fwObject pointer,
+ * while we have to keep the existing one. So quick swap the contents.
+ */
+ swab = *fwObject;
+ *fwObject = *newFwObject;
+ *newFwObject = swab;
+
+ /* But keep the mutexes the same */
+ swab.mutex = fwObject->mutex;
+ fwObject->mutex = newFwObject->mutex;
+ newFwObject->mutex = swab.mutex;
+
+ (void)nssCKFWMutex_Unlock(newFwObject->mutex);
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+
+ /*
+ * Now delete the old object. Remember the names have changed.
+ */
+ nssCKFWObject_Destroy(newFwObject);
+
+ return CKR_OK;
+ } else {
+ /*
+ * An "ordinary" change.
+ */
+ if( (void *)NULL == (void *)fwObject->mdObject->SetAttribute ) {
+ /* We could fake it with copying, like above.. later */
+ return CKR_ATTRIBUTE_READ_ONLY;
+ }
+
+ error = nssCKFWMutex_Lock(fwObject->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ error = fwObject->mdObject->SetAttribute(fwObject->mdObject, fwObject,
+ fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
+ fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
+ attribute, value);
+
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+
+ return error;
+ }
+}
+
+/*
+ * nssCKFWObject_GetObjectSize
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWObject_GetObjectSize
+(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+)
+{
+ CK_ULONG rv;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (CK_ULONG)0;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != *pError ) {
+ return (CK_ULONG)0;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwObject->mdObject->GetObjectSize ) {
+ *pError = CKR_INFORMATION_SENSITIVE;
+ return (CK_ULONG)0;
+ }
+
+ *pError = nssCKFWMutex_Lock(fwObject->mutex);
+ if( CKR_OK != *pError ) {
+ return (CK_ULONG)0;
+ }
+
+ rv = fwObject->mdObject->GetObjectSize(fwObject->mdObject, fwObject,
+ fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
+ fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
+ pError);
+
+ (void)nssCKFWMutex_Unlock(fwObject->mutex);
+ return rv;
+}
+
+/*
+ * NSSCKFWObject_GetMDObject
+ *
+ */
+NSS_IMPLEMENT NSSCKMDObject *
+NSSCKFWObject_GetMDObject
+(
+ NSSCKFWObject *fwObject
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
+ return (NSSCKMDObject *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWObject_GetMDObject(fwObject);
+}
+
+/*
+ * NSSCKFWObject_GetArena
+ *
+ */
+NSS_IMPLEMENT NSSArena *
+NSSCKFWObject_GetArena
+(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+)
+{
+#ifdef DEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != *pError ) {
+ return (NSSArena *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWObject_GetArena(fwObject, pError);
+}
+
+/*
+ * NSSCKFWObject_IsTokenObject
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+NSSCKFWObject_IsTokenObject
+(
+ NSSCKFWObject *fwObject
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
+ return CK_FALSE;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWObject_IsTokenObject(fwObject);
+}
+
+/*
+ * NSSCKFWObject_GetAttributeCount
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+NSSCKFWObject_GetAttributeCount
+(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+)
+{
+#ifdef DEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (CK_ULONG)0;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != *pError ) {
+ return (CK_ULONG)0;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWObject_GetAttributeCount(fwObject, pError);
+}
+
+/*
+ * NSSCKFWObject_GetAttributeTypes
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWObject_GetAttributeTypes
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE_PTR typeArray,
+ CK_ULONG ulCount
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef DEBUG
+ error = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWObject_GetAttributeTypes(fwObject, typeArray, ulCount);
+}
+
+/*
+ * NSSCKFWObject_GetAttributeSize
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+NSSCKFWObject_GetAttributeSize
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+)
+{
+#ifdef DEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (CK_ULONG)0;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != *pError ) {
+ return (CK_ULONG)0;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWObject_GetAttributeSize(fwObject, attribute, pError);
+}
+
+/*
+ * NSSCKFWObject_GetAttribute
+ *
+ */
+NSS_IMPLEMENT NSSItem *
+NSSCKFWObject_GetAttribute
+(
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *itemOpt,
+ NSSArena *arenaOpt,
+ CK_RV *pError
+)
+{
+#ifdef DEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSItem *)NULL;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != *pError ) {
+ return (NSSItem *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWObject_GetAttribute(fwObject, attribute, itemOpt, arenaOpt, pError);
+}
+
+/*
+ * NSSCKFWObject_GetObjectSize
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+NSSCKFWObject_GetObjectSize
+(
+ NSSCKFWObject *fwObject,
+ CK_RV *pError
+)
+{
+#ifdef DEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (CK_ULONG)0;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != *pError ) {
+ return (CK_ULONG)0;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWObject_GetObjectSize(fwObject, pError);
+}
diff --git a/security/nss/lib/ckfw/session.c b/security/nss/lib/ckfw/session.c
new file mode 100644
index 000000000..4335be4f2
--- /dev/null
+++ b/security/nss/lib/ckfw/session.c
@@ -0,0 +1,1651 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * session.c
+ *
+ * This file implements the NSSCKFWSession type and methods.
+ */
+
+#ifndef CK_T
+#include "ck.h"
+#endif /* CK_T */
+
+/*
+ * NSSCKFWSession
+ *
+ * -- create/destroy --
+ * nssCKFWSession_Create
+ * nssCKFWSession_Destroy
+ *
+ * -- public accessors --
+ * NSSCKFWSession_GetMDSession
+ * NSSCKFWSession_GetArena
+ * NSSCKFWSession_CallNotification
+ * NSSCKFWSession_IsRWSession
+ * NSSCKFWSession_IsSO
+ *
+ * -- implement public accessors --
+ * nssCKFWSession_GetMDSession
+ * nssCKFWSession_GetArena
+ * nssCKFWSession_CallNotification
+ * nssCKFWSession_IsRWSession
+ * nssCKFWSession_IsSO
+ *
+ * -- private accessors --
+ * nssCKFWSession_GetSlot
+ * nssCKFWSession_GetSessionState
+ * nssCKFWSession_SetFWFindObjects
+ * nssCKFWSession_GetFWFindObjects
+ *
+ * -- module fronts --
+ * nssCKFWSession_GetDeviceError
+ * nssCKFWSession_Login
+ * nssCKFWSession_Logout
+ * nssCKFWSession_InitPIN
+ * nssCKFWSession_SetPIN
+ * nssCKFWSession_GetOperationStateLen
+ * nssCKFWSession_GetOperationState
+ * nssCKFWSession_SetOperationState
+ * nssCKFWSession_CreateObject
+ * nssCKFWSession_CopyObject
+ * nssCKFWSession_FindObjectsInit
+ * nssCKFWSession_SeedRandom
+ * nssCKFWSession_GetRandom
+ */
+
+struct NSSCKFWSessionStr {
+ NSSArena *arena;
+ NSSCKMDSession *mdSession;
+ NSSCKFWToken *fwToken;
+ NSSCKMDToken *mdToken;
+ NSSCKFWInstance *fwInstance;
+ NSSCKMDInstance *mdInstance;
+ CK_VOID_PTR pApplication;
+ CK_NOTIFY Notify;
+
+ /*
+ * Everything above is set at creation time, and then not modified.
+ * The items below are atomic. No locking required. If we fear
+ * about pointer-copies being nonatomic, we'll lock fwFindObjects.
+ */
+
+ CK_BBOOL rw;
+ NSSCKFWFindObjects *fwFindObjects;
+};
+
+#ifdef DEBUG
+/*
+ * But first, the pointer-tracking stuff.
+ *
+ * NOTE: the pointer-tracking support in NSS/base currently relies
+ * upon NSPR's CallOnce support. That, however, relies upon NSPR's
+ * locking, which is tied into the runtime. We need a pointer-tracker
+ * implementation that uses the locks supplied through C_Initialize.
+ * That support, however, can be filled in later. So for now, I'll
+ * just do this routines as no-ops.
+ */
+
+static CK_RV
+session_add_pointer
+(
+ const NSSCKFWSession *fwSession
+)
+{
+ return CKR_OK;
+}
+
+static CK_RV
+session_remove_pointer
+(
+ const NSSCKFWSession *fwSession
+)
+{
+ return CKR_OK;
+}
+
+NSS_IMPLEMENT CK_RV
+nssCKFWSession_verifyPointer
+(
+ const NSSCKFWSession *fwSession
+)
+{
+ return CKR_OK;
+}
+
+#endif /* DEBUG */
+
+/*
+ * nssCKFWSession_Create
+ *
+ */
+NSS_IMPLEMENT NSSCKFWSession *
+nssCKFWSession_Create
+(
+ NSSCKFWToken *fwToken,
+ NSSCKMDSession *mdSession,
+ CK_BBOOL rw,
+ CK_VOID_PTR pApplication,
+ CK_NOTIFY Notify,
+ CK_RV *pError
+)
+{
+ NSSArena *arena = (NSSArena *)NULL;
+ NSSCKFWSession *fwSession;
+ NSSCKFWSlot *fwSlot;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWSession *)NULL;
+ }
+
+ *pError = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWSession *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ arena = NSSArena_Create();
+ if( (NSSArena *)NULL == arena ) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKFWSession *)NULL;
+ }
+
+ fwSession = nss_ZNEW(arena, NSSCKFWSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ fwSession->arena = arena;
+ fwSession->mdSession = mdSession;
+ fwSession->fwToken = fwToken;
+ fwSession->mdToken = nssCKFWToken_GetMDToken(fwToken);
+
+ fwSlot = nssCKFWToken_GetFWSlot(fwToken);
+ fwSession->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
+ fwSession->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
+
+ fwSession->rw = rw;
+ fwSession->pApplication = pApplication;
+ fwSession->Notify = Notify;
+
+ fwSession->fwFindObjects = (NSSCKFWFindObjects *)NULL;
+
+#ifdef DEBUG
+ *pError = session_add_pointer(fwSession);
+ if( CKR_OK != *pError ) {
+ goto loser;
+ }
+#endif /* DEBUG */
+
+ return fwSession;
+
+ loser:
+ if( (NSSArena *)NULL != arena ) {
+ NSSArena_Destroy(arena);
+ }
+
+ return (NSSCKFWSession *)NULL;
+}
+
+/*
+ * nssCKFWSession_Destroy
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSession_Destroy
+(
+ NSSCKFWSession *fwSession,
+ CK_BBOOL removeFromTokenHash
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ if( removeFromTokenHash ) {
+ error = nssCKFWToken_RemoveSession(fwSession->fwToken, fwSession);
+ }
+
+ /*
+ * Invalidate session objects
+ */
+
+#ifdef DEBUG
+ (void)session_remove_pointer(fwSession);
+#endif /* DEBUG */
+ NSSArena_Destroy(fwSession->arena);
+
+ return error;
+}
+
+/*
+ * nssCKFWSession_GetMDSession
+ *
+ */
+NSS_IMPLEMENT NSSCKMDSession *
+nssCKFWSession_GetMDSession
+(
+ NSSCKFWSession *fwSession
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
+ return (NSSCKMDSession *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwSession->mdSession;
+}
+
+/*
+ * nssCKFWSession_GetArena
+ *
+ */
+NSS_IMPLEMENT NSSArena *
+nssCKFWSession_GetArena
+(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+)
+{
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != *pError ) {
+ return (NSSArena *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwSession->arena;
+}
+
+/*
+ * nssCKFWSession_CallNotification
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSession_CallNotification
+(
+ NSSCKFWSession *fwSession,
+ CK_NOTIFICATION event
+)
+{
+ CK_RV error = CKR_OK;
+ CK_SESSION_HANDLE handle;
+
+#ifdef NSSDEBUG
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ if( (CK_NOTIFY)NULL == fwSession->Notify ) {
+ return CKR_OK;
+ }
+
+ handle = nssCKFWInstance_FindSessionHandle(fwSession->fwInstance, fwSession);
+ if( (CK_SESSION_HANDLE)0 == handle ) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ error = fwSession->Notify(handle, event, fwSession->pApplication);
+
+ return error;
+}
+
+/*
+ * nssCKFWSession_IsRWSession
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWSession_IsRWSession
+(
+ NSSCKFWSession *fwSession
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ return fwSession->rw;
+}
+
+/*
+ * nssCKFWSession_IsSO
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWSession_IsSO
+(
+ NSSCKFWSession *fwSession
+)
+{
+ CK_STATE state;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ state = nssCKFWToken_GetSessionState(fwSession->fwToken);
+ switch( state ) {
+ case CKS_RO_PUBLIC_SESSION:
+ case CKS_RO_USER_FUNCTIONS:
+ case CKS_RW_PUBLIC_SESSION:
+ case CKS_RW_USER_FUNCTIONS:
+ return CK_FALSE;
+ case CKS_RW_SO_FUNCTIONS:
+ return CK_TRUE;
+ default:
+ return CK_FALSE;
+ }
+}
+
+/*
+ * nssCKFWSession_GetFWSlot
+ *
+ */
+NSS_IMPLEMENT NSSCKFWSlot *
+nssCKFWSession_GetFWSlot
+(
+ NSSCKFWSession *fwSession
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
+ return (NSSCKFWSlot *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return nssCKFWToken_GetFWSlot(fwSession->fwToken);
+}
+
+/*
+ * nssCFKWSession_GetSessionState
+ *
+ */
+NSS_IMPLEMENT CK_STATE
+nssCKFWSession_GetSessionState
+(
+ NSSCKFWSession *fwSession
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
+ return CKS_RO_PUBLIC_SESSION; /* whatever */
+ }
+#endif /* NSSDEBUG */
+
+ return nssCKFWToken_GetSessionState(fwSession->fwToken);
+}
+
+/*
+ * nssCKFWSession_SetFWFindObjects
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSession_SetFWFindObjects
+(
+ NSSCKFWSession *fwSession,
+ NSSCKFWFindObjects *fwFindObjects
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ /* fwFindObjects may be null */
+#endif /* NSSDEBUG */
+
+ if( (NSSCKFWFindObjects *)NULL != fwSession->fwFindObjects ) {
+ return CKR_OPERATION_ACTIVE;
+ }
+
+ fwSession->fwFindObjects = fwFindObjects;
+
+ return CKR_OK;
+}
+
+/*
+ * nssCKFWSession_GetFWFindObjects
+ *
+ */
+NSS_IMPLEMENT NSSCKFWFindObjects *
+nssCKFWSession_GetFWFindObjects
+(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+)
+{
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWFindObjects *)NULL;
+ }
+
+ *pError = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWFindObjects *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ if( (NSSCKFWFindObjects *)NULL == fwSession->fwFindObjects ) {
+ *pError = CKR_OPERATION_NOT_INITIALIZED;
+ return (NSSCKFWFindObjects *)NULL;
+ }
+
+ return fwSession->fwFindObjects;
+}
+
+/*
+ * nssCKFWSession_GetDeviceError
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWSession_GetDeviceError
+(
+ NSSCKFWSession *fwSession
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwSession->mdSession->GetDeviceError ) {
+ return (CK_ULONG)0;
+ }
+
+ return fwSession->mdSession->GetDeviceError(fwSession->mdSession,
+ fwSession, fwSession->mdToken, fwSession->fwToken,
+ fwSession->mdInstance, fwSession->fwInstance);
+}
+
+/*
+ * nssCKFWSession_Login
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSession_Login
+(
+ NSSCKFWSession *fwSession,
+ CK_USER_TYPE userType,
+ NSSItem *pin
+)
+{
+ CK_RV error = CKR_OK;
+ CK_STATE oldState;
+ CK_STATE newState;
+
+#ifdef NSSDEBUG
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ switch( userType ) {
+ case CKU_SO:
+ case CKU_USER:
+ break;
+ default:
+ return CKR_USER_TYPE_INVALID;
+ }
+
+ if( (NSSItem *)NULL == pin ) {
+ if( CK_TRUE != nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken) ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+ }
+#endif /* NSSDEBUG */
+
+ oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);
+
+ /*
+ * It's not clear what happens when you're already logged in.
+ * I'll just fail; but if we decide to change, the logic is
+ * all right here.
+ */
+
+ if( CKU_SO == userType ) {
+ switch( oldState ) {
+ case CKS_RO_PUBLIC_SESSION:
+ /*
+ * There's no such thing as a read-only security officer
+ * session, so fail. The error should be CKR_SESSION_READ_ONLY,
+ * except that C_Login isn't defined to return that. So we'll
+ * do CKR_SESSION_READ_ONLY_EXISTS, which is what is documented.
+ */
+ return CKR_SESSION_READ_ONLY_EXISTS;
+ case CKS_RO_USER_FUNCTIONS:
+ return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
+ case CKS_RW_PUBLIC_SESSION:
+ newState = CKS_RW_SO_FUNCTIONS;
+ break;
+ case CKS_RW_USER_FUNCTIONS:
+ return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
+ case CKS_RW_SO_FUNCTIONS:
+ return CKR_USER_ALREADY_LOGGED_IN;
+ default:
+ return CKR_GENERAL_ERROR;
+ }
+ } else /* CKU_USER == userType */ {
+ switch( oldState ) {
+ case CKS_RO_PUBLIC_SESSION:
+ newState = CKS_RO_USER_FUNCTIONS;
+ break;
+ case CKS_RO_USER_FUNCTIONS:
+ return CKR_USER_ALREADY_LOGGED_IN;
+ case CKS_RW_PUBLIC_SESSION:
+ newState = CKS_RW_USER_FUNCTIONS;
+ break;
+ case CKS_RW_USER_FUNCTIONS:
+ return CKR_USER_ALREADY_LOGGED_IN;
+ case CKS_RW_SO_FUNCTIONS:
+ return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
+ default:
+ return CKR_GENERAL_ERROR;
+ }
+ }
+
+ /*
+ * So now we're in one of three cases:
+ *
+ * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_SO_FUNCTIONS;
+ * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_USER_FUNCTIONS;
+ * Old == CKS_RO_PUBLIC_SESSION, New == CKS_RO_USER_FUNCTIONS;
+ */
+
+ if( (void *)NULL == (void *)fwSession->mdSession->Login ) {
+ /*
+ * The Module doesn't want to be informed (or check the pin)
+ * it'll just rely on the Framework as needed.
+ */
+ ;
+ } else {
+ error = fwSession->mdSession->Login(fwSession->mdSession, fwSession,
+ fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
+ fwSession->fwInstance, userType, pin, oldState, newState);
+ if( CKR_OK != error ) {
+ return error;
+ }
+ }
+
+ (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState);
+ return CKR_OK;
+}
+
+/*
+ * nssCKFWSession_Logout
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSession_Logout
+(
+ NSSCKFWSession *fwSession
+)
+{
+ CK_RV error = CKR_OK;
+ CK_STATE oldState;
+ CK_STATE newState;
+
+#ifdef NSSDEBUG
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);
+
+ switch( oldState ) {
+ case CKS_RO_PUBLIC_SESSION:
+ return CKR_USER_NOT_LOGGED_IN;
+ case CKS_RO_USER_FUNCTIONS:
+ newState = CKS_RO_PUBLIC_SESSION;
+ break;
+ case CKS_RW_PUBLIC_SESSION:
+ return CKR_USER_NOT_LOGGED_IN;
+ case CKS_RW_USER_FUNCTIONS:
+ newState = CKS_RW_PUBLIC_SESSION;
+ break;
+ case CKS_RW_SO_FUNCTIONS:
+ newState = CKS_RW_PUBLIC_SESSION;
+ break;
+ default:
+ return CKR_GENERAL_ERROR;
+ }
+
+ /*
+ * So now we're in one of three cases:
+ *
+ * Old == CKS_RW_SO_FUNCTIONS, New == CKS_RW_PUBLIC_SESSION;
+ * Old == CKS_RW_USER_FUNCTIONS, New == CKS_RW_PUBLIC_SESSION;
+ * Old == CKS_RO_USER_FUNCTIONS, New == CKS_RO_PUBLIC_SESSION;
+ */
+
+ if( (void *)NULL == (void *)fwSession->mdSession->Logout ) {
+ /*
+ * The Module doesn't want to be informed. Okay.
+ */
+ ;
+ } else {
+ error = fwSession->mdSession->Logout(fwSession->mdSession, fwSession,
+ fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
+ fwSession->fwInstance, oldState, newState);
+ if( CKR_OK != error ) {
+ /*
+ * Now what?! A failure really should end up with the Framework
+ * considering it logged out, right?
+ */
+ ;
+ }
+ }
+
+ (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState);
+ return error;
+}
+
+/*
+ * nssCKFWSession_InitPIN
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSession_InitPIN
+(
+ NSSCKFWSession *fwSession,
+ NSSItem *pin
+)
+{
+ CK_RV error = CKR_OK;
+ CK_STATE state;
+
+#ifdef NSSDEBUG
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ state = nssCKFWToken_GetSessionState(fwSession->fwToken);
+ if( CKS_RW_SO_FUNCTIONS != state ) {
+ return CKR_USER_NOT_LOGGED_IN;
+ }
+
+ if( (NSSItem *)NULL == pin ) {
+ CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
+ if( CK_TRUE != has ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+ }
+
+ if( (void *)NULL == (void *)fwSession->mdSession->InitPIN ) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+
+ error = fwSession->mdSession->InitPIN(fwSession->mdSession, fwSession,
+ fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
+ fwSession->fwInstance, pin);
+
+ return error;
+}
+
+/*
+ * nssCKFWSession_SetPIN
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSession_SetPIN
+(
+ NSSCKFWSession *fwSession,
+ NSSItem *newPin,
+ NSSItem *oldPin
+)
+{
+ CK_RV error = CKR_OK;
+ CK_STATE state;
+
+#ifdef NSSDEBUG
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ state = nssCKFWToken_GetSessionState(fwSession->fwToken);
+ if( (CKS_RW_SO_FUNCTIONS != state) &&
+ (CKS_RW_USER_FUNCTIONS != state) ) {
+ return CKR_USER_NOT_LOGGED_IN;
+ }
+
+ if( (NSSItem *)NULL == newPin ) {
+ CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
+ if( CK_TRUE != has ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+ }
+
+ if( (NSSItem *)NULL == oldPin ) {
+ CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
+ if( CK_TRUE != has ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+ }
+
+ if( (void *)NULL == (void *)fwSession->mdSession->SetPIN ) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+
+ error = fwSession->mdSession->SetPIN(fwSession->mdSession, fwSession,
+ fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
+ fwSession->fwInstance, newPin, oldPin);
+
+ return error;
+}
+
+/*
+ * nssCKFWSession_GetOperationStateLen
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWSession_GetOperationStateLen
+(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+)
+{
+ CK_ULONG mdAmt;
+ CK_ULONG fwAmt;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (CK_ULONG)0;
+ }
+
+ *pError = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != *pError ) {
+ return (CK_ULONG)0;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwSession->mdSession->GetOperationStateLen ) {
+ *pError = CKR_STATE_UNSAVEABLE;
+ }
+
+ /*
+ * We could check that the session is actually in some state..
+ */
+
+ mdAmt = fwSession->mdSession->GetOperationStateLen(fwSession->mdSession,
+ fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
+ fwSession->fwInstance, pError);
+
+ if( ((CK_ULONG)0 == mdAmt) && (CKR_OK != *pError) ) {
+ return (CK_ULONG)0;
+ }
+
+ /*
+ * Add a bit of sanity-checking
+ */
+ fwAmt = mdAmt + 2*sizeof(CK_ULONG);
+
+ return fwAmt;
+}
+
+/*
+ * nssCKFWSession_GetOperationState
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSession_GetOperationState
+(
+ NSSCKFWSession *fwSession,
+ NSSItem *buffer
+)
+{
+ CK_RV error = CKR_OK;
+ CK_ULONG fwAmt;
+ CK_ULONG *ulBuffer;
+ NSSItem i2;
+ CK_ULONG n, i;
+
+#ifdef NSSDEBUG
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (NSSItem *)NULL == buffer ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ if( (void *)NULL == buffer->data ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwSession->mdSession->GetOperationState ) {
+ return CKR_STATE_UNSAVEABLE;
+ }
+
+ /*
+ * Sanity-check the caller's buffer.
+ */
+
+ error = CKR_OK;
+ fwAmt = nssCKFWSession_GetOperationStateLen(fwSession, &error);
+ if( ((CK_ULONG)0 == fwAmt) && (CKR_OK != error) ) {
+ return error;
+ }
+
+ if( buffer->size < fwAmt ) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ ulBuffer = (CK_ULONG *)buffer->data;
+
+ i2.size = buffer->size - 2*sizeof(CK_ULONG);
+ i2.data = (void *)&ulBuffer[2];
+
+ error = fwSession->mdSession->GetOperationState(fwSession->mdSession,
+ fwSession, fwSession->mdToken, fwSession->fwToken,
+ fwSession->mdInstance, fwSession->fwInstance, &i2);
+
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ /*
+ * Add a little integrety/identity check.
+ * NOTE: right now, it's pretty stupid.
+ * A CRC or something would be better.
+ */
+
+ ulBuffer[0] = 0x434b4657; /* CKFW */
+ ulBuffer[1] = 0;
+ n = i2.size/sizeof(CK_ULONG);
+ for( i = 0; i < n; i++ ) {
+ ulBuffer[1] ^= ulBuffer[2+i];
+ }
+
+ return CKR_OK;
+}
+
+/*
+ * nssCKFWSession_SetOperationState
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSession_SetOperationState
+(
+ NSSCKFWSession *fwSession,
+ NSSItem *state,
+ NSSCKFWObject *encryptionKey,
+ NSSCKFWObject *authenticationKey
+)
+{
+ CK_RV error = CKR_OK;
+ CK_ULONG *ulBuffer;
+ CK_ULONG n, i;
+ CK_ULONG x;
+ NSSItem s;
+ NSSCKMDObject *mdek;
+ NSSCKMDObject *mdak;
+
+#ifdef NSSDEBUG
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (NSSItem *)NULL == state ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ if( (void *)NULL == state->data ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ if( (NSSCKFWObject *)NULL != encryptionKey ) {
+ error = nssCKFWObject_verifyPointer(encryptionKey);
+ if( CKR_OK != error ) {
+ return error;
+ }
+ }
+
+ if( (NSSCKFWObject *)NULL != authenticationKey ) {
+ error = nssCKFWObject_verifyPointer(authenticationKey);
+ if( CKR_OK != error ) {
+ return error;
+ }
+ }
+#endif /* NSSDEBUG */
+
+ ulBuffer = (CK_ULONG *)state->data;
+ if( 0x43b4657 != ulBuffer[0] ) {
+ return CKR_SAVED_STATE_INVALID;
+ }
+ n = (state->size / sizeof(CK_ULONG)) - 2;
+ x = (CK_ULONG)0;
+ for( i = 0; i < n; i++ ) {
+ x ^= ulBuffer[2+i];
+ }
+
+ if( x != ulBuffer[1] ) {
+ return CKR_SAVED_STATE_INVALID;
+ }
+
+ if( (void *)NULL == (void *)fwSession->mdSession->SetOperationState ) {
+ return CKR_GENERAL_ERROR;
+ }
+
+ s.size = state->size - 2*sizeof(CK_ULONG);
+ s.data = (void *)&ulBuffer[2];
+
+ if( (NSSCKFWObject *)NULL != encryptionKey ) {
+ mdek = nssCKFWObject_GetMDObject(encryptionKey);
+ } else {
+ mdek = (NSSCKMDObject *)NULL;
+ }
+
+ if( (NSSCKFWObject *)NULL != authenticationKey ) {
+ mdak = nssCKFWObject_GetMDObject(authenticationKey);
+ } else {
+ mdak = (NSSCKMDObject *)NULL;
+ }
+
+ error = fwSession->mdSession->SetOperationState(fwSession->mdSession,
+ fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
+ fwSession->fwInstance, &s, mdek, encryptionKey, mdak, authenticationKey);
+
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ /*
+ * Here'd we restore any session data
+ */
+
+ return CKR_OK;
+}
+
+static CK_BBOOL
+nss_attributes_form_token_object
+(
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount
+)
+{
+ CK_ULONG i;
+ CK_BBOOL rv;
+
+ for( i = 0; i < ulAttributeCount; i++ ) {
+ if( CKA_TOKEN == pTemplate[i].type ) {
+ /* If we sanity-check, we can remove this sizeof check */
+ if( sizeof(CK_BBOOL) == pTemplate[i].ulValueLen ) {
+ (void)nsslibc_memcpy(&rv, pTemplate[i].pValue, sizeof(CK_BBOOL));
+ return rv;
+ } else {
+ return CK_FALSE;
+ }
+ }
+ }
+
+ return CK_FALSE;
+}
+
+/*
+ * nssCKFWSession_CreateObject
+ *
+ */
+NSS_IMPLEMENT NSSCKFWObject *
+nssCKFWSession_CreateObject
+(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+)
+{
+ NSSArena *arena;
+ NSSCKMDObject *mdObject;
+ NSSCKFWObject *fwObject;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWObject *)NULL;
+ }
+
+ *pError = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != pError ) {
+ return (NSSCKFWObject *)NULL;
+ }
+
+ if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSCKFWObject *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ /*
+ * Here would be an excellent place to sanity-check the object.
+ */
+
+ if( CK_TRUE == nss_attributes_form_token_object(pTemplate, ulAttributeCount) ) {
+ /* === TOKEN OBJECT === */
+
+ if( (void *)NULL == (void *)fwSession->mdSession->CreateObject ) {
+ *pError = CKR_TOKEN_WRITE_PROTECTED;
+ return (NSSCKFWObject *)NULL;
+ }
+
+ arena = nssCKFWToken_GetArena(fwSession->fwToken, pError);
+ if( (NSSArena *)NULL == arena ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWObject *)NULL;
+ }
+
+ goto callmdcreateobject;
+ } else {
+ /* === SESSION OBJECT === */
+
+ arena = nssCKFWSession_GetArena(fwSession, pError);
+ if( (NSSArena *)NULL == arena ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWObject *)NULL;
+ }
+
+ if( CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
+ fwSession->fwInstance) ) {
+ /* --- module handles the session object -- */
+
+ if( (void *)NULL == (void *)fwSession->mdSession->CreateObject ) {
+ *pError = CKR_GENERAL_ERROR;
+ return (NSSCKFWObject *)NULL;
+ }
+
+ goto callmdcreateobject;
+ } else {
+ /* --- framework handles the session object -- */
+ mdObject = nssCKMDSessionObject_Create(fwSession->fwToken,
+ arena, pTemplate, ulAttributeCount, pError);
+ goto gotmdobject;
+ }
+ }
+
+ callmdcreateobject:
+ mdObject = fwSession->mdSession->CreateObject(fwSession->mdSession,
+ fwSession, fwSession->mdToken, fwSession->fwToken,
+ fwSession->mdInstance, fwSession->fwInstance, arena, pTemplate,
+ ulAttributeCount, pError);
+
+ gotmdobject:
+ if( (NSSCKMDObject *)NULL == mdObject ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWObject *)NULL;
+ }
+
+ fwObject = nssCKFWObject_Create(arena, mdObject, fwSession,
+ fwSession->fwToken, fwSession->fwInstance, pError);
+ if( (NSSCKFWObject *)NULL == fwObject ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+
+ if( (void *)NULL != (void *)mdObject->Destroy ) {
+ (void)mdObject->Destroy(mdObject, (NSSCKFWObject *)NULL,
+ fwSession->mdSession, fwSession, fwSession->mdToken,
+ fwSession->fwToken, fwSession->mdInstance, fwSession->fwInstance);
+ }
+
+ return (NSSCKFWObject *)NULL;
+ }
+
+ return fwObject;
+}
+
+/*
+ * nssCKFWSession_CopyObject
+ *
+ */
+NSS_IMPLEMENT NSSCKFWObject *
+nssCKFWSession_CopyObject
+(
+ NSSCKFWSession *fwSession,
+ NSSCKFWObject *fwObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+)
+{
+ CK_BBOOL oldIsToken;
+ CK_BBOOL newIsToken;
+ CK_ULONG i;
+ NSSCKFWObject *rv;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWObject *)NULL;
+ }
+
+ *pError = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWObject *)NULL;
+ }
+
+ *pError = nssCKFWObject_verifyPointer(fwObject);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWObject *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ /*
+ * Sanity-check object
+ */
+
+ oldIsToken = nssCKFWObject_IsTokenObject(fwObject);
+
+ newIsToken = oldIsToken;
+ for( i = 0; i < ulAttributeCount; i++ ) {
+ if( CKA_TOKEN == pTemplate[i].type ) {
+ /* Since we sanity-checked the object, we know this is the right size. */
+ (void)nsslibc_memcpy(&newIsToken, pTemplate[i].pValue, sizeof(CK_BBOOL));
+ break;
+ }
+ }
+
+ /*
+ * If the Module handles its session objects, or if both the new
+ * and old object are token objects, use CopyObject if it exists.
+ */
+
+ if( ((void *)NULL != (void *)fwSession->mdSession->CopyObject) &&
+ (((CK_TRUE == oldIsToken) && (CK_TRUE == newIsToken)) ||
+ (CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
+ fwSession->fwInstance))) ) {
+ /* use copy object */
+ NSSArena *arena;
+ NSSCKMDObject *mdOldObject;
+ NSSCKMDObject *mdObject;
+
+ mdOldObject = nssCKFWObject_GetMDObject(fwObject);
+
+ if( CK_TRUE == newIsToken ) {
+ arena = nssCKFWToken_GetArena(fwSession->fwToken, pError);
+ } else {
+ arena = nssCKFWSession_GetArena(fwSession, pError);
+ }
+ if( (NSSArena *)NULL == arena ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWObject *)NULL;
+ }
+
+ mdObject = fwSession->mdSession->CopyObject(fwSession->mdSession,
+ fwSession, fwSession->mdToken, fwSession->fwToken,
+ fwSession->mdInstance, fwSession->fwInstance, mdOldObject,
+ fwObject, arena, pTemplate, ulAttributeCount, pError);
+ if( (NSSCKMDObject *)NULL == mdObject ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWObject *)NULL;
+ }
+
+ rv = nssCKFWObject_Create(arena, mdObject, fwSession,
+ fwSession->fwToken, fwSession->fwInstance, pError);
+ if( (NSSCKFWObject *)NULL == fwObject ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+
+ if( (void *)NULL != (void *)mdObject->Destroy ) {
+ (void)mdObject->Destroy(mdObject, (NSSCKFWObject *)NULL,
+ fwSession->mdSession, fwSession, fwSession->mdToken,
+ fwSession->fwToken, fwSession->mdInstance, fwSession->fwInstance);
+ }
+
+ return (NSSCKFWObject *)NULL;
+ }
+
+ return rv;
+ } else {
+ /* use create object */
+ NSSArena *tmpArena;
+ CK_ATTRIBUTE_PTR newTemplate;
+ CK_ULONG i;
+ NSSCKFWObject *rv;
+
+ tmpArena = NSSArena_Create();
+ if( (NSSArena *)NULL == tmpArena ) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKFWObject *)NULL;
+ }
+
+ newTemplate = nss_ZNEWARRAY(tmpArena, CK_ATTRIBUTE, ulAttributeCount);
+ if( (CK_ATTRIBUTE_PTR)NULL == newTemplate ) {
+ NSSArena_Destroy(tmpArena);
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKFWObject *)NULL;
+ }
+
+ for( i = 0; i < ulAttributeCount; i++ ) {
+ newTemplate[i] = pTemplate[i];
+ if( (void *)NULL == newTemplate[i].pValue ) {
+ NSSItem item;
+ NSSItem *it = nssCKFWObject_GetAttribute(fwObject, newTemplate[i].type,
+ &item, tmpArena, pError);
+ if( (NSSItem *)NULL == it ) {
+ if( CKR_OK != *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ NSSArena_Destroy(tmpArena);
+ return (NSSCKFWObject *)NULL;
+ }
+ newTemplate[i].pValue = it->data;
+ newTemplate[i].ulValueLen = it->size;
+ }
+ }
+
+ rv = nssCKFWSession_CreateObject(fwSession, newTemplate, ulAttributeCount, pError);
+ if( (NSSCKFWObject *)NULL == rv ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ NSSArena_Destroy(tmpArena);
+ return (NSSCKFWObject *)NULL;
+ }
+
+ NSSArena_Destroy(tmpArena);
+ return rv;
+ }
+}
+
+/*
+ * nssCKFWSession_FindObjectsInit
+ *
+ */
+NSS_IMPLEMENT NSSCKFWFindObjects *
+nssCKFWSession_FindObjectsInit
+(
+ NSSCKFWSession *fwSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_RV *pError
+)
+{
+ NSSCKMDFindObjects *mdfo1 = (NSSCKMDFindObjects *)NULL;
+ NSSCKMDFindObjects *mdfo2 = (NSSCKMDFindObjects *)NULL;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWFindObjects *)NULL;
+ }
+
+ *pError = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWFindObjects *)NULL;
+ }
+
+ if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSCKFWFindObjects *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ if( CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
+ fwSession->fwInstance) ) {
+ CK_ULONG i;
+
+ /*
+ * Does the search criteria restrict us to token or session
+ * objects?
+ */
+
+ for( i = 0; i < ulAttributeCount; i++ ) {
+ if( CKA_TOKEN == pTemplate[i].type ) {
+ /* Yes, it does. */
+ CK_BBOOL isToken;
+ if( sizeof(CK_BBOOL) != pTemplate[i].ulValueLen ) {
+ *pError = CKR_ATTRIBUTE_VALUE_INVALID;
+ return (NSSCKFWFindObjects *)NULL;
+ }
+ (void)nsslibc_memcpy(&isToken, pTemplate[i].pValue, sizeof(CK_BBOOL));
+
+ if( CK_TRUE == isToken ) {
+ /* Pass it on to the module's search routine */
+ if( (void *)NULL == (void *)fwSession->mdSession->FindObjectsInit ) {
+ goto wrap;
+ }
+
+ mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
+ fwSession, fwSession->mdToken, fwSession->fwToken,
+ fwSession->mdInstance, fwSession->fwInstance,
+ pTemplate, ulAttributeCount, pError);
+ } else {
+ /* Do the search ourselves */
+ mdfo1 = nssCKMDFindSessionObjects_Create(fwSession->fwToken,
+ pTemplate, ulAttributeCount, pError);
+ }
+
+ if( (NSSCKMDFindObjects *)NULL == mdfo1 ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWFindObjects *)NULL;
+ }
+
+ goto wrap;
+ }
+ }
+
+ if( i == ulAttributeCount ) {
+ /* No, it doesn't. Do a hybrid search. */
+ mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
+ fwSession, fwSession->mdToken, fwSession->fwToken,
+ fwSession->mdInstance, fwSession->fwInstance,
+ pTemplate, ulAttributeCount, pError);
+
+ if( (NSSCKMDFindObjects *)NULL == mdfo1 ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWFindObjects *)NULL;
+ }
+
+ mdfo2 = nssCKMDFindSessionObjects_Create(fwSession->fwToken,
+ pTemplate, ulAttributeCount, pError);
+ if( (NSSCKMDFindObjects *)NULL == mdfo2 ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ if( (void *)NULL != (void *)mdfo1->Final ) {
+ mdfo1->Final(mdfo1, (NSSCKFWFindObjects *)NULL, fwSession->mdSession,
+ fwSession, fwSession->mdToken, fwSession->fwToken,
+ fwSession->mdInstance, fwSession->fwInstance);
+ }
+ return (NSSCKFWFindObjects *)NULL;
+ }
+
+ goto wrap;
+ }
+ /*NOTREACHED*/
+ } else {
+ /* Module handles all its own objects. Pass on to module's search */
+ mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
+ fwSession, fwSession->mdToken, fwSession->fwToken,
+ fwSession->mdInstance, fwSession->fwInstance,
+ pTemplate, ulAttributeCount, pError);
+
+ if( (NSSCKMDFindObjects *)NULL == mdfo1 ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWFindObjects *)NULL;
+ }
+
+ goto wrap;
+ }
+
+ wrap:
+ return nssCKFWFindObjects_Create(fwSession, fwSession->fwToken,
+ fwSession->fwInstance, mdfo1, mdfo2, pError);
+}
+
+/*
+ * nssCKFWSession_SeedRandom
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSession_SeedRandom
+(
+ NSSCKFWSession *fwSession,
+ NSSItem *seed
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (NSSItem *)NULL == seed ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ if( (void *)NULL == seed->data ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ if( 0 == seed->size ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwSession->mdSession->SeedRandom ) {
+ return CKR_RANDOM_SEED_NOT_SUPPORTED;
+ }
+
+ error = fwSession->mdSession->SeedRandom(fwSession->mdSession, fwSession,
+ fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
+ fwSession->fwInstance, seed);
+
+ return error;
+}
+
+/*
+ * nssCKFWSession_GetRandom
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSession_GetRandom
+(
+ NSSCKFWSession *fwSession,
+ NSSItem *buffer
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (NSSItem *)NULL == buffer ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ if( (void *)NULL == buffer->data ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwSession->mdSession->GetRandom ) {
+ if( CK_TRUE == nssCKFWToken_GetHasRNG(fwSession->fwToken) ) {
+ return CKR_GENERAL_ERROR;
+ } else {
+ return CKR_RANDOM_NO_RNG;
+ }
+ }
+
+ if( 0 == buffer->size ) {
+ return CKR_OK;
+ }
+
+ error = fwSession->mdSession->GetRandom(fwSession->mdSession, fwSession,
+ fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
+ fwSession->fwInstance, buffer);
+
+ return error;
+}
+
+/*
+ * NSSCKFWSession_GetMDSession
+ *
+ */
+
+NSS_IMPLEMENT NSSCKMDSession *
+NSSCKFWSession_GetMDSession
+(
+ NSSCKFWSession *fwSession
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
+ return (NSSCKMDSession *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWSession_GetMDSession(fwSession);
+}
+
+/*
+ * NSSCKFWSession_GetArena
+ *
+ */
+
+NSS_IMPLEMENT NSSArena *
+NSSCKFWSession_GetArena
+(
+ NSSCKFWSession *fwSession,
+ CK_RV *pError
+)
+{
+#ifdef DEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != *pError ) {
+ return (NSSArena *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWSession_GetArena(fwSession, pError);
+}
+
+/*
+ * NSSCKFWSession_CallNotification
+ *
+ */
+
+NSS_IMPLEMENT CK_RV
+NSSCKFWSession_CallNotification
+(
+ NSSCKFWSession *fwSession,
+ CK_NOTIFICATION event
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef DEBUG
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWSession_CallNotification(fwSession, event);
+}
+
+/*
+ * NSSCKFWSession_IsRWSession
+ *
+ */
+
+NSS_IMPLEMENT CK_BBOOL
+NSSCKFWSession_IsRWSession
+(
+ NSSCKFWSession *fwSession
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
+ return CK_FALSE;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWSession_IsRWSession(fwSession);
+}
+
+/*
+ * NSSCKFWSession_IsSO
+ *
+ */
+
+NSS_IMPLEMENT CK_BBOOL
+NSSCKFWSession_IsSO
+(
+ NSSCKFWSession *fwSession
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
+ return CK_FALSE;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWSession_IsSO(fwSession);
+}
diff --git a/security/nss/lib/ckfw/sessobj.c b/security/nss/lib/ckfw/sessobj.c
new file mode 100644
index 000000000..8acf81e3a
--- /dev/null
+++ b/security/nss/lib/ckfw/sessobj.c
@@ -0,0 +1,1096 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * sessobj.c
+ *
+ * This file contains an NSSCKMDObject implementation for session
+ * objects. The framework uses this implementation to manage
+ * session objects when a Module doesn't wish to be bothered.
+ */
+
+#ifndef CK_T
+#include "ck.h"
+#endif /* CK_T */
+
+/*
+ * nssCKMDSessionObject
+ *
+ * -- create --
+ * nssCKMDSessionObject_Create
+ *
+ * -- EPV calls --
+ * nss_ckmdSessionObject_Finalize
+ * nss_ckmdSessionObject_IsTokenObject
+ * nss_ckmdSessionObject_GetAttributeCount
+ * nss_ckmdSessionObject_GetAttributeTypes
+ * nss_ckmdSessionObject_GetAttributeSize
+ * nss_ckmdSessionObject_GetAttribute
+ * nss_ckmdSessionObject_SetAttribute
+ * nss_ckmdSessionObject_GetObjectSize
+ */
+
+struct nssCKMDSessionObjectStr {
+ CK_ULONG n;
+ NSSArena *arena;
+ NSSItem *attributes;
+ CK_ATTRIBUTE_TYPE_PTR types;
+ nssCKFWHash *hash;
+};
+typedef struct nssCKMDSessionObjectStr nssCKMDSessionObject;
+
+#ifdef DEBUG
+/*
+ * But first, the pointer-tracking stuff.
+ *
+ * NOTE: the pointer-tracking support in NSS/base currently relies
+ * upon NSPR's CallOnce support. That, however, relies upon NSPR's
+ * locking, which is tied into the runtime. We need a pointer-tracker
+ * implementation that uses the locks supplied through C_Initialize.
+ * That support, however, can be filled in later. So for now, I'll
+ * just do this routines as no-ops.
+ */
+
+static CK_RV
+nss_ckmdSessionObject_add_pointer
+(
+ const NSSCKMDObject *mdObject
+)
+{
+ return CKR_OK;
+}
+
+static CK_RV
+nss_ckmdSessionObject_remove_pointer
+(
+ const NSSCKMDObject *mdObject
+)
+{
+ return CKR_OK;
+}
+
+static CK_RV
+nss_ckmdSessionObject_verifyPointer
+(
+ const NSSCKMDObject *mdObject
+)
+{
+ return CKR_OK;
+}
+
+#endif /* DEBUG */
+
+/*
+ * We must forward-declare these routines
+ */
+static void
+nss_ckmdSessionObject_Finalize
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+);
+
+static CK_RV
+nss_ckmdSessionObject_Destroy
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+);
+
+static CK_BBOOL
+nss_ckmdSessionObject_IsTokenObject
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+);
+
+static CK_ULONG
+nss_ckmdSessionObject_GetAttributeCount
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+);
+
+static CK_RV
+nss_ckmdSessionObject_GetAttributeTypes
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE_PTR typeArray,
+ CK_ULONG ulCount
+);
+
+static CK_ULONG
+nss_ckmdSessionObject_GetAttributeSize
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+);
+
+static NSSItem *
+nss_ckmdSessionObject_GetAttribute
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+);
+
+static CK_RV
+nss_ckmdSessionObject_SetAttribute
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *value
+);
+
+static CK_ULONG
+nss_ckmdSessionObject_GetObjectSize
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+);
+
+/*
+ * nssCKMDSessionObject_Create
+ *
+ */
+NSS_IMPLEMENT NSSCKMDObject *
+nssCKMDSessionObject_Create
+(
+ NSSCKFWToken *fwToken,
+ NSSArena *arena,
+ CK_ATTRIBUTE_PTR attributes,
+ CK_ULONG ulCount,
+ CK_RV *pError
+)
+{
+ NSSCKMDObject *mdObject = (NSSCKMDObject *)NULL;
+ nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)NULL;
+ CK_ULONG i;
+ nssCKFWHash *hash;
+
+ mdso = nss_ZNEW(arena, nssCKMDSessionObject);
+ if( (nssCKMDSessionObject *)NULL == mdso ) {
+ goto loser;
+ }
+
+ mdso->arena = arena;
+ mdso->n = ulCount;
+ mdso->attributes = nss_ZNEWARRAY(arena, NSSItem, ulCount);
+ if( (NSSItem *)NULL == mdso->attributes ) {
+ goto loser;
+ }
+
+ mdso->types = nss_ZNEWARRAY(arena, CK_ATTRIBUTE_TYPE, ulCount);
+
+ for( i = 0; i < ulCount; i++ ) {
+ mdso->types[i] = attributes[i].type;
+ mdso->attributes[i].size = attributes[i].ulValueLen;
+ mdso->attributes[i].data = nss_ZAlloc(arena, attributes[i].ulValueLen);
+ if( (void *)NULL == mdso->attributes[i].data ) {
+ goto loser;
+ }
+ (void)nsslibc_memcpy(mdso->attributes[i].data, attributes[i].pValue,
+ attributes[i].ulValueLen);
+ }
+
+ mdObject = nss_ZNEW(arena, NSSCKMDObject);
+ if( (NSSCKMDObject *)NULL == mdObject ) {
+ goto loser;
+ }
+
+ mdObject->etc = (void *)mdso;
+ mdObject->Finalize = nss_ckmdSessionObject_Finalize;
+ mdObject->Destroy = nss_ckmdSessionObject_Destroy;
+ mdObject->IsTokenObject = nss_ckmdSessionObject_IsTokenObject;
+ mdObject->GetAttributeCount = nss_ckmdSessionObject_GetAttributeCount;
+ mdObject->GetAttributeTypes = nss_ckmdSessionObject_GetAttributeTypes;
+ mdObject->GetAttributeSize = nss_ckmdSessionObject_GetAttributeSize;
+ mdObject->GetAttribute = nss_ckmdSessionObject_GetAttribute;
+ mdObject->SetAttribute = nss_ckmdSessionObject_SetAttribute;
+ mdObject->GetObjectSize = nss_ckmdSessionObject_GetObjectSize;
+
+ hash = nssCKFWToken_GetSessionObjectHash(fwToken);
+ if( (nssCKFWHash *)NULL == hash ) {
+ *pError = CKR_GENERAL_ERROR;
+ goto loser;
+ }
+
+ mdso->hash = hash;
+
+ *pError = nssCKFWHash_Add(hash, mdObject, mdObject);
+ if( CKR_OK != *pError ) {
+ goto loser;
+ }
+
+#ifdef DEBUG
+ if( CKR_OK != nss_ckmdSessionObject_add_pointer(mdObject) ) {
+ goto loser;
+ }
+#endif /* DEBUG */
+
+ *pError = CKR_OK;
+ return mdObject;
+
+ loser:
+ if( (nssCKMDSessionObject *)NULL != mdso ) {
+ if( (NSSItem *)NULL != mdso->attributes ) {
+ for( i = 0; i < ulCount; i++ ) {
+ nss_ZFreeIf(mdso->attributes[i].data);
+ }
+
+ nss_ZFreeIf(mdso->attributes);
+ }
+
+ nss_ZFreeIf(mdso->types);
+ nss_ZFreeIf(mdso);
+ }
+
+ nss_ZFreeIf(mdObject);
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKMDObject *)NULL;
+}
+
+/*
+ * nss_ckmdSessionObject_Finalize
+ *
+ */
+static void
+nss_ckmdSessionObject_Finalize
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ /* This shouldn't ever be called */
+ return;
+}
+
+/*
+ * nss_ckmdSessionObject_Destroy
+ *
+ */
+
+static CK_RV
+nss_ckmdSessionObject_Destroy
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ CK_RV error = CKR_OK;
+ nssCKMDSessionObject *mdso;
+ CK_ULONG i;
+
+#ifdef NSSDEBUG
+ error = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ mdso = (nssCKMDSessionObject *)mdObject->etc;
+
+ nssCKFWHash_Remove(mdso->hash, mdObject);
+
+ for( i = 0; i < mdso->n; i++ ) {
+ nss_ZFreeIf(mdso->attributes[i].data);
+ }
+ nss_ZFreeIf(mdso->attributes);
+ nss_ZFreeIf(mdso->types);
+ nss_ZFreeIf(mdso);
+ nss_ZFreeIf(mdObject);
+
+#ifdef DEBUG
+ (void)nss_ckmdSessionObject_remove_pointer(mdObject);
+#endif /* DEBUG */
+
+ return CKR_OK;
+}
+
+/*
+ * nss_ckmdSessionObject_IsTokenObject
+ *
+ */
+
+static CK_BBOOL
+nss_ckmdSessionObject_IsTokenObject
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nss_ckmdSessionObject_verifyPointer(mdObject) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ /*
+ * This implementation is only ever used for session objects.
+ */
+ return CK_FALSE;
+}
+
+/*
+ * nss_ckmdSessionObject_GetAttributeCount
+ *
+ */
+static CK_ULONG
+nss_ckmdSessionObject_GetAttributeCount
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ nssCKMDSessionObject *obj;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return 0;
+ }
+
+ *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if( CKR_OK != *pError ) {
+ return 0;
+ }
+
+ /* We could even check all the other arguments, for sanity. */
+#endif /* NSSDEBUG */
+
+ obj = (nssCKMDSessionObject *)mdObject->etc;
+
+ return obj->n;
+}
+
+/*
+ * nss_ckmdSessionObject_GetAttributeTypes
+ *
+ */
+static CK_RV
+nss_ckmdSessionObject_GetAttributeTypes
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE_PTR typeArray,
+ CK_ULONG ulCount
+)
+{
+ CK_RV error = CKR_OK;
+ nssCKMDSessionObject *obj;
+
+#ifdef NSSDEBUG
+ error = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ /* We could even check all the other arguments, for sanity. */
+#endif /* NSSDEBUG */
+
+ obj = (nssCKMDSessionObject *)mdObject->etc;
+
+ if( ulCount < obj->n ) {
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ (void)nsslibc_memcpy(typeArray, obj->types,
+ sizeof(CK_ATTRIBUTE_TYPE) * obj->n);
+
+ return CKR_OK;
+}
+
+/*
+ * nss_ckmdSessionObject_GetAttributeSize
+ *
+ */
+static CK_ULONG
+nss_ckmdSessionObject_GetAttributeSize
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+)
+{
+ nssCKMDSessionObject *obj;
+ CK_ULONG i;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return 0;
+ }
+
+ *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if( CKR_OK != *pError ) {
+ return 0;
+ }
+
+ /* We could even check all the other arguments, for sanity. */
+#endif /* NSSDEBUG */
+
+ obj = (nssCKMDSessionObject *)mdObject->etc;
+
+ for( i = 0; i < obj->n; i++ ) {
+ if( attribute == obj->types[i] ) {
+ return (CK_ULONG)(obj->attributes[i].size);
+ }
+ }
+
+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
+ return 0;
+}
+
+/*
+ * nss_ckmdSessionObject_GetAttribute
+ *
+ */
+static NSSItem *
+nss_ckmdSessionObject_GetAttribute
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ CK_RV *pError
+)
+{
+ nssCKMDSessionObject *obj;
+ CK_ULONG i;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return 0;
+ }
+
+ *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if( CKR_OK != *pError ) {
+ return 0;
+ }
+
+ /* We could even check all the other arguments, for sanity. */
+#endif /* NSSDEBUG */
+
+ obj = (nssCKMDSessionObject *)mdObject->etc;
+
+ for( i = 0; i < obj->n; i++ ) {
+ if( attribute == obj->types[i] ) {
+ return &obj->attributes[i];
+ }
+ }
+
+ *pError = CKR_ATTRIBUTE_TYPE_INVALID;
+ return 0;
+}
+
+/*
+ * nss_ckmdSessionObject_SetAttribute
+ *
+ */
+
+/*
+ * Okay, so this implementation sucks. It doesn't support removing
+ * an attribute (if value == NULL), and could be more graceful about
+ * memory. It should allow "blank" slots in the arrays, with some
+ * invalid attribute type, and then it could support removal much
+ * more easily. Do this later.
+ */
+static CK_RV
+nss_ckmdSessionObject_SetAttribute
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_ATTRIBUTE_TYPE attribute,
+ NSSItem *value
+)
+{
+ nssCKMDSessionObject *obj;
+ CK_ULONG i;
+ NSSItem n;
+ NSSItem *ra;
+ CK_ATTRIBUTE_TYPE_PTR rt;
+ CK_RV error;
+
+#ifdef NSSDEBUG
+ error = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if( CKR_OK != error ) {
+ return 0;
+ }
+
+ /* We could even check all the other arguments, for sanity. */
+#endif /* NSSDEBUG */
+
+ obj = (nssCKMDSessionObject *)mdObject->etc;
+
+ n.size = value->size;
+ n.data = nss_ZAlloc(obj->arena, n.size);
+ if( (void *)NULL == n.data ) {
+ return CKR_HOST_MEMORY;
+ }
+ (void)nsslibc_memcpy(n.data, value->data, n.size);
+
+ for( i = 0; i < obj->n; i++ ) {
+ if( attribute == obj->types[i] ) {
+ nss_ZFreeIf(obj->attributes[i].data);
+ obj->attributes[i] = n;
+ return CKR_OK;
+ }
+ }
+
+ /*
+ * It's new.
+ */
+
+ ra = (NSSItem *)nss_ZRealloc(obj->attributes, sizeof(NSSItem) * (obj->n + 1));
+ if( (NSSItem *)NULL == ra ) {
+ nss_ZFreeIf(n.data);
+ return CKR_HOST_MEMORY;
+ }
+
+ rt = (CK_ATTRIBUTE_TYPE_PTR)nss_ZRealloc(obj->types, (obj->n + 1));
+ if( (CK_ATTRIBUTE_TYPE_PTR)NULL == rt ) {
+ nss_ZFreeIf(n.data);
+ obj->attributes = (NSSItem *)nss_ZRealloc(ra, sizeof(NSSItem) * obj->n);
+ if( (NSSItem *)NULL == obj->attributes ) {
+ return CKR_GENERAL_ERROR;
+ }
+ return CKR_HOST_MEMORY;
+ }
+
+ obj->attributes = ra;
+ obj->types = rt;
+ obj->attributes[obj->n] = n;
+ obj->types[obj->n] = attribute;
+ obj->n++;
+
+ return CKR_OK;
+}
+
+/*
+ * nss_ckmdSessionObject_GetObjectSize
+ *
+ */
+static CK_ULONG
+nss_ckmdSessionObject_GetObjectSize
+(
+ NSSCKMDObject *mdObject,
+ NSSCKFWObject *fwObject,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ CK_RV *pError
+)
+{
+ nssCKMDSessionObject *obj;
+ CK_ULONG i;
+ CK_ULONG rv = (CK_ULONG)0;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return 0;
+ }
+
+ *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
+ if( CKR_OK != *pError ) {
+ return 0;
+ }
+
+ /* We could even check all the other arguments, for sanity. */
+#endif /* NSSDEBUG */
+
+ obj = (nssCKMDSessionObject *)mdObject->etc;
+
+ for( i = 0; i < obj->n; i++ ) {
+ rv += obj->attributes[i].size;
+ }
+
+ rv += sizeof(NSSItem) * obj->n;
+ rv += sizeof(CK_ATTRIBUTE_TYPE) * obj->n;
+ rv += sizeof(nssCKMDSessionObject);
+
+ return rv;
+}
+
+/*
+ * nssCKMDFindSessionObjects
+ *
+ * -- create --
+ * nssCKMDFindSessionObjects_Create
+ *
+ * -- EPV calls --
+ * nss_ckmdFindSessionObjects_Final
+ * nss_ckmdFindSessionObjects_Next
+ */
+
+struct nodeStr {
+ struct nodeStr *next;
+ NSSCKMDObject *mdObject;
+};
+
+struct nssCKMDFindSessionObjectsStr {
+ NSSArena *arena;
+ CK_RV error;
+ CK_ATTRIBUTE_PTR pTemplate;
+ CK_ULONG ulCount;
+ struct nodeStr *list;
+ nssCKFWHash *hash;
+
+};
+typedef struct nssCKMDFindSessionObjectsStr nssCKMDFindSessionObjects;
+
+#ifdef DEBUG
+/*
+ * But first, the pointer-tracking stuff.
+ *
+ * NOTE: the pointer-tracking support in NSS/base currently relies
+ * upon NSPR's CallOnce support. That, however, relies upon NSPR's
+ * locking, which is tied into the runtime. We need a pointer-tracker
+ * implementation that uses the locks supplied through C_Initialize.
+ * That support, however, can be filled in later. So for now, I'll
+ * just do this routines as no-ops.
+ */
+
+static CK_RV
+nss_ckmdFindSessionObjects_add_pointer
+(
+ const NSSCKMDFindObjects *mdFindObjects
+)
+{
+ return CKR_OK;
+}
+
+static CK_RV
+nss_ckmdFindSessionObjects_remove_pointer
+(
+ const NSSCKMDFindObjects *mdFindObjects
+)
+{
+ return CKR_OK;
+}
+
+static CK_RV
+nss_ckmdFindSessionObjects_verifyPointer
+(
+ const NSSCKMDFindObjects *mdFindObjects
+)
+{
+ return CKR_OK;
+}
+
+#endif /* DEBUG */
+
+/*
+ * We must forward-declare these routines.
+ */
+static void
+nss_ckmdFindSessionObjects_Final
+(
+ NSSCKMDFindObjects *mdFindObjects,
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+);
+
+static NSSCKMDObject *
+nss_ckmdFindSessionObjects_Next
+(
+ NSSCKMDFindObjects *mdFindObjects,
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError
+);
+
+/*
+ * This (or something like it) should be in ../base or something.
+ */
+static int
+attributes_match
+(
+ NSSItem *a,
+ void *b_data,
+ CK_ULONG b_size
+)
+{
+ if( a->size != b_size ) {
+ return 0;
+ }
+
+ if( PR_TRUE == nsslibc_memequal(a->data, b->data, a->size, (PRStatus *)NULL) ) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static CK_BBOOL
+items_match
+(
+ NSSItem *a,
+ CK_VOID_PTR pValue,
+ CK_ULONG ulValueLen
+)
+{
+ return CK_FALSE; /* XXX fgmr 19990517 rush to compile.. */
+}
+
+/*
+ * Our hashtable iterator
+ */
+static void
+findfcn
+(
+ const void *key,
+ void *value,
+ void *closure
+)
+{
+ NSSCKMDObject *mdObject = (NSSCKMDObject *)value;
+ nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)mdObject->etc;
+ nssCKMDFindSessionObjects *mdfso = (nssCKMDFindSessionObjects *)closure;
+ CK_ULONG i, j;
+ struct nodeStr *node;
+
+ if( CKR_OK != mdfso->error ) {
+ return;
+ }
+
+ for( i = 0; i < mdfso->ulCount; i++ ) {
+ CK_ATTRIBUTE_PTR p = &mdfso->pTemplate[i];
+
+ for( j = 0; j < mdso->n; j++ ) {
+ if( mdso->types[j] == p->type ) {
+ if( !items_match(&mdso->attributes[j], p->pValue, p->ulValueLen) ) {
+ return;
+ }
+ }
+ }
+
+ if( j == mdso->n ) {
+ /* Attribute not found */
+ return;
+ }
+ }
+
+ /* Matches */
+ node = nss_ZNEW(mdfso->arena, struct nodeStr);
+ if( (struct nodeStr *)NULL == node ) {
+ mdfso->error = CKR_HOST_MEMORY;
+ return;
+ }
+
+ node->mdObject = mdObject;
+ node->next = mdfso->list;
+ mdfso->list = node;
+
+ return;
+}
+
+/*
+ * nssCKMDFindSessionObjects_Create
+ *
+ */
+NSS_IMPLEMENT NSSCKMDFindObjects *
+nssCKMDFindSessionObjects_Create
+(
+ NSSCKFWToken *fwToken,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_RV *pError
+)
+{
+ NSSArena *arena;
+ nssCKMDFindSessionObjects *mdfso;
+ nssCKFWHash *hash;
+ NSSCKMDFindObjects *rv;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKMDFindObjects *)NULL;
+ }
+
+ *pError = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != *pError ) {
+ return (NSSCKMDFindObjects *)NULL;
+ }
+
+ if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSCKMDFindObjects *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ hash = nssCKFWToken_GetSessionObjectHash(fwToken);
+ if( (nssCKFWHash *)NULL == hash ) {
+ *pError= CKR_GENERAL_ERROR;
+ return (NSSCKMDFindObjects *)NULL;
+ }
+
+ arena = NSSArena_Create();
+ if( (NSSArena *)NULL == arena ) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKMDFindObjects *)NULL;
+ }
+
+ mdfso = nss_ZNEW(arena, nssCKMDFindSessionObjects);
+ if( (nssCKMDFindSessionObjects *)NULL == mdfso ) {
+ NSSArena_Destroy(arena);
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKMDFindObjects *)NULL;
+ }
+
+ rv = nss_ZNEW(arena, NSSCKMDFindObjects);
+
+ mdfso->error = CKR_OK;
+ mdfso->pTemplate = pTemplate;
+ mdfso->ulCount = ulCount;
+ mdfso->hash = hash;
+
+ nssCKFWHash_Iterate(hash, findfcn, mdfso);
+
+ if( CKR_OK != mdfso->error ) {
+ NSSArena_Destroy(arena);
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKMDFindObjects *)NULL;
+ }
+
+ rv->etc = (void *)mdfso;
+ rv->Final = nss_ckmdFindSessionObjects_Final;
+ rv->Next = nss_ckmdFindSessionObjects_Next;
+
+#ifdef DEBUG
+ if( *pError != nss_ckmdFindSessionObjects_add_pointer(rv) ) {
+ NSSArena_Destroy(arena);
+ return (NSSCKMDFindObjects *)NULL;
+ }
+#endif /* DEBUG */
+
+ return rv;
+}
+
+static void
+nss_ckmdFindSessionObjects_Final
+(
+ NSSCKMDFindObjects *mdFindObjects,
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance
+)
+{
+ nssCKMDFindSessionObjects *mdfso;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) {
+ return;
+ }
+#endif /* NSSDEBUG */
+
+ mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
+ NSSArena_Destroy(mdfso->arena);
+
+#ifdef DEBUG
+ (void)nss_ckmdFindSessionObjects_remove_pointer(mdFindObjects);
+#endif /* DEBUG */
+
+ return;
+}
+
+static NSSCKMDObject *
+nss_ckmdFindSessionObjects_Next
+(
+ NSSCKMDFindObjects *mdFindObjects,
+ NSSCKFWFindObjects *fwFindObjects,
+ NSSCKMDSession *mdSession,
+ NSSCKFWSession *fwSession,
+ NSSCKMDToken *mdToken,
+ NSSCKFWToken *fwToken,
+ NSSCKMDInstance *mdInstance,
+ NSSCKFWInstance *fwInstance,
+ NSSArena *arena,
+ CK_RV *pError
+)
+{
+ nssCKMDFindSessionObjects *mdfso;
+ nssCKFWHash *hash;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) {
+ return (NSSCKMDObject *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
+
+ while( 1 ) {
+ if( (struct nodeStr *)NULL == mdfso->list ) {
+ *pError = CKR_OK;
+ return (NSSCKMDObject *)NULL;
+ }
+
+ if( nssCKFWHash_Exists(mdfso->hash, mdfso->list->mdObject) ) {
+ break;
+ }
+
+ mdfso->list = mdfso->list->next;
+ }
+
+ return mdfso->list->mdObject;
+}
diff --git a/security/nss/lib/ckfw/slot.c b/security/nss/lib/ckfw/slot.c
new file mode 100644
index 000000000..a8426c561
--- /dev/null
+++ b/security/nss/lib/ckfw/slot.c
@@ -0,0 +1,752 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * slot.c
+ *
+ * This file implements the NSSCKFWSlot type and methods.
+ */
+
+#ifndef CK_T
+#include "ck.h"
+#endif /* CK_T */
+
+/*
+ * NSSCKFWSlot
+ *
+ * -- create/destroy --
+ * nssCKFWSlot_Create
+ * nssCKFWSlot_Destroy
+ *
+ * -- public accessors --
+ * NSSCKFWSlot_GetMDSlot
+ * NSSCKFWSlot_GetFWInstance
+ * NSSCKFWSlot_GetMDInstance
+ *
+ * -- implement public accessors --
+ * nssCKFWSlot_GetMDSlot
+ * nssCKFWSlot_GetFWInstance
+ * nssCKFWSlot_GetMDInstance
+ *
+ * -- private accessors --
+ * nssCKFWSlot_GetSlotID
+ * nssCKFWSlot_ClearToken
+ *
+ * -- module fronts --
+ * nssCKFWSlot_GetSlotDescription
+ * nssCKFWSlot_GetManufacturerID
+ * nssCKFWSlot_GetTokenPresent
+ * nssCKFWSlot_GetRemovableDevice
+ * nssCKFWSlot_GetHardwareSlot
+ * nssCKFWSlot_GetHardwareVersion
+ * nssCKFWSlot_GetFirmwareVersion
+ * nssCKFWSlot_InitToken
+ * nssCKFWSlot_GetToken
+ */
+
+struct NSSCKFWSlotStr {
+ NSSCKFWMutex *mutex;
+ NSSCKMDSlot *mdSlot;
+ NSSCKFWInstance *fwInstance;
+ NSSCKMDInstance *mdInstance;
+ CK_SLOT_ID slotID;
+
+ /*
+ * Everything above is set at creation time, and then not modified.
+ * The invariants the mutex protects are:
+ *
+ * 1) Each of the cached descriptions (versions, etc.) are in an
+ * internally consistant state.
+ *
+ * 2) The fwToken points to the token currently in the slot, and
+ * it is in a consistant state.
+ *
+ * Note that the calls accessing the cached descriptions will
+ * call the NSSCKMDSlot methods with the mutex locked. Those
+ * methods may then call the public NSSCKFWSlot routines. Those
+ * public routines only access the constant data above, so there's
+ * no problem. But be careful if you add to this object; mutexes
+ * are in general not reentrant, so don't create deadlock situations.
+ */
+
+ NSSUTF8 *slotDescription;
+ NSSUTF8 *manufacturerID;
+ CK_VERSION hardwareVersion;
+ CK_VERSION firmwareVersion;
+ NSSCKFWToken *fwToken;
+};
+
+#ifdef DEBUG
+/*
+ * But first, the pointer-tracking stuff.
+ *
+ * NOTE: the pointer-tracking support in NSS/base currently relies
+ * upon NSPR's CallOnce support. That, however, relies upon NSPR's
+ * locking, which is tied into the runtime. We need a pointer-tracker
+ * implementation that uses the locks supplied through C_Initialize.
+ * That support, however, can be filled in later. So for now, I'll
+ * just do this routines as no-ops.
+ */
+
+static CK_RV
+slot_add_pointer
+(
+ const NSSCKFWSlot *fwSlot
+)
+{
+ return CKR_OK;
+}
+
+static CK_RV
+slot_remove_pointer
+(
+ const NSSCKFWSlot *fwSlot
+)
+{
+ return CKR_OK;
+}
+
+NSS_IMPLEMENT CK_RV
+nssCKFWSlot_verifyPointer
+(
+ const NSSCKFWSlot *fwSlot
+)
+{
+ return CKR_OK;
+}
+
+#endif /* DEBUG */
+
+/*
+ * nssCKFWSlot_Create
+ *
+ */
+NSS_IMPLEMENT NSSCKFWSlot *
+nssCKFWSlot_Create
+(
+ NSSCKFWInstance *fwInstance,
+ NSSCKMDSlot *mdSlot,
+ CK_SLOT_ID slotID,
+ CK_RV *pError
+)
+{
+ NSSCKFWSlot *fwSlot;
+ NSSCKMDInstance *mdInstance;
+ NSSArena *arena;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWSlot *)NULL;
+ }
+
+ *pError = nssCKFWInstance_verifyPointer(fwInstance);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWSlot *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
+ if( (NSSCKMDInstance *)NULL == mdInstance ) {
+ *pError = CKR_GENERAL_ERROR;
+ return (NSSCKFWSlot *)NULL;
+ }
+
+ arena = nssCKFWInstance_GetArena(fwInstance, pError);
+ if( (NSSArena *)NULL == arena ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ }
+
+ fwSlot = nss_ZNEW(arena, NSSCKFWSlot);
+ if( (NSSCKFWSlot *)NULL == fwSlot ) {
+ *pError = CKR_HOST_MEMORY;
+ return (NSSCKFWSlot *)NULL;
+ }
+
+ fwSlot->mdSlot = mdSlot;
+ fwSlot->fwInstance = fwInstance;
+ fwSlot->mdInstance = mdInstance;
+ fwSlot->slotID = slotID;
+
+ fwSlot->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
+ if( (NSSCKFWMutex *)NULL == fwSlot->mutex ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ (void)nss_ZFreeIf(fwSlot);
+ return (NSSCKFWSlot *)NULL;
+ }
+
+ if( (void *)NULL != (void *)mdSlot->Initialize ) {
+ *pError = CKR_OK;
+ *pError = mdSlot->Initialize(mdSlot, fwSlot, mdInstance, fwInstance);
+ if( CKR_OK != *pError ) {
+ (void)nssCKFWMutex_Destroy(fwSlot->mutex);
+ (void)nss_ZFreeIf(fwSlot);
+ return (NSSCKFWSlot *)NULL;
+ }
+ }
+
+#ifdef DEBUG
+ *pError = slot_add_pointer(fwSlot);
+ if( CKR_OK != *pError ) {
+ if( (void *)NULL != (void *)mdSlot->Destroy ) {
+ mdSlot->Destroy(mdSlot, fwSlot, mdInstance, fwInstance);
+ }
+
+ (void)nssCKFWMutex_Destroy(fwSlot->mutex);
+ (void)nss_ZFreeIf(fwSlot);
+ return (NSSCKFWSlot *)NULL;
+ }
+#endif /* DEBUG */
+
+ return fwSlot;
+}
+
+/*
+ * nssCKFWSlot_Destroy
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSlot_Destroy
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWSlot_verifyPointer(fwSlot);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ (void)nssCKFWMutex_Destroy(fwSlot->mutex);
+
+ if( (void *)NULL != (void *)fwSlot->mdSlot->Destroy ) {
+ fwSlot->mdSlot->Destroy(fwSlot->mdSlot, fwSlot,
+ fwSlot->mdInstance, fwSlot->fwInstance);
+ }
+
+#ifdef DEBUG
+ error = slot_remove_pointer(fwSlot);
+#endif /* DEBUG */
+ (void)nss_ZFreeIf(fwSlot);
+ return error;
+}
+
+/*
+ * nssCKFWSlot_GetMDSlot
+ *
+ */
+NSS_IMPLEMENT NSSCKMDSlot *
+nssCKFWSlot_GetMDSlot
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ return (NSSCKMDSlot *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwSlot->mdSlot;
+}
+
+/*
+ * nssCKFWSlot_GetFWInstance
+ *
+ */
+
+NSS_IMPLEMENT NSSCKFWInstance *
+nssCKFWSlot_GetFWInstance
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ return (NSSCKFWInstance *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwSlot->fwInstance;
+}
+
+/*
+ * nssCKFWSlot_GetMDInstance
+ *
+ */
+
+NSS_IMPLEMENT NSSCKMDInstance *
+nssCKFWSlot_GetMDInstance
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ return (NSSCKMDInstance *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwSlot->mdInstance;
+}
+
+/*
+ * nssCKFWSlot_GetSlotID
+ *
+ */
+NSS_IMPLEMENT CK_SLOT_ID
+nssCKFWSlot_GetSlotID
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ return (CK_SLOT_ID)0;
+ }
+#endif /* NSSDEBUG */
+
+ return fwSlot->slotID;
+}
+
+/*
+ * nssCKFWSlot_GetSlotDescription
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSlot_GetSlotDescription
+(
+ NSSCKFWSlot *fwSlot,
+ CK_CHAR slotDescription[64]
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ if( (CK_CHAR_PTR)NULL == slotDescription ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ error = nssCKFWSlot_verifyPointer(fwSlot);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwSlot->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (NSSUTF8 *)NULL == fwSlot->slotDescription ) {
+ if( (void *)NULL != (void *)fwSlot->mdSlot->GetSlotDescription ) {
+ fwSlot->slotDescription = fwSlot->mdSlot->GetSlotDescription(
+ fwSlot->mdSlot, fwSlot, fwSlot->mdInstance,
+ fwSlot->fwInstance, &error);
+ if( ((NSSUTF8 *)NULL == fwSlot->slotDescription) && (CKR_OK != error) ) {
+ goto done;
+ }
+ } else {
+ fwSlot->slotDescription = "";
+ }
+ }
+
+ (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->slotDescription, slotDescription, 64, ' ');
+ error = CKR_OK;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwSlot->mutex);
+ return error;
+}
+
+/*
+ * nssCKFWSlot_GetManufacturerID
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWSlot_GetManufacturerID
+(
+ NSSCKFWSlot *fwSlot,
+ CK_CHAR manufacturerID[32]
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ if( (CK_CHAR_PTR)NULL == manufacturerID ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ error = nssCKFWSlot_verifyPointer(fwSlot);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwSlot->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (NSSUTF8 *)NULL == fwSlot->manufacturerID ) {
+ if( (void *)NULL != (void *)fwSlot->mdSlot->GetManufacturerID ) {
+ fwSlot->manufacturerID = fwSlot->mdSlot->GetManufacturerID(
+ fwSlot->mdSlot, fwSlot, fwSlot->mdInstance,
+ fwSlot->fwInstance, &error);
+ if( ((NSSUTF8 *)NULL == fwSlot->manufacturerID) && (CKR_OK != error) ) {
+ goto done;
+ }
+ } else {
+ fwSlot->manufacturerID = "";
+ }
+ }
+
+ (void)nssUTF8_CopyIntoFixedBuffer(fwSlot->manufacturerID, manufacturerID, 32, ' ');
+ error = CKR_OK;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwSlot->mutex);
+ return error;
+}
+
+/*
+ * nssCKFWSlot_GetTokenPresent
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWSlot_GetTokenPresent
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwSlot->mdSlot->GetTokenPresent ) {
+ return CK_TRUE;
+ }
+
+ return fwSlot->mdSlot->GetTokenPresent(fwSlot->mdSlot, fwSlot,
+ fwSlot->mdInstance, fwSlot->fwInstance);
+}
+
+/*
+ * nssCKFWSlot_GetRemovableDevice
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWSlot_GetRemovableDevice
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwSlot->mdSlot->GetRemovableDevice ) {
+ return CK_FALSE;
+ }
+
+ return fwSlot->mdSlot->GetRemovableDevice(fwSlot->mdSlot, fwSlot,
+ fwSlot->mdInstance, fwSlot->fwInstance);
+}
+
+/*
+ * nssCKFWSlot_GetHardwareSlot
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWSlot_GetHardwareSlot
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwSlot->mdSlot->GetHardwareSlot ) {
+ return CK_FALSE;
+ }
+
+ return fwSlot->mdSlot->GetHardwareSlot(fwSlot->mdSlot, fwSlot,
+ fwSlot->mdInstance, fwSlot->fwInstance);
+}
+
+/*
+ * nssCKFWSlot_GetHardwareVersion
+ *
+ */
+NSS_IMPLEMENT CK_VERSION
+nssCKFWSlot_GetHardwareVersion
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+ CK_VERSION rv;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ rv.major = rv.minor = 0;
+ return rv;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
+ rv.major = rv.minor = 0;
+ return rv;
+ }
+
+ if( (0 != fwSlot->hardwareVersion.major) ||
+ (0 != fwSlot->hardwareVersion.minor) ) {
+ rv = fwSlot->hardwareVersion;
+ goto done;
+ }
+
+ if( (void *)NULL != (void *)fwSlot->mdSlot->GetHardwareVersion ) {
+ fwSlot->hardwareVersion = fwSlot->mdSlot->GetHardwareVersion(
+ fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, fwSlot->fwInstance);
+ } else {
+ fwSlot->hardwareVersion.major = 0;
+ fwSlot->hardwareVersion.minor = 1;
+ }
+
+ rv = fwSlot->hardwareVersion;
+ done:
+ (void)nssCKFWMutex_Unlock(fwSlot->mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWSlot_GetFirmwareVersion
+ *
+ */
+NSS_IMPLEMENT CK_VERSION
+nssCKFWSlot_GetFirmwareVersion
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+ CK_VERSION rv;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ rv.major = rv.minor = 0;
+ return rv;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
+ rv.major = rv.minor = 0;
+ return rv;
+ }
+
+ if( (0 != fwSlot->firmwareVersion.major) ||
+ (0 != fwSlot->firmwareVersion.minor) ) {
+ rv = fwSlot->firmwareVersion;
+ goto done;
+ }
+
+ if( (void *)NULL != (void *)fwSlot->mdSlot->GetFirmwareVersion ) {
+ fwSlot->firmwareVersion = fwSlot->mdSlot->GetFirmwareVersion(
+ fwSlot->mdSlot, fwSlot, fwSlot->mdInstance, fwSlot->fwInstance);
+ } else {
+ fwSlot->firmwareVersion.major = 0;
+ fwSlot->firmwareVersion.minor = 1;
+ }
+
+ rv = fwSlot->firmwareVersion;
+ done:
+ (void)nssCKFWMutex_Unlock(fwSlot->mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWSlot_GetToken
+ *
+ */
+NSS_IMPLEMENT NSSCKFWToken *
+nssCKFWSlot_GetToken
+(
+ NSSCKFWSlot *fwSlot,
+ CK_RV *pError
+)
+{
+ NSSCKMDToken *mdToken;
+ NSSCKFWToken *fwToken;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWToken *)NULL;
+ }
+
+ *pError = nssCKFWSlot_verifyPointer(fwSlot);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWToken *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ *pError = nssCKFWMutex_Lock(fwSlot->mutex);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWToken *)NULL;
+ }
+
+ if( (NSSCKFWToken *)NULL == fwSlot->fwToken ) {
+ if( (void *)NULL == (void *)fwSlot->mdSlot->GetToken ) {
+ *pError = CKR_GENERAL_ERROR;
+ fwToken = (NSSCKFWToken *)NULL;
+ goto done;
+ }
+
+ mdToken = fwSlot->mdSlot->GetToken(fwSlot->mdSlot, fwSlot,
+ fwSlot->mdInstance, fwSlot->fwInstance, pError);
+ if( (NSSCKMDToken *)NULL == mdToken ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ return (NSSCKFWToken *)NULL;
+ }
+
+ fwToken = nssCKFWToken_Create(fwSlot, mdToken, pError);
+ } else {
+ fwToken = fwSlot->fwToken;
+ }
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwSlot->mutex);
+ return fwToken;
+}
+
+/*
+ * nssCKFWSlot_ClearToken
+ *
+ */
+NSS_IMPLEMENT void
+nssCKFWSlot_ClearToken
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ return;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwSlot->mutex) ) {
+ /* Now what? */
+ return;
+ }
+
+ fwSlot->fwToken = (NSSCKFWToken *)NULL;
+ (void)nssCKFWMutex_Unlock(fwSlot->mutex);
+ return;
+}
+
+/*
+ * NSSCKFWSlot_GetMDSlot
+ *
+ */
+
+NSS_IMPLEMENT NSSCKMDSlot *
+NSSCKFWSlot_GetMDSlot
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ return (NSSCKMDSlot *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWSlot_GetMDSlot(fwSlot);
+}
+
+/*
+ * NSSCKFWSlot_GetFWInstance
+ *
+ */
+
+NSS_IMPLEMENT NSSCKFWInstance *
+NSSCKFWSlot_GetFWInstance
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ return (NSSCKFWInstance *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWSlot_GetFWInstance(fwSlot);
+}
+
+/*
+ * NSSCKFWSlot_GetMDInstance
+ *
+ */
+
+NSS_IMPLEMENT NSSCKMDInstance *
+NSSCKFWSlot_GetMDInstance
+(
+ NSSCKFWSlot *fwSlot
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWSlot_verifyPointer(fwSlot) ) {
+ return (NSSCKMDInstance *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWSlot_GetMDInstance(fwSlot);
+}
diff --git a/security/nss/lib/ckfw/token.c b/security/nss/lib/ckfw/token.c
new file mode 100644
index 000000000..44e84b8c7
--- /dev/null
+++ b/security/nss/lib/ckfw/token.c
@@ -0,0 +1,1859 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * token.c
+ *
+ * This file implements the NSSCKFWToken type and methods.
+ */
+
+#ifndef CK_T
+#include "ck.h"
+#endif /* CK_T */
+
+/*
+ * NSSCKFWToken
+ *
+ * -- create/destroy --
+ * nssCKFWToken_Create
+ * nssCKFWToken_Destroy
+ *
+ * -- public accessors --
+ * NSSCKFWToken_GetMDToken
+ * NSSCKFWToken_GetFWSlot
+ * NSSCKFWToken_GetMDSlot
+ * NSSCKFWToken_GetSessionState
+ *
+ * -- implement public accessors --
+ * nssCKFWToken_GetMDToken
+ * nssCKFWToken_GetFWSlot
+ * nssCKFWToken_GetMDSlot
+ * nssCKFWToken_GetSessionState
+ * nssCKFWToken_SetSessionState
+ *
+ * -- private accessors --
+ * nssCKFWToken_SetSessionState
+ * nssCKFWToken_RemoveSession
+ * nssCKFWToken_CloseAllSessions
+ * nssCKFWToken_GetSessionCount
+ * nssCKFWToken_GetRwSessionCount
+ * nssCKFWToken_GetRoSessionCount
+ * nssCKFWToken_GetSessionObjectHash
+ * nssCKFWToken_GetMDObjectHash
+ * nssCKFWToken_GetObjectHandleHash
+ *
+ * -- module fronts --
+ * nssCKFWToken_InitToken
+ * nssCKFWToken_GetLabel
+ * nssCKFWToken_GetManufacturerID
+ * nssCKFWToken_GetModel
+ * nssCKFWToken_GetSerialNumber
+ * nssCKFWToken_GetHasRNG
+ * nssCKFWToken_GetIsWriteProtected
+ * nssCKFWToken_GetLoginRequired
+ * nssCKFWToken_GetUserPinInitialized
+ * nssCKFWToken_GetRestoreKeyNotNeeded
+ * nssCKFWToken_GetHasClockOnToken
+ * nssCKFWToken_GetHasProtectedAuthenticationPath
+ * nssCKFWToken_GetSupportsDualCryptoOperations
+ * nssCKFWToken_GetMaxSessionCount
+ * nssCKFWToken_GetMaxRwSessionCount
+ * nssCKFWToken_GetMaxPinLen
+ * nssCKFWToken_GetMinPinLen
+ * nssCKFWToken_GetTotalPublicMemory
+ * nssCKFWToken_GetFreePublicMemory
+ * nssCKFWToken_GetTotalPrivateMemory
+ * nssCKFWToken_GetFreePrivateMemory
+ * nssCKFWToken_GetHardwareVersion
+ * nssCKFWToken_GetFirmwareVersion
+ * nssCKFWToken_GetUTCTime
+ * nssCKFWToken_OpenSession
+ * nssCKFWToken_GetMechanismCount
+ * nssCKFWToken_GetMechanismTypes
+ * nssCKFWToken_GetMechanism
+ */
+
+struct NSSCKFWTokenStr {
+ NSSCKFWMutex *mutex;
+ NSSArena *arena;
+ NSSCKMDToken *mdToken;
+ NSSCKFWSlot *fwSlot;
+ NSSCKMDSlot *mdSlot;
+ NSSCKFWInstance *fwInstance;
+ NSSCKMDInstance *mdInstance;
+
+ /*
+ * Everything above is set at creation time, and then not modified.
+ * The invariants the mutex protects are:
+ *
+ * 1) Each of the cached descriptions (versions, etc.) are in an
+ * internally consistant state.
+ *
+ * 2) The session counts and hashes are consistant.
+ *
+ * 3) The object hashes are consistant.
+ *
+ * Note that the calls accessing the cached descriptions will call
+ * the NSSCKMDToken methods with the mutex locked. Those methods
+ * may then call the public NSSCKFWToken routines. Those public
+ * routines only access the constant data above and the atomic
+ * CK_STATE session state variable below, so there's no problem.
+ * But be careful if you add to this object; mutexes are in
+ * general not reentrant, so don't create deadlock situations.
+ */
+
+ NSSUTF8 *label;
+ NSSUTF8 *manufacturerID;
+ NSSUTF8 *model;
+ NSSUTF8 *serialNumber;
+ CK_VERSION hardwareVersion;
+ CK_VERSION firmwareVersion;
+
+ CK_ULONG sessionCount;
+ CK_ULONG rwSessionCount;
+ nssCKFWHash *sessions;
+ nssCKFWHash *sessionObjectHash;
+ nssCKFWHash *mdObjectHash;
+
+ CK_STATE state;
+};
+
+#ifdef DEBUG
+/*
+ * But first, the pointer-tracking stuff.
+ *
+ * NOTE: the pointer-tracking support in NSS/base currently relies
+ * upon NSPR's CallOnce support. That, however, relies upon NSPR's
+ * locking, which is tied into the runtime. We need a pointer-tracker
+ * implementation that uses the locks supplied through C_Initialize.
+ * That support, however, can be filled in later. So for now, I'll
+ * just do this routines as no-ops.
+ */
+
+static CK_RV
+token_add_pointer
+(
+ const NSSCKFWToken *fwToken
+)
+{
+ return CKR_OK;
+}
+
+static CK_RV
+token_remove_pointer
+(
+ const NSSCKFWToken *fwToken
+)
+{
+ return CKR_OK;
+}
+
+NSS_IMPLEMENT CK_RV
+nssCKFWToken_verifyPointer
+(
+ const NSSCKFWToken *fwToken
+)
+{
+ return CKR_OK;
+}
+
+#endif /* DEBUG */
+
+/*
+ * nssCKFWToken_Create
+ *
+ */
+NSS_IMPLEMENT NSSCKFWToken *
+nssCKFWToken_Create
+(
+ NSSCKFWSlot *fwSlot,
+ NSSCKMDToken *mdToken,
+ CK_RV *pError
+)
+{
+ NSSArena *arena = (NSSArena *)NULL;
+ NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
+ CK_BBOOL called_setup = CK_FALSE;
+
+ /*
+ * We have already verified the arguments in nssCKFWSlot_GetToken.
+ */
+
+ arena = NSSArena_Create();
+ if( (NSSArena *)NULL == arena ) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ fwToken = nss_ZNEW(arena, NSSCKFWToken);
+ if( (NSSCKFWToken *)NULL == fwToken ) {
+ *pError = CKR_HOST_MEMORY;
+ goto loser;
+ }
+
+ fwToken->arena = arena;
+ fwToken->mdToken = mdToken;
+ fwToken->fwSlot = fwSlot;
+ fwToken->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
+ fwToken->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
+ fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
+ fwToken->sessionCount = 0;
+ fwToken->rwSessionCount = 0;
+
+ fwToken->mutex = nssCKFWInstance_CreateMutex(fwToken->fwInstance, arena, pError);
+ if( (NSSCKFWMutex *)NULL == fwToken->mutex ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ goto loser;
+ }
+
+ fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, arena, pError);
+ if( (nssCKFWHash *)NULL == fwToken->sessions ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ goto loser;
+ }
+
+ if( CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
+ fwToken->fwInstance) ) {
+ fwToken->sessionObjectHash = nssCKFWHash_Create(fwToken->fwInstance,
+ arena, pError);
+ if( (nssCKFWHash *)NULL == fwToken->sessionObjectHash ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ goto loser;
+ }
+ }
+
+ fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance,
+ arena, pError);
+ if( (nssCKFWHash *)NULL == fwToken->mdObjectHash ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ goto loser;
+ }
+
+ fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance,
+ arena, pError);
+ if( (nssCKFWHash *)NULL == fwToken->mdObjectHash ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ goto loser;
+ }
+
+ /* More here */
+
+ if( (void *)NULL != (void *)mdToken->Setup ) {
+ *pError = mdToken->Setup(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
+ if( CKR_OK != *pError ) {
+ goto loser;
+ }
+ }
+
+ called_setup = CK_TRUE;
+
+#ifdef DEBUG
+ *pError = token_add_pointer(fwToken);
+ if( CKR_OK != *pError ) {
+ goto loser;
+ }
+#endif /* DEBUG */
+
+ *pError = CKR_OK;
+ return fwToken;
+
+ loser:
+
+ if( CK_TRUE == called_setup ) {
+ if( (void *)NULL != (void *)mdToken->Invalidate ) {
+ mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
+ }
+ }
+
+ if( (NSSArena *)NULL != arena ) {
+ (void)NSSArena_Destroy(arena);
+ }
+
+ return (NSSCKFWToken *)NULL;
+}
+
+/*
+ * nssCKFWToken_Destroy
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWToken_Destroy
+(
+ NSSCKFWToken *fwToken
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ (void)nssCKFWMutex_Destroy(fwToken->mutex);
+
+ if( (void *)NULL != (void *)fwToken->mdToken->Invalidate ) {
+ fwToken->mdToken->Invalidate(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+ }
+
+ nssCKFWSlot_ClearToken(fwToken->fwSlot);
+
+#ifdef DEBUG
+ error = token_remove_pointer(fwToken);
+#endif /* DEBUG */
+
+ (void)NSSArena_Destroy(fwToken->arena);
+ return error;
+}
+
+/*
+ * nssCKFWToken_GetMDToken
+ *
+ */
+NSS_IMPLEMENT NSSCKMDToken *
+nssCKFWToken_GetMDToken
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return (NSSCKMDToken *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwToken->mdToken;
+}
+
+/*
+ * nssCKFWToken_GetArena
+ *
+ */
+NSS_IMPLEMENT NSSArena *
+nssCKFWToken_GetArena
+(
+ NSSCKFWToken *fwToken,
+ CK_RV *pError
+)
+{
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSArena *)NULL;
+ }
+
+ *pError = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != *pError ) {
+ return (NSSArena *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwToken->arena;
+}
+
+/*
+ * nssCKFWToken_GetFWSlot
+ *
+ */
+NSS_IMPLEMENT NSSCKFWSlot *
+nssCKFWToken_GetFWSlot
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return (NSSCKFWSlot *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwToken->fwSlot;
+}
+
+/*
+ * nssCKFWToken_GetMDSlot
+ *
+ */
+NSS_IMPLEMENT NSSCKMDSlot *
+nssCKFWToken_GetMDSlot
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return (NSSCKMDSlot *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwToken->mdSlot;
+}
+
+/*
+ * nssCKFWToken_GetSessionState
+ *
+ */
+NSS_IMPLEMENT CK_STATE
+nssCKFWToken_GetSessionState
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CKS_RO_PUBLIC_SESSION; /* whatever */
+ }
+#endif /* NSSDEBUG */
+
+ /*
+ * BTW, do not lock the token in this method.
+ */
+
+ /*
+ * Theoretically, there is no state if there aren't any
+ * sessions open. But then we'd need to worry about
+ * reporting an error, etc. What the heck-- let's just
+ * revert to CKR_RO_PUBLIC_SESSION as the "default."
+ */
+
+ return fwToken->state;
+}
+
+/*
+ * nssCKFWToken_InitToken
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWToken_InitToken
+(
+ NSSCKFWToken *fwToken,
+ NSSItem *pin,
+ NSSUTF8 *label
+)
+{
+ CK_RV error;
+
+#ifdef NSSDEBUG
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != error ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwToken->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( fwToken->sessionCount > 0 ) {
+ error = CKR_SESSION_EXISTS;
+ goto done;
+ }
+
+ if( (void *)NULL == (void *)fwToken->mdToken->InitToken ) {
+ error = CKR_DEVICE_ERROR;
+ goto done;
+ }
+
+ if( (NSSItem *)NULL == pin ) {
+ if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) {
+ ; /* okay */
+ } else {
+ error = CKR_PIN_INCORRECT;
+ goto done;
+ }
+ }
+
+ if( (NSSUTF8 *)NULL == label ) {
+ label = "";
+ }
+
+ error = fwToken->mdToken->InitToken(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance, pin, label);
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
+}
+
+/*
+ * nssCKFWToken_GetLabel
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWToken_GetLabel
+(
+ NSSCKFWToken *fwToken,
+ CK_CHAR label[32]
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ if( (CK_CHAR_PTR)NULL == label ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwToken->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (NSSUTF8 *)NULL == fwToken->label ) {
+ if( (void *)NULL != (void *)fwToken->mdToken->GetLabel ) {
+ fwToken->label = fwToken->mdToken->GetLabel(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance, &error);
+ if( ((NSSUTF8 *)NULL == fwToken->label) && (CKR_OK != error) ) {
+ goto done;
+ }
+ } else {
+ fwToken->label = "";
+ }
+ }
+
+ (void)nssUTF8_CopyIntoFixedBuffer(fwToken->label, label, 32, ' ');
+ error = CKR_OK;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
+}
+
+/*
+ * nssCKFWToken_GetManufacturerID
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWToken_GetManufacturerID
+(
+ NSSCKFWToken *fwToken,
+ CK_CHAR manufacturerID[32]
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ if( (CK_CHAR_PTR)NULL == manufacturerID ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwToken->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (NSSUTF8 *)NULL == fwToken->manufacturerID ) {
+ if( (void *)NULL != (void *)fwToken->mdToken->GetManufacturerID ) {
+ fwToken->manufacturerID = fwToken->mdToken->GetManufacturerID(fwToken->mdToken,
+ fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
+ if( ((NSSUTF8 *)NULL == fwToken->manufacturerID) && (CKR_OK != error) ) {
+ goto done;
+ }
+ } else {
+ fwToken->manufacturerID = "";
+ }
+ }
+
+ (void)nssUTF8_CopyIntoFixedBuffer(fwToken->manufacturerID, manufacturerID, 32, ' ');
+ error = CKR_OK;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
+}
+
+/*
+ * nssCKFWToken_GetModel
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWToken_GetModel
+(
+ NSSCKFWToken *fwToken,
+ CK_CHAR model[16]
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ if( (CK_CHAR_PTR)NULL == model ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwToken->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (NSSUTF8 *)NULL == fwToken->model ) {
+ if( (void *)NULL != (void *)fwToken->mdToken->GetModel ) {
+ fwToken->model = fwToken->mdToken->GetModel(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance, &error);
+ if( ((NSSUTF8 *)NULL == fwToken->model) && (CKR_OK != error) ) {
+ goto done;
+ }
+ } else {
+ fwToken->model = "";
+ }
+ }
+
+ (void)nssUTF8_CopyIntoFixedBuffer(fwToken->model, model, 16, ' ');
+ error = CKR_OK;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
+}
+
+/*
+ * nssCKFWToken_GetSerialNumber
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWToken_GetSerialNumber
+(
+ NSSCKFWToken *fwToken,
+ CK_CHAR serialNumber[16]
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ if( (CK_CHAR_PTR)NULL == serialNumber ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwToken->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (NSSUTF8 *)NULL == fwToken->serialNumber ) {
+ if( (void *)NULL != (void *)fwToken->mdToken->GetSerialNumber ) {
+ fwToken->serialNumber = fwToken->mdToken->GetSerialNumber(fwToken->mdToken,
+ fwToken, fwToken->mdInstance, fwToken->fwInstance, &error);
+ if( ((NSSUTF8 *)NULL == fwToken->serialNumber) && (CKR_OK != error) ) {
+ goto done;
+ }
+ } else {
+ fwToken->serialNumber = "";
+ }
+ }
+
+ (void)nssUTF8_CopyIntoFixedBuffer(fwToken->serialNumber, serialNumber, 16, ' ');
+ error = CKR_OK;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
+}
+
+
+/*
+ * nssCKFWToken_GetHasRNG
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWToken_GetHasRNG
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetHasRNG ) {
+ return CK_FALSE;
+ }
+
+ return fwToken->mdToken->GetHasRNG(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetIsWriteProtected
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWToken_GetIsWriteProtected
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetIsWriteProtected ) {
+ return CK_FALSE;
+ }
+
+ return fwToken->mdToken->GetIsWriteProtected(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetLoginRequired
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWToken_GetLoginRequired
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetLoginRequired ) {
+ return CK_FALSE;
+ }
+
+ return fwToken->mdToken->GetLoginRequired(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetUserPinInitialized
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWToken_GetUserPinInitialized
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetUserPinInitialized ) {
+ return CK_FALSE;
+ }
+
+ return fwToken->mdToken->GetUserPinInitialized(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetRestoreKeyNotNeeded
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWToken_GetRestoreKeyNotNeeded
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetRestoreKeyNotNeeded ) {
+ return CK_FALSE;
+ }
+
+ return fwToken->mdToken->GetRestoreKeyNotNeeded(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetHasClockOnToken
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWToken_GetHasClockOnToken
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetHasClockOnToken ) {
+ return CK_FALSE;
+ }
+
+ return fwToken->mdToken->GetHasClockOnToken(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetHasProtectedAuthenticationPath
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWToken_GetHasProtectedAuthenticationPath
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetHasProtectedAuthenticationPath ) {
+ return CK_FALSE;
+ }
+
+ return fwToken->mdToken->GetHasProtectedAuthenticationPath(fwToken->mdToken,
+ fwToken, fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetSupportsDualCryptoOperations
+ *
+ */
+NSS_IMPLEMENT CK_BBOOL
+nssCKFWToken_GetSupportsDualCryptoOperations
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_FALSE;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetSupportsDualCryptoOperations ) {
+ return CK_FALSE;
+ }
+
+ return fwToken->mdToken->GetSupportsDualCryptoOperations(fwToken->mdToken,
+ fwToken, fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetMaxSessionCount
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWToken_GetMaxSessionCount
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetMaxSessionCount ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+
+ return fwToken->mdToken->GetMaxSessionCount(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetMaxRwSessionCount
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWToken_GetMaxRwSessionCount
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetMaxRwSessionCount ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+
+ return fwToken->mdToken->GetMaxRwSessionCount(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetMaxPinLen
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWToken_GetMaxPinLen
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetMaxPinLen ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+
+ return fwToken->mdToken->GetMaxPinLen(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetMinPinLen
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWToken_GetMinPinLen
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetMinPinLen ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+
+ return fwToken->mdToken->GetMinPinLen(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetTotalPublicMemory
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWToken_GetTotalPublicMemory
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetTotalPublicMemory ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+
+ return fwToken->mdToken->GetTotalPublicMemory(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetFreePublicMemory
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWToken_GetFreePublicMemory
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetFreePublicMemory ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+
+ return fwToken->mdToken->GetFreePublicMemory(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetTotalPrivateMemory
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWToken_GetTotalPrivateMemory
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetTotalPrivateMemory ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+
+ return fwToken->mdToken->GetTotalPrivateMemory(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetFreePrivateMemory
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWToken_GetFreePrivateMemory
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetFreePrivateMemory ) {
+ return CK_UNAVAILABLE_INFORMATION;
+ }
+
+ return fwToken->mdToken->GetFreePrivateMemory(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetHardwareVersion
+ *
+ */
+NSS_IMPLEMENT CK_VERSION
+nssCKFWToken_GetHardwareVersion
+(
+ NSSCKFWToken *fwToken
+)
+{
+ CK_VERSION rv;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ rv.major = rv.minor = 0;
+ return rv;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
+ rv.major = rv.minor = 0;
+ return rv;
+ }
+
+ if( (0 != fwToken->hardwareVersion.major) ||
+ (0 != fwToken->hardwareVersion.minor) ) {
+ rv = fwToken->hardwareVersion;
+ goto done;
+ }
+
+ if( (void *)NULL != (void *)fwToken->mdToken->GetHardwareVersion ) {
+ fwToken->hardwareVersion = fwToken->mdToken->GetHardwareVersion(
+ fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
+ } else {
+ fwToken->hardwareVersion.major = 0;
+ fwToken->hardwareVersion.minor = 1;
+ }
+
+ rv = fwToken->hardwareVersion;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWToken_GetFirmwareVersion
+ *
+ */
+NSS_IMPLEMENT CK_VERSION
+nssCKFWToken_GetFirmwareVersion
+(
+ NSSCKFWToken *fwToken
+)
+{
+ CK_VERSION rv;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ rv.major = rv.minor = 0;
+ return rv;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
+ rv.major = rv.minor = 0;
+ return rv;
+ }
+
+ if( (0 != fwToken->firmwareVersion.major) ||
+ (0 != fwToken->firmwareVersion.minor) ) {
+ rv = fwToken->firmwareVersion;
+ goto done;
+ }
+
+ if( (void *)NULL != (void *)fwToken->mdToken->GetFirmwareVersion ) {
+ fwToken->firmwareVersion = fwToken->mdToken->GetFirmwareVersion(
+ fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance);
+ } else {
+ fwToken->firmwareVersion.major = 0;
+ fwToken->firmwareVersion.minor = 1;
+ }
+
+ rv = fwToken->firmwareVersion;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWToken_GetUTCTime
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWToken_GetUTCTime
+(
+ NSSCKFWToken *fwToken,
+ CK_CHAR utcTime[16]
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( (CK_CHAR_PTR)NULL == utcTime ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+#endif /* DEBUG */
+
+ if( CK_TRUE != nssCKFWToken_GetHasClockOnToken(fwToken) ) {
+ /* return CKR_DEVICE_ERROR; */
+ (void)nssUTF8_CopyIntoFixedBuffer((NSSUTF8 *)NULL, utcTime, 16, ' ');
+ return CKR_OK;
+ }
+
+ if( (void *)NULL == (void *)fwToken->mdToken->GetUTCTime ) {
+ /* It said it had one! */
+ return CKR_GENERAL_ERROR;
+ }
+
+ error = fwToken->mdToken->GetUTCTime(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance, utcTime);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ /* Sanity-check the data */
+ {
+ /* Format is YYYYMMDDhhmmss00 */
+ int i;
+ int Y, M, D, h, m, s, z;
+ static int dims[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+ for( i = 0; i < 16; i++ ) {
+ if( (utcTime[i] < '0') || (utcTime[i] > '9') ) {
+ goto badtime;
+ }
+ }
+
+ Y = ((utcTime[ 0] - '0') * 1000) + ((utcTime[1] - '0') * 100) +
+ ((utcTime[ 2] - '0') * 10) + (utcTime[ 3] - '0');
+ M = ((utcTime[ 4] - '0') * 10) + (utcTime[ 5] - '0');
+ D = ((utcTime[ 6] - '0') * 10) + (utcTime[ 7] - '0');
+ h = ((utcTime[ 8] - '0') * 10) + (utcTime[ 9] - '0');
+ m = ((utcTime[10] - '0') * 10) + (utcTime[11] - '0');
+ s = ((utcTime[12] - '0') * 10) + (utcTime[13] - '0');
+ z = ((utcTime[14] - '0') * 10) + (utcTime[15] - '0');
+
+ if( (Y < 1990) || (Y > 3000) ) goto badtime; /* Y3K problem. heh heh heh */
+ if( (M < 1) || (M > 12) ) goto badtime;
+ if( (D < 1) || (D > 31) ) goto badtime;
+
+ if( D > dims[M-1] ) goto badtime; /* per-month check */
+ if( (2 == M) && (((Y%4)||!(Y%100))&&(Y%400)) && (D > 28) ) goto badtime; /* leap years */
+
+ if( (h < 0) || (h > 23) ) goto badtime;
+ if( (m < 0) || (m > 60) ) goto badtime;
+ if( (s < 0) || (s > 61) ) goto badtime;
+
+ /* 60m and 60 or 61s is only allowed for leap seconds. */
+ if( (60 == m) || (s >= 60) ) {
+ if( (23 != h) || (60 != m) || (s < 60) ) goto badtime;
+ /* leap seconds can only happen on June 30 or Dec 31.. I think */
+ /* if( ((6 != M) || (30 != D)) && ((12 != M) || (31 != D)) ) goto badtime; */
+ }
+ }
+
+ return CKR_OK;
+
+ badtime:
+ return CKR_GENERAL_ERROR;
+}
+
+/*
+ * nssCKFWToken_OpenSession
+ *
+ */
+NSS_IMPLEMENT NSSCKFWSession *
+nssCKFWToken_OpenSession
+(
+ NSSCKFWToken *fwToken,
+ CK_BBOOL rw,
+ CK_VOID_PTR pApplication,
+ CK_NOTIFY Notify,
+ CK_RV *pError
+)
+{
+ NSSCKFWSession *fwSession = (NSSCKFWSession *)NULL;
+ NSSCKMDSession *mdSession;
+
+#ifdef NSSDEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSCKFWSession *)NULL;
+ }
+
+ *pError = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWSession *)NULL;
+ }
+
+ switch( rw ) {
+ case CK_TRUE:
+ case CK_FALSE:
+ break;
+ default:
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSCKFWSession *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ *pError = nssCKFWMutex_Lock(fwToken->mutex);
+ if( CKR_OK != *pError ) {
+ return (NSSCKFWSession *)NULL;
+ }
+
+ if( CK_TRUE == rw ) {
+ /* Read-write session desired */
+ if( CK_TRUE != nssCKFWToken_GetIsWriteProtected(fwToken) ) {
+ *pError = CKR_TOKEN_WRITE_PROTECTED;
+ goto done;
+ }
+ } else {
+ /* Read-only session desired */
+ if( CKS_RW_SO_FUNCTIONS == nssCKFWToken_GetSessionState(fwToken) ) {
+ *pError = CKR_SESSION_READ_WRITE_SO_EXISTS;
+ goto done;
+ }
+ }
+
+ /* We could compare sesion counts to any limits we know of, I guess.. */
+
+ if( (void *)NULL == (void *)fwToken->mdToken->OpenSession ) {
+ /*
+ * I'm not sure that the Module actually needs to implement
+ * mdSessions -- the Framework can keep track of everything
+ * needed, really. But I'll sort out that detail later..
+ */
+ *pError = CKR_GENERAL_ERROR;
+ goto done;
+ }
+
+ mdSession = fwToken->mdToken->OpenSession(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance,
+ /*XXX fgmr! */(NSSCKFWSession *)NULL,
+ rw, pError);
+ if( (NSSCKMDSession *)NULL == mdSession ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ goto done;
+ }
+
+ fwSession = nssCKFWSession_Create(fwToken, mdSession, rw,
+ pApplication, Notify, pError);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ if( CKR_OK == *pError ) {
+ *pError = CKR_GENERAL_ERROR;
+ }
+ if( (void *)NULL != (void *)mdSession->Close ) {
+ mdSession->Close(mdSession, fwSession, fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+ }
+ goto done;
+ }
+
+ *pError = nssCKFWHash_Add(fwToken->sessions, fwSession, fwSession);
+ if( CKR_OK != *pError ) {
+ (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
+ fwSession = (NSSCKFWSession *)NULL;
+ goto done;
+ }
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return fwSession;
+}
+
+/*
+ * nssCKFWToken_GetMechanismCount
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWToken_GetMechanismCount
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return 0;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == fwToken->mdToken->GetMechanismCount ) {
+ return 0;
+ }
+
+ return fwToken->mdToken->GetMechanismCount(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance);
+}
+
+/*
+ * nssCKFWToken_GetMechanismTypes
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWToken_GetMechanismTypes
+(
+ NSSCKFWToken *fwToken,
+ CK_MECHANISM_TYPE types[]
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ if( (CK_MECHANISM_TYPE *)NULL == types ) {
+ return CKR_ARGUMENTS_BAD;
+ }
+#endif /* NSSDEBUG */
+
+ if( (void *)NULL == fwToken->mdToken->GetMechanismTypes ) {
+ /*
+ * This should only be called with a sufficiently-large
+ * "types" array, which can only be done if GetMechanismCount
+ * is implemented. If that's implemented (and returns nonzero),
+ * then this should be too. So return an error.
+ */
+ return CKR_GENERAL_ERROR;
+ }
+
+ return fwToken->mdToken->GetMechanismTypes(fwToken->mdToken, fwToken,
+ fwToken->mdInstance, fwToken->fwInstance, types);
+}
+
+
+/*
+ * nssCKFWToken_GetMechanism
+ *
+ */
+NSS_IMPLEMENT NSSCKFWMechanism *
+nssCKFWToken_GetMechanism
+(
+ NSSCKFWToken *fwToken,
+ CK_MECHANISM_TYPE which,
+ CK_RV *pError
+)
+{
+ /* XXX fgmr */
+ return (NSSCKFWMechanism *)NULL;
+}
+
+NSS_IMPLEMENT CK_RV
+nssCKFWToken_SetSessionState
+(
+ NSSCKFWToken *fwToken,
+ CK_STATE newState
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ switch( newState ) {
+ case CKS_RO_PUBLIC_SESSION:
+ case CKS_RO_USER_FUNCTIONS:
+ case CKS_RW_PUBLIC_SESSION:
+ case CKS_RW_USER_FUNCTIONS:
+ case CKS_RW_SO_FUNCTIONS:
+ break;
+ default:
+ return CKR_ARGUMENTS_BAD;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwToken->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ fwToken->state = newState;
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return CKR_OK;
+}
+
+/*
+ * nssCKFWToken_RemoveSession
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWToken_RemoveSession
+(
+ NSSCKFWToken *fwToken,
+ NSSCKFWSession *fwSession
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ error = nssCKFWSession_verifyPointer(fwSession);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwToken->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ if( CKR_OK != nssCKFWHash_Exists(fwToken->sessions, fwSession) ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto done;
+ }
+
+ nssCKFWHash_Remove(fwToken->sessions, fwSession);
+ fwToken->sessionCount--;
+
+ if( nssCKFWSession_IsRWSession(fwSession) ) {
+ fwToken->rwSessionCount--;
+ }
+
+ if( 0 == fwToken->sessionCount ) {
+ fwToken->rwSessionCount = 0; /* sanity */
+ fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
+ }
+
+ error = CKR_OK;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
+}
+
+static void
+nss_ckfwtoken_session_iterator
+(
+ const void *key,
+ void *value,
+ void *closure
+)
+{
+ /*
+ * Remember that the fwToken->mutex is locked
+ */
+ NSSCKFWSession *fwSession = (NSSCKFWSession *)value;
+ (void)nssCKFWSession_Destroy(fwSession, CK_FALSE);
+ return;
+}
+
+/*
+ * nssCKFWToken_CloseAllSessions
+ *
+ */
+NSS_IMPLEMENT CK_RV
+nssCKFWToken_CloseAllSessions
+(
+ NSSCKFWToken *fwToken
+)
+{
+ CK_RV error = CKR_OK;
+
+#ifdef NSSDEBUG
+ error = nssCKFWToken_verifyPointer(fwToken);
+ if( CKR_OK != error ) {
+ return error;
+ }
+#endif /* NSSDEBUG */
+
+ error = nssCKFWMutex_Lock(fwToken->mutex);
+ if( CKR_OK != error ) {
+ return error;
+ }
+
+ nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, (void *)NULL);
+
+ nssCKFWHash_Destroy(fwToken->sessions);
+
+ fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, fwToken->arena, &error);
+ if( (nssCKFWHash *)NULL == fwToken->sessions ) {
+ if( CKR_OK == error ) {
+ error = CKR_GENERAL_ERROR;
+ }
+ goto done;
+ }
+
+ fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */
+ fwToken->sessionCount = 0;
+ fwToken->rwSessionCount = 0;
+
+ error = CKR_OK;
+
+ done:
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return error;
+}
+
+/*
+ * nssCKFWToken_GetSessionCount
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWToken_GetSessionCount
+(
+ NSSCKFWToken *fwToken
+)
+{
+ CK_ULONG rv;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return (CK_ULONG)0;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
+ return (CK_ULONG)0;
+ }
+
+ rv = fwToken->sessionCount;
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWToken_GetRwSessionCount
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWToken_GetRwSessionCount
+(
+ NSSCKFWToken *fwToken
+)
+{
+ CK_ULONG rv;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return (CK_ULONG)0;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
+ return (CK_ULONG)0;
+ }
+
+ rv = fwToken->rwSessionCount;
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWToken_GetRoSessionCount
+ *
+ */
+NSS_IMPLEMENT CK_ULONG
+nssCKFWToken_GetRoSessionCount
+(
+ NSSCKFWToken *fwToken
+)
+{
+ CK_ULONG rv;
+
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return (CK_ULONG)0;
+ }
+#endif /* NSSDEBUG */
+
+ if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) {
+ return (CK_ULONG)0;
+ }
+
+ rv = fwToken->sessionCount - fwToken->rwSessionCount;
+ (void)nssCKFWMutex_Unlock(fwToken->mutex);
+ return rv;
+}
+
+/*
+ * nssCKFWToken_GetSessionObjectHash
+ *
+ */
+NSS_IMPLEMENT nssCKFWHash *
+nssCKFWToken_GetSessionObjectHash
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return (nssCKFWHash *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwToken->sessionObjectHash;
+}
+
+/*
+ * nssCKFWToken_GetMDObjectHash
+ *
+ */
+NSS_IMPLEMENT nssCKFWHash *
+nssCKFWToken_GetMDObjectHash
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return (nssCKFWHash *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwToken->mdObjectHash;
+}
+
+/*
+ * nssCKFWToken_GetObjectHandleHash
+ *
+ */
+NSS_IMPLEMENT nssCKFWHash *
+nssCKFWToken_GetObjectHandleHash
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef NSSDEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return (nssCKFWHash *)NULL;
+ }
+#endif /* NSSDEBUG */
+
+ return fwToken->mdObjectHash;
+}
+
+/*
+ * NSSCKFWToken_GetMDToken
+ *
+ */
+
+NSS_IMPLEMENT NSSCKMDToken *
+NSSCKFWToken_GetMDToken
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return (NSSCKMDToken *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWToken_GetMDToken(fwToken);
+}
+
+/*
+ * NSSCKFWToken_GetArena
+ *
+ */
+
+NSS_IMPLEMENT NSSArena *
+NSSCKFWToken_GetArena
+(
+ NSSCKFWToken *fwToken,
+ CK_RV *pError
+)
+{
+#ifdef DEBUG
+ if( (CK_RV *)NULL == pError ) {
+ return (NSSArena *)NULL;
+ }
+
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ *pError = CKR_ARGUMENTS_BAD;
+ return (NSSArena *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWToken_GetArena(fwToken, pError);
+}
+
+/*
+ * NSSCKFWToken_GetFWSlot
+ *
+ */
+
+NSS_IMPLEMENT NSSCKFWSlot *
+NSSCKFWToken_GetFWSlot
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return (NSSCKFWSlot *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWToken_GetFWSlot(fwToken);
+}
+
+/*
+ * NSSCKFWToken_GetMDSlot
+ *
+ */
+
+NSS_IMPLEMENT NSSCKMDSlot *
+NSSCKFWToken_GetMDSlot
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return (NSSCKMDSlot *)NULL;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWToken_GetMDSlot(fwToken);
+}
+
+/*
+ * NSSCKFWToken_GetSessionState
+ *
+ */
+
+NSS_IMPLEMENT CK_STATE
+NSSCKFWSession_GetSessionState
+(
+ NSSCKFWToken *fwToken
+)
+{
+#ifdef DEBUG
+ if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) {
+ return CKS_RO_PUBLIC_SESSION;
+ }
+#endif /* DEBUG */
+
+ return nssCKFWToken_GetSessionState(fwToken);
+}
diff --git a/security/nss/lib/ckfw/wrap.c b/security/nss/lib/ckfw/wrap.c
new file mode 100644
index 000000000..4a138807f
--- /dev/null
+++ b/security/nss/lib/ckfw/wrap.c
@@ -0,0 +1,3413 @@
+/*
+ * The contents of this file are subject to the Mozilla Public
+ * License Version 1.1 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * rights and limitations under the License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is Netscape
+ * Communications Corporation. Portions created by Netscape are
+ * Copyright (C) 1994-2000 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License Version 2 or later (the
+ * "GPL"), in which case the provisions of the GPL are applicable
+ * instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of the GPL and not to
+ * allow others to use your version of this file under the MPL,
+ * indicate your decision by deleting the provisions above and
+ * replace them with the notice and other provisions required by
+ * the GPL. If you do not delete the provisions above, a recipient
+ * may use your version of this file under either the MPL or the
+ * GPL.
+ */
+
+#ifdef DEBUG
+static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
+#endif /* DEBUG */
+
+/*
+ * wrap.c
+ *
+ * This file contains the routines that actually implement the cryptoki
+ * API, using the internal APIs of the NSS Cryptoki Framework. There is
+ * one routine here for every cryptoki routine. For linking reasons
+ * the actual entry points passed back with C_GetFunctionList have to
+ * exist in one of the Module's source files; however, those are merely
+ * simple wrappers that call these routines. The intelligence of the
+ * implementations is here.
+ */
+
+#ifndef CK_T
+#include "ck.h"
+#endif /* CK_T */
+
+/*
+ * NSSCKFWC_Initialize
+ * NSSCKFWC_Finalize
+ * NSSCKFWC_GetInfo
+ * -- NSSCKFWC_GetFunctionList -- see the API insert file
+ * NSSCKFWC_GetSlotList
+ * NSSCKFWC_GetSlotInfo
+ * NSSCKFWC_GetTokenInfo
+ * NSSCKFWC_WaitForSlotEvent
+ * NSSCKFWC_GetMechanismList
+ * NSSCKFWC_GetMechanismInfo
+ * NSSCKFWC_InitToken
+ * NSSCKFWC_InitPIN
+ * NSSCKFWC_SetPIN
+ * NSSCKFWC_OpenSession
+ * NSSCKFWC_CloseSession
+ * NSSCKFWC_CloseAllSessions
+ * NSSCKFWC_GetSessionInfo
+ * NSSCKFWC_GetOperationState
+ * NSSCKFWC_SetOperationState
+ * NSSCKFWC_Login
+ * NSSCKFWC_Logout
+ * NSSCKFWC_CreateObject
+ * NSSCKFWC_CopyObject
+ * NSSCKFWC_DestroyObject
+ * NSSCKFWC_GetObjectSize
+ * NSSCKFWC_GetAttributeValue
+ * NSSCKFWC_SetAttributeValue
+ * NSSCKFWC_FindObjectsInit
+ * NSSCKFWC_FindObjects
+ * NSSCKFWC_FindObjectsFinal
+ * NSSCKFWC_EncryptInit
+ * NSSCKFWC_Encrypt
+ * NSSCKFWC_EncryptUpdate
+ * NSSCKFWC_EncryptFinal
+ * NSSCKFWC_DecryptInit
+ * NSSCKFWC_Decrypt
+ * NSSCKFWC_DecryptUpdate
+ * NSSCKFWC_DecryptFinal
+ * NSSCKFWC_DigestInit
+ * NSSCKFWC_Digest
+ * NSSCKFWC_DigestUpdate
+ * NSSCKFWC_DigestKey
+ * NSSCKFWC_DigestFinal
+ * NSSCKFWC_SignInit
+ * NSSCKFWC_Sign
+ * NSSCKFWC_SignUpdate
+ * NSSCKFWC_SignFinal
+ * NSSCKFWC_SignRecoverInit
+ * NSSCKFWC_SignRecover
+ * NSSCKFWC_VerifyInit
+ * NSSCKFWC_Verify
+ * NSSCKFWC_VerifyUpdate
+ * NSSCKFWC_VerifyFinal
+ * NSSCKFWC_VerifyRecoverInit
+ * NSSCKFWC_VerifyRecover
+ * NSSCKFWC_DigestEncryptUpdate
+ * NSSCKFWC_DecryptDigestUpdate
+ * NSSCKFWC_SignEncryptUpdate
+ * NSSCKFWC_DecryptVerifyUpdate
+ * NSSCKFWC_GenerateKey
+ * NSSCKFWC_GenerateKeyPair
+ * NSSCKFWC_WrapKey
+ * NSSCKFWC_UnwrapKey
+ * NSSCKFWC_DeriveKey
+ * NSSCKFWC_SeedRandom
+ * NSSCKFWC_GenerateRandom
+ * NSSCKFWC_GetFunctionStatus
+ * NSSCKFWC_CancelFunction
+ */
+
+/*
+ * NSSCKFWC_Initialize
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_Initialize
+(
+ NSSCKFWInstance **pFwInstance,
+ NSSCKMDInstance *mdInstance,
+ CK_VOID_PTR pInitArgs
+)
+{
+ CK_RV error = CKR_OK;
+
+ if( (NSSCKFWInstance **)NULL == pFwInstance ) {
+ error = CKR_GENERAL_ERROR;
+ goto loser;
+ }
+
+ if( (NSSCKFWInstance *)NULL != *pFwInstance ) {
+ error = CKR_CRYPTOKI_ALREADY_INITIALIZED;
+ goto loser;
+ }
+
+ if( (NSSCKMDInstance *)NULL == mdInstance ) {
+ error = CKR_GENERAL_ERROR;
+ goto loser;
+ }
+
+ *pFwInstance = nssCKFWInstance_Create(pInitArgs, mdInstance, &error);
+ if( (NSSCKFWInstance *)NULL == *pFwInstance ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_ARGUMENTS_BAD:
+ case CKR_CANT_LOCK:
+ case CKR_CRYPTOKI_ALREADY_INITIALIZED:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_NEED_TO_CREATE_THREADS:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_Finalize
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_Finalize
+(
+ NSSCKFWInstance **pFwInstance
+)
+{
+ CK_RV error = CKR_OK;
+
+ if( (NSSCKFWInstance **)NULL == pFwInstance ) {
+ error = CKR_GENERAL_ERROR;
+ goto loser;
+ }
+
+ if( (NSSCKFWInstance *)NULL == *pFwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ error = nssCKFWInstance_Destroy(*pFwInstance);
+
+ /* In any case */
+ *pFwInstance = (NSSCKFWInstance *)NULL;
+
+ loser:
+ switch( error ) {
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_OK:
+ break;
+ default:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_GetInfo
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GetInfo
+(
+ NSSCKFWInstance *fwInstance,
+ CK_INFO_PTR pInfo
+)
+{
+ CK_RV error = CKR_OK;
+
+ if( (CK_INFO_PTR)CK_NULL_PTR == pInfo ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /*
+ * A purify error here means a caller error
+ */
+ (void)nsslibc_memset(pInfo, 0, sizeof(CK_INFO));
+
+ pInfo->cryptokiVersion = nssCKFWInstance_GetCryptokiVersion(fwInstance);
+
+ error = nssCKFWInstance_GetManufacturerID(fwInstance, pInfo->manufacturerID);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ pInfo->flags = nssCKFWInstance_GetFlags(fwInstance);
+
+ error = nssCKFWInstance_GetLibraryDescription(fwInstance, pInfo->libraryDescription);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ pInfo->libraryVersion = nssCKFWInstance_GetLibraryVersion(fwInstance);
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ break;
+ default:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * C_GetFunctionList is implemented entirely in the Module's file which
+ * includes the Framework API insert file. It requires no "actual"
+ * NSSCKFW routine.
+ */
+
+/*
+ * NSSCKFWC_GetSlotList
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GetSlotList
+(
+ NSSCKFWInstance *fwInstance,
+ CK_BBOOL tokenPresent,
+ CK_SLOT_ID_PTR pSlotList,
+ CK_ULONG_PTR pulCount
+)
+{
+ CK_RV error = CKR_OK;
+ CK_ULONG nSlots;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ switch( tokenPresent ) {
+ case CK_TRUE:
+ case CK_FALSE:
+ break;
+ default:
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ if( (CK_ULONG_PTR)CK_NULL_PTR == pulCount ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
+ if( (CK_ULONG)0 == nSlots ) {
+ goto loser;
+ }
+
+ if( (CK_SLOT_ID_PTR)CK_NULL_PTR == pSlotList ) {
+ *pulCount = nSlots;
+ return CKR_OK;
+ }
+
+ /*
+ * A purify error here indicates caller error.
+ */
+ (void)nsslibc_memset(pSlotList, 0, *pulCount * sizeof(CK_SLOT_ID));
+
+ if( *pulCount < nSlots ) {
+ *pulCount = nSlots;
+ error = CKR_BUFFER_TOO_SMALL;
+ goto loser;
+ } else {
+ CK_ULONG i;
+ *pulCount = nSlots;
+
+ /*
+ * Our secret "mapping": CK_SLOT_IDs are integers [1,N], and we
+ * just index one when we need it.
+ */
+
+ for( i = 0; i < nSlots; i++ ) {
+ pSlotList[i] = i+1;
+ }
+
+ return CKR_OK;
+ }
+
+ loser:
+ switch( error ) {
+ case CKR_BUFFER_TOO_SMALL:
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_GetSlotInfo
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GetSlotInfo
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID,
+ CK_SLOT_INFO_PTR pInfo
+)
+{
+ CK_RV error = CKR_OK;
+ CK_ULONG nSlots;
+ NSSCKFWSlot **slots;
+ NSSCKFWSlot *fwSlot;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
+ if( (CK_ULONG)0 == nSlots ) {
+ goto loser;
+ }
+
+ if( (slotID < 1) || (slotID > nSlots) ) {
+ error = CKR_SLOT_ID_INVALID;
+ goto loser;
+ }
+
+ if( (CK_SLOT_INFO_PTR)CK_NULL_PTR == pInfo ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /*
+ * A purify error here indicates caller error.
+ */
+ (void)nsslibc_memset(pInfo, 0, sizeof(CK_SLOT_INFO));
+
+ slots = nssCKFWInstance_GetSlots(fwInstance, &error);
+ if( (NSSCKFWSlot **)NULL == slots ) {
+ goto loser;
+ }
+
+ fwSlot = slots[ slotID-1 ];
+
+ error = nssCKFWSlot_GetSlotDescription(fwSlot, pInfo->slotDescription);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ error = nssCKFWSlot_GetManufacturerID(fwSlot, pInfo->manufacturerID);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ if( nssCKFWSlot_GetTokenPresent(fwSlot) ) {
+ pInfo->flags |= CKF_TOKEN_PRESENT;
+ }
+
+ if( nssCKFWSlot_GetRemovableDevice(fwSlot) ) {
+ pInfo->flags |= CKF_REMOVABLE_DEVICE;
+ }
+
+ if( nssCKFWSlot_GetHardwareSlot(fwSlot) ) {
+ pInfo->flags |= CKF_HW_SLOT;
+ }
+
+ pInfo->hardwareVersion = nssCKFWSlot_GetHardwareVersion(fwSlot);
+ pInfo->firmwareVersion = nssCKFWSlot_GetFirmwareVersion(fwSlot);
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_SLOT_ID_INVALID:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_GetTokenInfo
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GetTokenInfo
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID,
+ CK_TOKEN_INFO_PTR pInfo
+)
+{
+ CK_RV error = CKR_OK;
+ CK_ULONG nSlots;
+ NSSCKFWSlot **slots;
+ NSSCKFWSlot *fwSlot;
+ NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
+ if( (CK_ULONG)0 == nSlots ) {
+ goto loser;
+ }
+
+ if( (slotID < 1) || (slotID > nSlots) ) {
+ error = CKR_SLOT_ID_INVALID;
+ goto loser;
+ }
+
+ if( (CK_TOKEN_INFO_PTR)CK_NULL_PTR == pInfo ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /*
+ * A purify error here indicates caller error.
+ */
+ (void)nsslibc_memset(pInfo, 0, sizeof(CK_TOKEN_INFO));
+
+ slots = nssCKFWInstance_GetSlots(fwInstance, &error);
+ if( (NSSCKFWSlot **)NULL == slots ) {
+ goto loser;
+ }
+
+ fwSlot = slots[ slotID-1 ];
+
+ if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
+ error = CKR_TOKEN_NOT_PRESENT;
+ goto loser;
+ }
+
+ fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
+ if( (NSSCKFWToken *)NULL == fwToken ) {
+ goto loser;
+ }
+
+ error = nssCKFWToken_GetLabel(fwToken, pInfo->label);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ error = nssCKFWToken_GetManufacturerID(fwToken, pInfo->manufacturerID);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ error = nssCKFWToken_GetModel(fwToken, pInfo->model);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ error = nssCKFWToken_GetSerialNumber(fwToken, pInfo->serialNumber);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ if( nssCKFWToken_GetHasRNG(fwToken) ) {
+ pInfo->flags |= CKF_RNG;
+ }
+
+ if( nssCKFWToken_GetIsWriteProtected(fwToken) ) {
+ pInfo->flags |= CKF_WRITE_PROTECTED;
+ }
+
+ if( nssCKFWToken_GetLoginRequired(fwToken) ) {
+ pInfo->flags |= CKF_LOGIN_REQUIRED;
+ }
+
+ if( nssCKFWToken_GetUserPinInitialized(fwToken) ) {
+ pInfo->flags |= CKF_USER_PIN_INITIALIZED;
+ }
+
+ if( nssCKFWToken_GetRestoreKeyNotNeeded(fwToken) ) {
+ pInfo->flags |= CKF_RESTORE_KEY_NOT_NEEDED;
+ }
+
+ if( nssCKFWToken_GetHasClockOnToken(fwToken) ) {
+ pInfo->flags |= CKF_CLOCK_ON_TOKEN;
+ }
+
+ if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) {
+ pInfo->flags |= CKF_PROTECTED_AUTHENTICATION_PATH;
+ }
+
+ if( nssCKFWToken_GetSupportsDualCryptoOperations(fwToken) ) {
+ pInfo->flags |= CKF_DUAL_CRYPTO_OPERATIONS;
+ }
+
+ pInfo->ulMaxSessionCount = nssCKFWToken_GetMaxSessionCount(fwToken);
+ pInfo->ulSessionCount = nssCKFWToken_GetSessionCount(fwToken);
+ pInfo->ulMaxRwSessionCount = nssCKFWToken_GetMaxRwSessionCount(fwToken);
+ pInfo->ulRwSessionCount= nssCKFWToken_GetRwSessionCount(fwToken);
+ pInfo->ulMaxPinLen = nssCKFWToken_GetMaxPinLen(fwToken);
+ pInfo->ulMinPinLen = nssCKFWToken_GetMinPinLen(fwToken);
+ pInfo->ulTotalPublicMemory = nssCKFWToken_GetTotalPublicMemory(fwToken);
+ pInfo->ulFreePublicMemory = nssCKFWToken_GetFreePublicMemory(fwToken);
+ pInfo->ulTotalPrivateMemory = nssCKFWToken_GetTotalPrivateMemory(fwToken);
+ pInfo->ulFreePrivateMemory = nssCKFWToken_GetFreePrivateMemory(fwToken);
+ pInfo->hardwareVersion = nssCKFWToken_GetHardwareVersion(fwToken);
+ pInfo->firmwareVersion = nssCKFWToken_GetFirmwareVersion(fwToken);
+
+ error = nssCKFWToken_GetUTCTime(fwToken, pInfo->utcTime);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_DEVICE_REMOVED:
+ case CKR_TOKEN_NOT_PRESENT:
+ (void)nssCKFWToken_Destroy(fwToken);
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_SLOT_ID_INVALID:
+ case CKR_TOKEN_NOT_RECOGNIZED:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_WaitForSlotEvent
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_WaitForSlotEvent
+(
+ NSSCKFWInstance *fwInstance,
+ CK_FLAGS flags,
+ CK_SLOT_ID_PTR pSlot,
+ CK_VOID_PTR pReserved
+)
+{
+ CK_RV error = CKR_OK;
+ CK_ULONG nSlots;
+ CK_BBOOL block;
+ NSSCKFWSlot **slots;
+ NSSCKFWSlot *fwSlot;
+ CK_ULONG i;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ if( flags & ~CKF_DONT_BLOCK ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ block = (flags & CKF_DONT_BLOCK) ? CK_TRUE : CK_FALSE;
+
+ nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
+ if( (CK_ULONG)0 == nSlots ) {
+ goto loser;
+ }
+
+ if( (CK_SLOT_ID_PTR)CK_NULL_PTR == pSlot ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ if( (CK_VOID_PTR)CK_NULL_PTR != pReserved ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ slots = nssCKFWInstance_GetSlots(fwInstance, &error);
+ if( (NSSCKFWSlot **)NULL == slots ) {
+ goto loser;
+ }
+
+ fwSlot = nssCKFWInstance_WaitForSlotEvent(fwInstance, block, &error);
+ if( (NSSCKFWSlot *)NULL == fwSlot ) {
+ goto loser;
+ }
+
+ for( i = 0; i < nSlots; i++ ) {
+ if( fwSlot == slots[i] ) {
+ *pSlot = (CK_SLOT_ID)(CK_ULONG)(i+1);
+ }
+
+ return CKR_OK;
+ }
+
+ error = CKR_GENERAL_ERROR; /* returned something not in the slot list */
+
+ loser:
+ switch( error ) {
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_NO_EVENT:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_GetMechanismList
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GetMechanismList
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID,
+ CK_MECHANISM_TYPE_PTR pMechanismList,
+ CK_ULONG_PTR pulCount
+)
+{
+ CK_RV error = CKR_OK;
+ CK_ULONG nSlots;
+ NSSCKFWSlot **slots;
+ NSSCKFWSlot *fwSlot;
+ NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
+ CK_ULONG count;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
+ if( (CK_ULONG)0 == nSlots ) {
+ goto loser;
+ }
+
+ if( (slotID < 1) || (slotID > nSlots) ) {
+ error = CKR_SLOT_ID_INVALID;
+ goto loser;
+ }
+
+ if( (CK_ULONG_PTR)CK_NULL_PTR == pulCount ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ slots = nssCKFWInstance_GetSlots(fwInstance, &error);
+ if( (NSSCKFWSlot **)NULL == slots ) {
+ goto loser;
+ }
+
+ fwSlot = slots[ slotID-1 ];
+
+ if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
+ error = CKR_TOKEN_NOT_PRESENT;
+ goto loser;
+ }
+
+ fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
+ if( (NSSCKFWToken *)NULL == fwToken ) {
+ goto loser;
+ }
+
+ count = nssCKFWToken_GetMechanismCount(fwToken);
+
+ if( (CK_MECHANISM_TYPE_PTR)CK_NULL_PTR == pMechanismList ) {
+ *pulCount = count;
+ return CKR_OK;
+ }
+
+ if( *pulCount < count ) {
+ *pulCount = count;
+ error = CKR_BUFFER_TOO_SMALL;
+ goto loser;
+ }
+
+ /*
+ * A purify error here indicates caller error.
+ */
+ (void)nsslibc_memset(pMechanismList, 0, *pulCount * sizeof(CK_MECHANISM_TYPE));
+
+ *pulCount = count;
+ error = nssCKFWToken_GetMechanismTypes(fwToken, pMechanismList);
+
+ if( CKR_OK == error ) {
+ return CKR_OK;
+ }
+
+ loser:
+ switch( error ) {
+ case CKR_DEVICE_REMOVED:
+ case CKR_TOKEN_NOT_PRESENT:
+ (void)nssCKFWToken_Destroy(fwToken);
+ break;
+ case CKR_BUFFER_TOO_SMALL:
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_SLOT_ID_INVALID:
+ case CKR_TOKEN_NOT_RECOGNIZED:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_GetMechanismInfo
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GetMechanismInfo
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID,
+ CK_MECHANISM_TYPE type,
+ CK_MECHANISM_INFO_PTR pInfo
+)
+{
+ CK_RV error = CKR_OK;
+ CK_ULONG nSlots;
+ NSSCKFWSlot **slots;
+ NSSCKFWSlot *fwSlot;
+ NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
+ NSSCKFWMechanism *fwMechanism;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
+ if( (CK_ULONG)0 == nSlots ) {
+ goto loser;
+ }
+
+ if( (slotID < 1) || (slotID > nSlots) ) {
+ error = CKR_SLOT_ID_INVALID;
+ goto loser;
+ }
+
+ slots = nssCKFWInstance_GetSlots(fwInstance, &error);
+ if( (NSSCKFWSlot **)NULL == slots ) {
+ goto loser;
+ }
+
+ fwSlot = slots[ slotID-1 ];
+
+ if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
+ error = CKR_TOKEN_NOT_PRESENT;
+ goto loser;
+ }
+
+ if( (CK_MECHANISM_INFO_PTR)CK_NULL_PTR == pInfo ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /*
+ * A purify error here indicates caller error.
+ */
+ (void)nsslibc_memset(pInfo, 0, sizeof(CK_MECHANISM_INFO));
+
+ fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
+ if( (NSSCKFWToken *)NULL == fwToken ) {
+ goto loser;
+ }
+
+ fwMechanism = nssCKFWToken_GetMechanism(fwToken, type, &error);
+ if( (NSSCKFWMechanism *)NULL == fwMechanism ) {
+ goto loser;
+ }
+
+ pInfo->ulMinKeySize = nssCKFWMechanism_GetMinKeySize(fwMechanism);
+ pInfo->ulMaxKeySize = nssCKFWMechanism_GetMaxKeySize(fwMechanism);
+
+ if( nssCKFWMechanism_GetInHardware(fwMechanism) ) {
+ pInfo->flags |= CKF_HW;
+ }
+
+ /* More here... */
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_DEVICE_REMOVED:
+ case CKR_TOKEN_NOT_PRESENT:
+ (void)nssCKFWToken_Destroy(fwToken);
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_MECHANISM_INVALID:
+ case CKR_SLOT_ID_INVALID:
+ case CKR_TOKEN_NOT_RECOGNIZED:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_InitToken
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_InitToken
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID,
+ CK_CHAR_PTR pPin,
+ CK_ULONG ulPinLen,
+ CK_CHAR_PTR pLabel
+)
+{
+ CK_RV error = CKR_OK;
+ CK_ULONG nSlots;
+ NSSCKFWSlot **slots;
+ NSSCKFWSlot *fwSlot;
+ NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
+ NSSItem pin;
+ NSSUTF8 *label;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
+ if( (CK_ULONG)0 == nSlots ) {
+ goto loser;
+ }
+
+ if( (slotID < 1) || (slotID > nSlots) ) {
+ error = CKR_SLOT_ID_INVALID;
+ goto loser;
+ }
+
+ slots = nssCKFWInstance_GetSlots(fwInstance, &error);
+ if( (NSSCKFWSlot **)NULL == slots ) {
+ goto loser;
+ }
+
+ fwSlot = slots[ slotID-1 ];
+
+ if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
+ error = CKR_TOKEN_NOT_PRESENT;
+ goto loser;
+ }
+
+ fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
+ if( (NSSCKFWToken *)NULL == fwToken ) {
+ goto loser;
+ }
+
+ pin.size = (PRUint32)ulPinLen;
+ pin.data = (void *)pPin;
+ label = (NSSUTF8 *)pLabel; /* identity conversion */
+
+ error = nssCKFWToken_InitToken(fwToken, &pin, label);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_DEVICE_REMOVED:
+ case CKR_TOKEN_NOT_PRESENT:
+ (void)nssCKFWToken_Destroy(fwToken);
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_PIN_INCORRECT:
+ case CKR_PIN_LOCKED:
+ case CKR_SESSION_EXISTS:
+ case CKR_SLOT_ID_INVALID:
+ case CKR_TOKEN_NOT_RECOGNIZED:
+ case CKR_TOKEN_WRITE_PROTECTED:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_InitPIN
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_InitPIN
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_CHAR_PTR pPin,
+ CK_ULONG ulPinLen
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSItem pin, *arg;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_CHAR_PTR)CK_NULL_PTR == pPin ) {
+ arg = (NSSItem *)NULL;
+ } else {
+ arg = &pin;
+ pin.size = (PRUint32)ulPinLen;
+ pin.data = (void *)pPin;
+ }
+
+ error = nssCKFWSession_InitPIN(fwSession, arg);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_PIN_INVALID:
+ case CKR_PIN_LEN_RANGE:
+ case CKR_SESSION_READ_ONLY:
+ case CKR_SESSION_HANDLE_INVALID:
+ case CKR_TOKEN_WRITE_PROTECTED:
+ case CKR_USER_NOT_LOGGED_IN:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_SetPIN
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_SetPIN
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_CHAR_PTR pOldPin,
+ CK_ULONG ulOldLen,
+ CK_CHAR_PTR pNewPin,
+ CK_ULONG ulNewLen
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSItem oldPin, newPin, *oldArg, *newArg;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_CHAR_PTR)CK_NULL_PTR == pOldPin ) {
+ oldArg = (NSSItem *)NULL;
+ } else {
+ oldArg = &oldPin;
+ oldPin.size = (PRUint32)ulOldLen;
+ oldPin.data = (void *)pOldPin;
+ }
+
+ if( (CK_CHAR_PTR)CK_NULL_PTR == pNewPin ) {
+ newArg = (NSSItem *)NULL;
+ } else {
+ newArg = &newPin;
+ newPin.size = (PRUint32)ulNewLen;
+ newPin.data = (void *)pNewPin;
+ }
+
+ error = nssCKFWSession_SetPIN(fwSession, oldArg, newArg);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_PIN_INCORRECT:
+ case CKR_PIN_INVALID:
+ case CKR_PIN_LEN_RANGE:
+ case CKR_PIN_LOCKED:
+ case CKR_SESSION_HANDLE_INVALID:
+ case CKR_SESSION_READ_ONLY:
+ case CKR_TOKEN_WRITE_PROTECTED:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_OpenSession
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_OpenSession
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID,
+ CK_FLAGS flags,
+ CK_VOID_PTR pApplication,
+ CK_NOTIFY Notify,
+ CK_SESSION_HANDLE_PTR phSession
+)
+{
+ CK_RV error = CKR_OK;
+ CK_ULONG nSlots;
+ NSSCKFWSlot **slots;
+ NSSCKFWSlot *fwSlot;
+ NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
+ NSSCKFWSession *fwSession;
+ CK_BBOOL rw;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
+ if( (CK_ULONG)0 == nSlots ) {
+ goto loser;
+ }
+
+ if( (slotID < 1) || (slotID > nSlots) ) {
+ error = CKR_SLOT_ID_INVALID;
+ goto loser;
+ }
+
+ if( flags & CKF_RW_SESSION ) {
+ rw = CK_TRUE;
+ } else {
+ rw = CK_FALSE;
+ }
+
+ if( flags & CKF_SERIAL_SESSION ) {
+ ;
+ } else {
+ error = CKR_SESSION_PARALLEL_NOT_SUPPORTED;
+ goto loser;
+ }
+
+ if( flags & ~(CKF_RW_SESSION|CKF_SERIAL_SESSION) ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ if( (CK_SESSION_HANDLE_PTR)CK_NULL_PTR == phSession ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /*
+ * A purify error here indicates caller error.
+ */
+ *phSession = (CK_SESSION_HANDLE)0;
+
+ slots = nssCKFWInstance_GetSlots(fwInstance, &error);
+ if( (NSSCKFWSlot **)NULL == slots ) {
+ goto loser;
+ }
+
+ fwSlot = slots[ slotID-1 ];
+
+ if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
+ error = CKR_TOKEN_NOT_PRESENT;
+ goto loser;
+ }
+
+ fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
+ if( (NSSCKFWToken *)NULL == fwToken ) {
+ goto loser;
+ }
+
+ fwSession = nssCKFWToken_OpenSession(fwToken, rw, pApplication,
+ Notify, &error);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ goto loser;
+ }
+
+ *phSession = nssCKFWInstance_CreateSessionHandle(fwInstance,
+ fwSession, &error);
+ if( (CK_SESSION_HANDLE)0 == *phSession ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_SESSION_COUNT:
+ case CKR_SESSION_EXISTS:
+ case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
+ case CKR_SESSION_READ_WRITE_SO_EXISTS:
+ case CKR_SLOT_ID_INVALID:
+ case CKR_TOKEN_NOT_PRESENT:
+ case CKR_TOKEN_NOT_RECOGNIZED:
+ case CKR_TOKEN_WRITE_PROTECTED:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_CloseSession
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_CloseSession
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ error = nssCKFWSession_Destroy(fwSession, CK_TRUE);
+
+ /* In any case: */
+ nssCKFWInstance_DestroySessionHandle(fwInstance, hSession);
+
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_SESSION_HANDLE_INVALID:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_CloseAllSessions
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_CloseAllSessions
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SLOT_ID slotID
+)
+{
+ CK_RV error = CKR_OK;
+ CK_ULONG nSlots;
+ NSSCKFWSlot **slots;
+ NSSCKFWSlot *fwSlot;
+ NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ nSlots = nssCKFWInstance_GetNSlots(fwInstance, &error);
+ if( (CK_ULONG)0 == nSlots ) {
+ goto loser;
+ }
+
+ if( (slotID < 1) || (slotID > nSlots) ) {
+ error = CKR_SLOT_ID_INVALID;
+ goto loser;
+ }
+
+ slots = nssCKFWInstance_GetSlots(fwInstance, &error);
+ if( (NSSCKFWSlot **)NULL == slots ) {
+ goto loser;
+ }
+
+ fwSlot = slots[ slotID-1 ];
+
+ if( CK_TRUE != nssCKFWSlot_GetTokenPresent(fwSlot) ) {
+ error = CKR_TOKEN_NOT_PRESENT;
+ goto loser;
+ }
+
+ fwToken = nssCKFWSlot_GetToken(fwSlot, &error);
+ if( (NSSCKFWToken *)NULL == fwToken ) {
+ goto loser;
+ }
+
+ error = nssCKFWToken_CloseAllSessions(fwToken);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_SLOT_ID_INVALID:
+ case CKR_TOKEN_NOT_PRESENT:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_GetSessionInfo
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GetSessionInfo
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_SESSION_INFO_PTR pInfo
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWSlot *fwSlot;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_SESSION_INFO_PTR)CK_NULL_PTR == pInfo ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /*
+ * A purify error here indicates caller error.
+ */
+ (void)nsslibc_memset(pInfo, 0, sizeof(CK_SESSION_INFO));
+
+ fwSlot = nssCKFWSession_GetFWSlot(fwSession);
+ if( (NSSCKFWSlot *)NULL == fwSlot ) {
+ error = CKR_GENERAL_ERROR;
+ goto loser;
+ }
+
+ pInfo->slotID = nssCKFWSlot_GetSlotID(fwSlot);
+ pInfo->state = nssCKFWSession_GetSessionState(fwSession);
+
+ if( CK_TRUE == nssCKFWSession_IsRWSession(fwSession) ) {
+ pInfo->flags |= CKF_RW_SESSION;
+ }
+
+ pInfo->flags |= CKF_SERIAL_SESSION; /* Always true */
+
+ pInfo->ulDeviceError = nssCKFWSession_GetDeviceError(fwSession);
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_SESSION_HANDLE_INVALID:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_GetOperationState
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GetOperationState
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pOperationState,
+ CK_ULONG_PTR pulOperationStateLen
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ CK_ULONG len;
+ NSSItem buf;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_ULONG_PTR)CK_NULL_PTR == pulOperationStateLen ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ len = nssCKFWSession_GetOperationStateLen(fwSession, &error);
+ if( ((CK_ULONG)0 == len) && (CKR_OK != error) ) {
+ goto loser;
+ }
+
+ if( (CK_BYTE_PTR)CK_NULL_PTR == pOperationState ) {
+ *pulOperationStateLen = len;
+ return CKR_OK;
+ }
+
+ if( *pulOperationStateLen < len ) {
+ *pulOperationStateLen = len;
+ error = CKR_BUFFER_TOO_SMALL;
+ goto loser;
+ }
+
+ buf.size = (PRUint32)*pulOperationStateLen;
+ buf.data = (void *)pOperationState;
+ *pulOperationStateLen = len;
+ error = nssCKFWSession_GetOperationState(fwSession, &buf);
+
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_BUFFER_TOO_SMALL:
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_OPERATION_NOT_INITIALIZED:
+ case CKR_SESSION_HANDLE_INVALID:
+ case CKR_STATE_UNSAVEABLE:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_SetOperationState
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_SetOperationState
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pOperationState,
+ CK_ULONG ulOperationStateLen,
+ CK_OBJECT_HANDLE hEncryptionKey,
+ CK_OBJECT_HANDLE hAuthenticationKey
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWObject *eKey;
+ NSSCKFWObject *aKey;
+ NSSItem state;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ if( (CK_BYTE_PTR)CK_NULL_PTR == pOperationState ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /*
+ * We could loop through the buffer, to catch any purify errors
+ * in a place with a "user error" note.
+ */
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_OBJECT_HANDLE)0 == hEncryptionKey ) {
+ eKey = (NSSCKFWObject *)NULL;
+ } else {
+ eKey = nssCKFWInstance_ResolveObjectHandle(fwInstance, hEncryptionKey);
+ if( (NSSCKFWObject *)NULL == eKey ) {
+ error = CKR_KEY_HANDLE_INVALID;
+ goto loser;
+ }
+ }
+
+ if( (CK_OBJECT_HANDLE)0 == hAuthenticationKey ) {
+ aKey = (NSSCKFWObject *)NULL;
+ } else {
+ aKey = nssCKFWInstance_ResolveObjectHandle(fwInstance, hAuthenticationKey);
+ if( (NSSCKFWObject *)NULL == aKey ) {
+ error = CKR_KEY_HANDLE_INVALID;
+ goto loser;
+ }
+ }
+
+ error = nssCKFWSession_SetOperationState(fwSession, &state, eKey, aKey);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_KEY_CHANGED:
+ case CKR_KEY_NEEDED:
+ case CKR_KEY_NOT_NEEDED:
+ case CKR_SAVED_STATE_INVALID:
+ case CKR_SESSION_HANDLE_INVALID:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_Login
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_Login
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_USER_TYPE userType,
+ CK_CHAR_PTR pPin,
+ CK_ULONG ulPinLen
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSItem pin, *arg;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_CHAR_PTR)CK_NULL_PTR == pPin ) {
+ arg = (NSSItem *)NULL;
+ } else {
+ arg = &pin;
+ pin.size = (PRUint32)ulPinLen;
+ pin.data = (void *)pPin;
+ }
+
+ error = nssCKFWSession_Login(fwSession, userType, arg);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_PIN_EXPIRED:
+ case CKR_PIN_INCORRECT:
+ case CKR_PIN_LOCKED:
+ case CKR_SESSION_HANDLE_INVALID:
+ case CKR_SESSION_READ_ONLY_EXISTS:
+ case CKR_USER_ALREADY_LOGGED_IN:
+ case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
+ case CKR_USER_PIN_NOT_INITIALIZED:
+ case CKR_USER_TOO_MANY_TYPES:
+ case CKR_USER_TYPE_INVALID:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_Logout
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_Logout
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ error = nssCKFWSession_Logout(fwSession);
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_SESSION_HANDLE_INVALID:
+ case CKR_USER_NOT_LOGGED_IN:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_CreateObject
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_CreateObject
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phObject
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWObject *fwObject;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phObject ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /*
+ * A purify error here indicates caller error.
+ */
+ *phObject = (CK_OBJECT_HANDLE)0;
+
+ fwObject = nssCKFWSession_CreateObject(fwSession, pTemplate,
+ ulCount, &error);
+ if( (NSSCKFWObject *)NULL == fwObject ) {
+ goto loser;
+ }
+
+ *phObject = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
+ if( (CK_OBJECT_HANDLE)0 == *phObject ) {
+ nssCKFWObject_Destroy(fwObject);
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_ATTRIBUTE_READ_ONLY:
+ case CKR_ATTRIBUTE_TYPE_INVALID:
+ case CKR_ATTRIBUTE_VALUE_INVALID:
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_SESSION_HANDLE_INVALID:
+ case CKR_SESSION_READ_ONLY:
+ case CKR_TEMPLATE_INCOMPLETE:
+ case CKR_TEMPLATE_INCONSISTENT:
+ case CKR_TOKEN_WRITE_PROTECTED:
+ case CKR_USER_NOT_LOGGED_IN:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_CopyObject
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_CopyObject
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phNewObject
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWObject *fwObject;
+ NSSCKFWObject *fwNewObject;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phNewObject ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /*
+ * A purify error here indicates caller error.
+ */
+ *phNewObject = (CK_OBJECT_HANDLE)0;
+
+ fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
+ if( (NSSCKFWObject *)NULL == fwObject ) {
+ error = CKR_OBJECT_HANDLE_INVALID;
+ goto loser;
+ }
+
+ fwNewObject = nssCKFWSession_CopyObject(fwSession, fwObject,
+ pTemplate, ulCount, &error);
+ if( (NSSCKFWObject *)NULL == fwNewObject ) {
+ goto loser;
+ }
+
+ *phNewObject = nssCKFWInstance_CreateObjectHandle(fwInstance,
+ fwNewObject, &error);
+ if( (CK_OBJECT_HANDLE)0 == *phNewObject ) {
+ nssCKFWObject_Destroy(fwNewObject);
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_ATTRIBUTE_READ_ONLY:
+ case CKR_ATTRIBUTE_TYPE_INVALID:
+ case CKR_ATTRIBUTE_VALUE_INVALID:
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_OBJECT_HANDLE_INVALID:
+ case CKR_SESSION_HANDLE_INVALID:
+ case CKR_SESSION_READ_ONLY:
+ case CKR_TEMPLATE_INCONSISTENT:
+ case CKR_TOKEN_WRITE_PROTECTED:
+ case CKR_USER_NOT_LOGGED_IN:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_DestroyObject
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_DestroyObject
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWObject *fwObject;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
+ if( (NSSCKFWObject *)NULL == fwObject ) {
+ error = CKR_OBJECT_HANDLE_INVALID;
+ goto loser;
+ }
+
+ nssCKFWObject_Destroy(fwObject);
+ nssCKFWInstance_DestroyObjectHandle(fwInstance, hObject);
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_OBJECT_HANDLE_INVALID:
+ case CKR_SESSION_HANDLE_INVALID:
+ case CKR_SESSION_READ_ONLY:
+ case CKR_TOKEN_WRITE_PROTECTED:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_GetObjectSize
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GetObjectSize
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ULONG_PTR pulSize
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWObject *fwObject;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
+ if( (NSSCKFWObject *)NULL == fwObject ) {
+ error = CKR_OBJECT_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_ULONG_PTR)CK_NULL_PTR == pulSize ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /*
+ * A purify error here indicates caller error.
+ */
+ *pulSize = (CK_ULONG)0;
+
+ *pulSize = nssCKFWObject_GetObjectSize(fwObject, &error);
+ if( ((CK_ULONG)0 == *pulSize) && (CKR_OK != error) ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_INFORMATION_SENSITIVE:
+ case CKR_OBJECT_HANDLE_INVALID:
+ case CKR_SESSION_HANDLE_INVALID:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_GetAttributeValue
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GetAttributeValue
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWObject *fwObject;
+ CK_BBOOL sensitive = CK_FALSE;
+ CK_BBOOL invalid = CK_FALSE;
+ CK_BBOOL tooSmall = CK_FALSE;
+ CK_ULONG i;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
+ if( (NSSCKFWObject *)NULL == fwObject ) {
+ error = CKR_OBJECT_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ for( i = 0; i < ulCount; i++ ) {
+ CK_ULONG size = nssCKFWObject_GetAttributeSize(fwObject,
+ pTemplate[i].type, &error);
+ if( (CK_ULONG)0 == size ) {
+ switch( error ) {
+ case CKR_ATTRIBUTE_SENSITIVE:
+ case CKR_INFORMATION_SENSITIVE:
+ sensitive = CK_TRUE;
+ pTemplate[i].ulValueLen = (CK_ULONG)(-1);
+ continue;
+ case CKR_ATTRIBUTE_TYPE_INVALID:
+ invalid = CK_TRUE;
+ pTemplate[i].ulValueLen = (CK_ULONG)(-1);
+ continue;
+ case CKR_OK:
+ break;
+ default:
+ goto loser;
+ }
+ }
+
+ if( (CK_VOID_PTR)CK_NULL_PTR == pTemplate[i].pValue ) {
+ pTemplate[i].ulValueLen = size;
+ } else {
+ NSSItem it, *p;
+
+ if( pTemplate[i].ulValueLen < size ) {
+ tooSmall = CK_TRUE;
+ continue;
+ }
+
+ it.size = (PRUint32)pTemplate[i].ulValueLen;
+ it.data = (void *)pTemplate[i].pValue;
+ p = nssCKFWObject_GetAttribute(fwObject, pTemplate[i].type, &it,
+ (NSSArena *)NULL, &error);
+ if( (NSSItem *)NULL == p ) {
+ switch( error ) {
+ case CKR_ATTRIBUTE_SENSITIVE:
+ case CKR_INFORMATION_SENSITIVE:
+ sensitive = CK_TRUE;
+ pTemplate[i].ulValueLen = (CK_ULONG)(-1);
+ continue;
+ case CKR_ATTRIBUTE_TYPE_INVALID:
+ invalid = CK_TRUE;
+ pTemplate[i].ulValueLen = (CK_ULONG)(-1);
+ continue;
+ default:
+ goto loser;
+ }
+ }
+
+ pTemplate[i].ulValueLen = size;
+ }
+ }
+
+ if( sensitive ) {
+ error = CKR_ATTRIBUTE_SENSITIVE;
+ goto loser;
+ } else if( invalid ) {
+ error = CKR_ATTRIBUTE_TYPE_INVALID;
+ goto loser;
+ } else if( tooSmall ) {
+ error = CKR_BUFFER_TOO_SMALL;
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_ATTRIBUTE_SENSITIVE:
+ case CKR_ATTRIBUTE_TYPE_INVALID:
+ case CKR_BUFFER_TOO_SMALL:
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_OBJECT_HANDLE_INVALID:
+ case CKR_SESSION_HANDLE_INVALID:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_SetAttributeValue
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_SetAttributeValue
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hObject,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWObject *fwObject;
+ NSSCKFWObject *newFwObject;
+
+ CK_ULONG i;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ fwObject = nssCKFWInstance_ResolveObjectHandle(fwInstance, hObject);
+ if( (NSSCKFWObject *)NULL == fwObject ) {
+ error = CKR_OBJECT_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ newFwObject = nssCKFWSession_CopyObject(fwSession, fwObject, pTemplate,
+ ulCount, &error);
+ if( (NSSCKFWObject *)NULL == newFwObject ) {
+ goto loser;
+ }
+
+ error = nssCKFWInstance_ReassignObjectHandle(fwInstance, hObject, newFwObject);
+ nssCKFWObject_Destroy(fwObject);
+
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_ATTRIBUTE_READ_ONLY:
+ case CKR_ATTRIBUTE_TYPE_INVALID:
+ case CKR_ATTRIBUTE_VALUE_INVALID:
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_OBJECT_HANDLE_INVALID:
+ case CKR_SESSION_HANDLE_INVALID:
+ case CKR_SESSION_READ_ONLY:
+ case CKR_TEMPLATE_INCONSISTENT:
+ case CKR_TOKEN_WRITE_PROTECTED:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_FindObjectsInit
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_FindObjectsInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWFindObjects *fwFindObjects;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_ATTRIBUTE_PTR)CK_NULL_PTR == pTemplate ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
+ if( (NSSCKFWFindObjects *)NULL != fwFindObjects ) {
+ error = CKR_OPERATION_ACTIVE;
+ goto loser;
+ }
+
+ if( CKR_OPERATION_NOT_INITIALIZED != error ) {
+ goto loser;
+ }
+
+ fwFindObjects = nssCKFWSession_FindObjectsInit(fwSession,
+ pTemplate, ulCount, &error);
+ if( (NSSCKFWFindObjects *)NULL == fwFindObjects ) {
+ goto loser;
+ }
+
+ error = nssCKFWSession_SetFWFindObjects(fwSession, fwFindObjects);
+
+ if( CKR_OK != error ) {
+ nssCKFWFindObjects_Destroy(fwFindObjects);
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_ATTRIBUTE_TYPE_INVALID:
+ case CKR_ATTRIBUTE_VALUE_INVALID:
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_OPERATION_ACTIVE:
+ case CKR_SESSION_HANDLE_INVALID:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_FindObjects
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_FindObjects
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE_PTR phObject,
+ CK_ULONG ulMaxObjectCount,
+ CK_ULONG_PTR pulObjectCount
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWFindObjects *fwFindObjects;
+ CK_ULONG i;
+ NSSArena *arena;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ arena = nssCKFWSession_GetArena(fwSession, &error);
+ if( (NSSArena *)NULL == arena ) {
+ goto loser;
+ }
+
+ if( (CK_OBJECT_HANDLE_PTR)CK_NULL_PTR == phObject ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /*
+ * A purify error here indicates caller error.
+ */
+ (void)nsslibc_memset(phObject, 0, sizeof(CK_OBJECT_HANDLE) * ulMaxObjectCount);
+ *pulObjectCount = (CK_ULONG)0;
+
+ fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
+ if( (NSSCKFWFindObjects *)NULL == fwFindObjects ) {
+ goto loser;
+ }
+
+ for( i = 0; i < ulMaxObjectCount; i++ ) {
+ NSSCKFWObject *fwObject = nssCKFWFindObjects_Next(fwFindObjects,
+ arena, &error);
+ if( (NSSCKFWObject *)NULL == fwObject ) {
+ goto loser;
+ }
+
+ phObject[i] = nssCKFWInstance_FindObjectHandle(fwInstance, fwObject);
+ if( (CK_OBJECT_HANDLE)0 == phObject[i] ) {
+ phObject[i] = nssCKFWInstance_CreateObjectHandle(fwInstance, fwObject, &error);
+ }
+ if( (CK_OBJECT_HANDLE)0 == phObject[i] ) {
+ /* This isn't right either, is it? */
+ nssCKFWObject_Destroy(fwObject);
+ goto loser;
+ }
+ }
+
+ *pulObjectCount = i;
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_OPERATION_NOT_INITIALIZED:
+ case CKR_SESSION_HANDLE_INVALID:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_FindObjectsFinal
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_FindObjectsFinal
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSCKFWFindObjects *fwFindObjects;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ fwFindObjects = nssCKFWSession_GetFWFindObjects(fwSession, &error);
+ if( (NSSCKFWFindObjects *)NULL == fwFindObjects ) {
+ error = CKR_OPERATION_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ nssCKFWFindObjects_Destroy(fwFindObjects);
+ error = nssCKFWSession_SetFWFindObjects(fwSession, (NSSCKFWFindObjects *)NULL);
+
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_OPERATION_NOT_INITIALIZED:
+ case CKR_SESSION_HANDLE_INVALID:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_EncryptInit
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_EncryptInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_Encrypt
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_Encrypt
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pEncryptedData,
+ CK_ULONG_PTR pulEncryptedDataLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_EncryptUpdate
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_EncryptUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG_PTR pulEncryptedPartLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_EncryptFinal
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_EncryptFinal
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pLastEncryptedPart,
+ CK_ULONG_PTR pulLastEncryptedPartLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_DecryptInit
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_DecryptInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_Decrypt
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_Decrypt
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pEncryptedData,
+ CK_ULONG ulEncryptedDataLen,
+ CK_BYTE_PTR pData,
+ CK_ULONG_PTR pulDataLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_DecryptUpdate
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_DecryptUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG ulEncryptedPartLen,
+ CK_BYTE_PTR pPart,
+ CK_ULONG_PTR pulPartLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_DecryptFinal
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_DecryptFinal
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pLastPart,
+ CK_ULONG_PTR pulLastPartLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_DigestInit
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_DigestInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_Digest
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_Digest
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pDigest,
+ CK_ULONG_PTR pulDigestLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_DigestUpdate
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_DigestUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_DigestKey
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_DigestKey
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_OBJECT_HANDLE hKey
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_DigestFinal
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_DigestFinal
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pDigest,
+ CK_ULONG_PTR pulDigestLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_SignInit
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_SignInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_Sign
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_Sign
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_SignUpdate
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_SignUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_SignFinal
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_SignFinal
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_SignRecoverInit
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_SignRecoverInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_SignRecover
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_SignRecover
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG_PTR pulSignatureLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_VerifyInit
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_VerifyInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_Verify
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_Verify
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pData,
+ CK_ULONG ulDataLen,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_VerifyUpdate
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_VerifyUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_VerifyFinal
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_VerifyFinal
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_VerifyRecoverInit
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_VerifyRecoverInit
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hKey
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_VerifyRecover
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_VerifyRecover
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSignature,
+ CK_ULONG ulSignatureLen,
+ CK_BYTE_PTR pData,
+ CK_ULONG_PTR pulDataLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_DigestEncryptUpdate
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_DigestEncryptUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG_PTR pulEncryptedPartLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_DecryptDigestUpdate
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_DecryptDigestUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG ulEncryptedPartLen,
+ CK_BYTE_PTR pPart,
+ CK_ULONG_PTR pulPartLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_SignEncryptUpdate
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_SignEncryptUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pPart,
+ CK_ULONG ulPartLen,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG_PTR pulEncryptedPartLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_DecryptVerifyUpdate
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_DecryptVerifyUpdate
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pEncryptedPart,
+ CK_ULONG ulEncryptedPartLen,
+ CK_BYTE_PTR pPart,
+ CK_ULONG_PTR pulPartLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_GenerateKey
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GenerateKey
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulCount,
+ CK_OBJECT_HANDLE_PTR phKey
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_GenerateKeyPair
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GenerateKeyPair
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate,
+ CK_ULONG ulPublicKeyAttributeCount,
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
+ CK_ULONG ulPrivateKeyAttributeCount,
+ CK_OBJECT_HANDLE_PTR phPublicKey,
+ CK_OBJECT_HANDLE_PTR phPrivateKey
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_WrapKey
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_WrapKey
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hWrappingKey,
+ CK_OBJECT_HANDLE hKey,
+ CK_BYTE_PTR pWrappedKey,
+ CK_ULONG_PTR pulWrappedKeyLen
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_UnwrapKey
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_UnwrapKey
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hUnwrappingKey,
+ CK_BYTE_PTR pWrappedKey,
+ CK_ULONG ulWrappedKeyLen,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_DeriveKey
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_DeriveKey
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_MECHANISM_PTR pMechanism,
+ CK_OBJECT_HANDLE hBaseKey,
+ CK_ATTRIBUTE_PTR pTemplate,
+ CK_ULONG ulAttributeCount,
+ CK_OBJECT_HANDLE_PTR phKey
+)
+{
+ return CKR_FUNCTION_FAILED;
+}
+
+/*
+ * NSSCKFWC_SeedRandom
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_SeedRandom
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pSeed,
+ CK_ULONG ulSeedLen
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSItem seed;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_BYTE_PTR)CK_NULL_PTR == pSeed ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /* We could read through the buffer in a Purify trap */
+
+ seed.size = (PRUint32)ulSeedLen;
+ seed.data = (void *)pSeed;
+
+ error = nssCKFWSession_SeedRandom(fwSession, &seed);
+
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_CANCELED:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_OPERATION_ACTIVE:
+ case CKR_RANDOM_SEED_NOT_SUPPORTED:
+ case CKR_RANDOM_NO_RNG:
+ case CKR_SESSION_HANDLE_INVALID:
+ case CKR_USER_NOT_LOGGED_IN:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_GenerateRandom
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GenerateRandom
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession,
+ CK_BYTE_PTR pRandomData,
+ CK_ULONG ulRandomLen
+)
+{
+ CK_RV error = CKR_OK;
+ NSSCKFWSession *fwSession;
+ NSSItem buffer;
+
+ if( (NSSCKFWInstance *)NULL == fwInstance ) {
+ error = CKR_CRYPTOKI_NOT_INITIALIZED;
+ goto loser;
+ }
+
+ fwSession = nssCKFWInstance_ResolveSessionHandle(fwInstance, hSession);
+ if( (NSSCKFWSession *)NULL == fwSession ) {
+ error = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
+ }
+
+ if( (CK_BYTE_PTR)CK_NULL_PTR == pRandomData ) {
+ error = CKR_ARGUMENTS_BAD;
+ goto loser;
+ }
+
+ /*
+ * A purify error here indicates caller error.
+ */
+ (void)nsslibc_memset(pRandomData, 0, ulRandomLen);
+
+ buffer.size = (PRUint32)ulRandomLen;
+ buffer.data = (void *)pRandomData;
+
+ error = nssCKFWSession_GetRandom(fwSession, &buffer);
+
+ if( CKR_OK != error ) {
+ goto loser;
+ }
+
+ return CKR_OK;
+
+ loser:
+ switch( error ) {
+ case CKR_SESSION_CLOSED:
+ /* destroy session? */
+ break;
+ case CKR_DEVICE_REMOVED:
+ /* (void)nssCKFWToken_Destroy(fwToken); */
+ break;
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ case CKR_DEVICE_ERROR:
+ case CKR_DEVICE_MEMORY:
+ case CKR_FUNCTION_CANCELED:
+ case CKR_FUNCTION_FAILED:
+ case CKR_GENERAL_ERROR:
+ case CKR_HOST_MEMORY:
+ case CKR_OPERATION_ACTIVE:
+ case CKR_RANDOM_NO_RNG:
+ case CKR_SESSION_HANDLE_INVALID:
+ case CKR_USER_NOT_LOGGED_IN:
+ break;
+ default:
+ case CKR_OK:
+ error = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ return error;
+}
+
+/*
+ * NSSCKFWC_GetFunctionStatus
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_GetFunctionStatus
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+)
+{
+ return CKR_FUNCTION_NOT_PARALLEL;
+}
+
+/*
+ * NSSCKFWC_CancelFunction
+ *
+ */
+NSS_IMPLEMENT CK_RV
+NSSCKFWC_CancelFunction
+(
+ NSSCKFWInstance *fwInstance,
+ CK_SESSION_HANDLE hSession
+)
+{
+ return CKR_FUNCTION_NOT_PARALLEL;
+}