#!perl # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. $copyright = '/* THIS IS A GENERATED FILE */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ '; $count = -1; $i = 0; open(INPUT, "<$ARGV[0]") || die "Can't open $ARGV[0]: $!"; while(<INPUT>) { 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 } } } close INPUT; # 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 /* * 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 /* * 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 /* * 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 */ #include "nssckp.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 }; #include "nsscku.h" #endif /* NSSCKEPV_H */ EOD ; select API; print $copyright; print <<EOD /* * 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 #define __ADJOIN(x,y) ADJOIN(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; static 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 */ static 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 */ static 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 "static 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 static 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 static CK_RV CK_ENTRY __ADJOIN(MODULE_NAME,C_GetFunctionList) ( CK_FUNCTION_LIST_PTR_PTR ppFunctionList ) { *ppFunctionList = &FunctionList; return CKR_OK; } /* This one is always present */ CK_RV CK_ENTRY C_GetFunctionList ( CK_FUNCTION_LIST_PTR_PTR ppFunctionList ) { return __ADJOIN(MODULE_NAME,C_GetFunctionList)(ppFunctionList); } #undef __ADJOIN EOD ; select STDOUT; }